sema.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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 SEM_NAME1 "/tmp/foo.sem" SEM_D SEM_64
  19. #define SEM_NAME2 "/tmp/bar.sem" SEM_D SEM_64
  20. #define SEM_MODE 0666
  21. #define ITERATIONS 1000
  22. static PRBool debug_mode = PR_FALSE;
  23. static PRIntn iterations = ITERATIONS;
  24. static PRIntn counter;
  25. static PRSem *sem1, *sem2;
  26. /*
  27. * Thread 2 waits on semaphore 2 and posts to semaphore 1.
  28. */
  29. void ThreadFunc(void *arg)
  30. {
  31. PRIntn i;
  32. for (i = 0; i < iterations; i++) {
  33. if (PR_WaitSemaphore(sem2) == PR_FAILURE) {
  34. fprintf(stderr, "PR_WaitSemaphore failed\n");
  35. exit(1);
  36. }
  37. if (counter == 2*i+1) {
  38. if (debug_mode) {
  39. printf("thread 2: counter = %d\n", counter);
  40. }
  41. } else {
  42. fprintf(stderr, "thread 2: counter should be %d but is %d\n",
  43. 2*i+1, counter);
  44. exit(1);
  45. }
  46. counter++;
  47. if (PR_PostSemaphore(sem1) == PR_FAILURE) {
  48. fprintf(stderr, "PR_PostSemaphore failed\n");
  49. exit(1);
  50. }
  51. }
  52. }
  53. static void Help(void)
  54. {
  55. fprintf(stderr, "sema test program usage:\n");
  56. fprintf(stderr, "\t-d debug mode (FALSE)\n");
  57. fprintf(stderr, "\t-c <count> loop count (%d)\n", ITERATIONS);
  58. fprintf(stderr, "\t-h this message\n");
  59. } /* Help */
  60. int main(int argc, char **argv)
  61. {
  62. PRThread *thred;
  63. PRIntn i;
  64. PLOptStatus os;
  65. PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h");
  66. while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
  67. if (PL_OPT_BAD == os) {
  68. continue;
  69. }
  70. switch (opt->option) {
  71. case 'd': /* debug mode */
  72. debug_mode = PR_TRUE;
  73. break;
  74. case 'c': /* loop count */
  75. iterations = atoi(opt->value);
  76. break;
  77. case 'h':
  78. default:
  79. Help();
  80. return 2;
  81. }
  82. }
  83. PL_DestroyOptState(opt);
  84. if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
  85. fprintf(stderr, "warning: removed semaphore %s left over "
  86. "from previous run\n", SEM_NAME1);
  87. }
  88. if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) {
  89. fprintf(stderr, "warning: removed semaphore %s left over "
  90. "from previous run\n", SEM_NAME2);
  91. }
  92. sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1);
  93. if (NULL == sem1) {
  94. fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
  95. PR_GetError(), PR_GetOSError());
  96. exit(1);
  97. }
  98. sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0);
  99. if (NULL == sem2) {
  100. fprintf(stderr, "PR_OpenSemaphore failed\n");
  101. exit(1);
  102. }
  103. thred = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
  104. PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
  105. if (NULL == thred) {
  106. fprintf(stderr, "PR_CreateThread failed\n");
  107. exit(1);
  108. }
  109. /*
  110. * Thread 1 waits on semaphore 1 and posts to semaphore 2.
  111. */
  112. for (i = 0; i < iterations; i++) {
  113. if (PR_WaitSemaphore(sem1) == PR_FAILURE) {
  114. fprintf(stderr, "PR_WaitSemaphore failed\n");
  115. exit(1);
  116. }
  117. if (counter == 2*i) {
  118. if (debug_mode) {
  119. printf("thread 1: counter = %d\n", counter);
  120. }
  121. } else {
  122. fprintf(stderr, "thread 1: counter should be %d but is %d\n",
  123. 2*i, counter);
  124. exit(1);
  125. }
  126. counter++;
  127. if (PR_PostSemaphore(sem2) == PR_FAILURE) {
  128. fprintf(stderr, "PR_PostSemaphore failed\n");
  129. exit(1);
  130. }
  131. }
  132. if (PR_JoinThread(thred) == PR_FAILURE) {
  133. fprintf(stderr, "PR_JoinThread failed\n");
  134. exit(1);
  135. }
  136. if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
  137. fprintf(stderr, "PR_CloseSemaphore failed\n");
  138. }
  139. if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
  140. fprintf(stderr, "PR_CloseSemaphore failed\n");
  141. }
  142. if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
  143. fprintf(stderr, "PR_DeleteSemaphore failed\n");
  144. }
  145. if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) {
  146. fprintf(stderr, "PR_DeleteSemaphore failed\n");
  147. }
  148. printf("PASS\n");
  149. return 0;
  150. }