semapong.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "nspr.h"
  6. #include "plgetopt.h"
  7. #include <stdio.h>
  8. #ifdef DEBUG
  9. #define SEM_D "D"
  10. #else
  11. #define SEM_D
  12. #endif
  13. #ifdef IS_64
  14. #define SEM_64 "64"
  15. #else
  16. #define SEM_64
  17. #endif
  18. #define SHM_NAME "/tmp/counter" SEM_D SEM_64
  19. #define SEM_NAME1 "/tmp/foo.sem" SEM_D SEM_64
  20. #define SEM_NAME2 "/tmp/bar.sem" SEM_D SEM_64
  21. #define ITERATIONS 1000
  22. static PRBool debug_mode = PR_FALSE;
  23. static PRIntn iterations = ITERATIONS;
  24. static PRSem *sem1, *sem2;
  25. static void Help(void)
  26. {
  27. fprintf(stderr, "semapong test program usage:\n");
  28. fprintf(stderr, "\t-d debug mode (FALSE)\n");
  29. fprintf(stderr, "\t-c <count> loop count (%d)\n", ITERATIONS);
  30. fprintf(stderr, "\t-h this message\n");
  31. } /* Help */
  32. int main(int argc, char **argv)
  33. {
  34. PRIntn i;
  35. PRSharedMemory *shm;
  36. PRIntn *counter_addr;
  37. PLOptStatus os;
  38. PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h");
  39. while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
  40. if (PL_OPT_BAD == os) {
  41. continue;
  42. }
  43. switch (opt->option) {
  44. case 'd': /* debug mode */
  45. debug_mode = PR_TRUE;
  46. break;
  47. case 'c': /* loop count */
  48. iterations = atoi(opt->value);
  49. break;
  50. case 'h':
  51. default:
  52. Help();
  53. return 2;
  54. }
  55. }
  56. PL_DestroyOptState(opt);
  57. shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), 0, 0666);
  58. if (NULL == shm) {
  59. fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n",
  60. PR_GetError(), PR_GetOSError());
  61. exit(1);
  62. }
  63. sem1 = PR_OpenSemaphore(SEM_NAME1, 0, 0, 0);
  64. if (NULL == sem1) {
  65. fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
  66. PR_GetError(), PR_GetOSError());
  67. exit(1);
  68. }
  69. sem2 = PR_OpenSemaphore(SEM_NAME2, 0, 0, 0);
  70. if (NULL == sem2) {
  71. fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
  72. PR_GetError(), PR_GetOSError());
  73. exit(1);
  74. }
  75. counter_addr = PR_AttachSharedMemory(shm, 0);
  76. if (NULL == counter_addr) {
  77. fprintf(stderr, "PR_AttachSharedMemory failed\n");
  78. exit(1);
  79. }
  80. /*
  81. * Process 2 waits on semaphore 2 and posts to semaphore 1.
  82. */
  83. for (i = 0; i < iterations; i++) {
  84. if (PR_WaitSemaphore(sem2) == PR_FAILURE) {
  85. fprintf(stderr, "PR_WaitSemaphore failed\n");
  86. exit(1);
  87. }
  88. if (*counter_addr == 2*i+1) {
  89. if (debug_mode) {
  90. printf("process 2: counter = %d\n", *counter_addr);
  91. }
  92. } else {
  93. fprintf(stderr, "process 2: counter should be %d but is %d\n",
  94. 2*i+1, *counter_addr);
  95. exit(1);
  96. }
  97. (*counter_addr)++;
  98. if (PR_PostSemaphore(sem1) == PR_FAILURE) {
  99. fprintf(stderr, "PR_PostSemaphore failed\n");
  100. exit(1);
  101. }
  102. }
  103. if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) {
  104. fprintf(stderr, "PR_DetachSharedMemory failed\n");
  105. exit(1);
  106. }
  107. if (PR_CloseSharedMemory(shm) == PR_FAILURE) {
  108. fprintf(stderr, "PR_CloseSharedMemory failed\n");
  109. exit(1);
  110. }
  111. if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
  112. fprintf(stderr, "PR_CloseSemaphore failed\n");
  113. }
  114. if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
  115. fprintf(stderr, "PR_CloseSemaphore failed\n");
  116. }
  117. printf("PASS\n");
  118. return 0;
  119. }