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