semapong.c (3486B)
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 SHM_NAME "/tmp/counter" SEM_D SEM_64 23 #define SEM_NAME1 "/tmp/foo.sem" SEM_D SEM_64 24 #define SEM_NAME2 "/tmp/bar.sem" SEM_D SEM_64 25 #define ITERATIONS 1000 26 27 static PRBool debug_mode = PR_FALSE; 28 static PRIntn iterations = ITERATIONS; 29 static PRSem *sem1, *sem2; 30 31 static void Help(void) { 32 fprintf(stderr, "semapong test program usage:\n"); 33 fprintf(stderr, "\t-d debug mode (FALSE)\n"); 34 fprintf(stderr, "\t-c <count> loop count (%d)\n", ITERATIONS); 35 fprintf(stderr, "\t-h this message\n"); 36 } /* Help */ 37 38 int main(int argc, char** argv) { 39 PRIntn i; 40 PRSharedMemory* shm; 41 PRIntn* counter_addr; 42 PLOptStatus os; 43 PLOptState* opt = PL_CreateOptState(argc, argv, "dc:h"); 44 45 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { 46 if (PL_OPT_BAD == os) { 47 continue; 48 } 49 switch (opt->option) { 50 case 'd': /* debug mode */ 51 debug_mode = PR_TRUE; 52 break; 53 case 'c': /* loop count */ 54 iterations = atoi(opt->value); 55 break; 56 case 'h': 57 default: 58 Help(); 59 return 2; 60 } 61 } 62 PL_DestroyOptState(opt); 63 64 shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), 0, 0666); 65 if (NULL == shm) { 66 fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n", PR_GetError(), 67 PR_GetOSError()); 68 exit(1); 69 } 70 sem1 = PR_OpenSemaphore(SEM_NAME1, 0, 0, 0); 71 if (NULL == sem1) { 72 fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", PR_GetError(), 73 PR_GetOSError()); 74 exit(1); 75 } 76 sem2 = PR_OpenSemaphore(SEM_NAME2, 0, 0, 0); 77 if (NULL == sem2) { 78 fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", PR_GetError(), 79 PR_GetOSError()); 80 exit(1); 81 } 82 83 counter_addr = PR_AttachSharedMemory(shm, 0); 84 if (NULL == counter_addr) { 85 fprintf(stderr, "PR_AttachSharedMemory failed\n"); 86 exit(1); 87 } 88 89 /* 90 * Process 2 waits on semaphore 2 and posts to semaphore 1. 91 */ 92 for (i = 0; i < iterations; i++) { 93 if (PR_WaitSemaphore(sem2) == PR_FAILURE) { 94 fprintf(stderr, "PR_WaitSemaphore failed\n"); 95 exit(1); 96 } 97 if (*counter_addr == 2 * i + 1) { 98 if (debug_mode) { 99 printf("process 2: counter = %d\n", *counter_addr); 100 } 101 } else { 102 fprintf(stderr, "process 2: counter should be %d but is %d\n", 2 * i + 1, 103 *counter_addr); 104 exit(1); 105 } 106 (*counter_addr)++; 107 if (PR_PostSemaphore(sem1) == PR_FAILURE) { 108 fprintf(stderr, "PR_PostSemaphore failed\n"); 109 exit(1); 110 } 111 } 112 if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) { 113 fprintf(stderr, "PR_DetachSharedMemory failed\n"); 114 exit(1); 115 } 116 if (PR_CloseSharedMemory(shm) == PR_FAILURE) { 117 fprintf(stderr, "PR_CloseSharedMemory failed\n"); 118 exit(1); 119 } 120 if (PR_CloseSemaphore(sem1) == PR_FAILURE) { 121 fprintf(stderr, "PR_CloseSemaphore failed\n"); 122 } 123 if (PR_CloseSemaphore(sem2) == PR_FAILURE) { 124 fprintf(stderr, "PR_CloseSemaphore failed\n"); 125 } 126 printf("PASS\n"); 127 return 0; 128 }