1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/tests/semaping.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,179 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nspr.h" 1.10 +#include "plgetopt.h" 1.11 + 1.12 +#include <stdio.h> 1.13 + 1.14 +#ifdef SYMBIAN 1.15 +#define SHM_NAME "c:\\data\\counter" 1.16 +#define SEM_NAME1 "c:\\data\\foo.sem" 1.17 +#define SEM_NAME2 "c:\\data\\bar.sem" 1.18 +#define EXE_NAME "nspr_tests_semapong.exe" 1.19 +#else 1.20 +#define SHM_NAME "/tmp/counter" 1.21 +#define SEM_NAME1 "/tmp/foo.sem" 1.22 +#define SEM_NAME2 "/tmp/bar.sem" 1.23 +#define EXE_NAME "semapong" 1.24 +#endif 1.25 +#define SEM_MODE 0666 1.26 +#define SHM_MODE 0666 1.27 +#define ITERATIONS 1000 1.28 + 1.29 +static PRBool debug_mode = PR_FALSE; 1.30 +static PRIntn iterations = ITERATIONS; 1.31 +static PRSem *sem1, *sem2; 1.32 + 1.33 +static void Help(void) 1.34 +{ 1.35 + fprintf(stderr, "semaping test program usage:\n"); 1.36 + fprintf(stderr, "\t-d debug mode (FALSE)\n"); 1.37 + fprintf(stderr, "\t-c <count> loop count (%d)\n", ITERATIONS); 1.38 + fprintf(stderr, "\t-h this message\n"); 1.39 +} /* Help */ 1.40 + 1.41 +int main(int argc, char **argv) 1.42 +{ 1.43 + PRProcess *proc; 1.44 + PRIntn i; 1.45 + char *child_argv[32]; 1.46 + char **child_arg; 1.47 + char iterations_buf[32]; 1.48 + PRSharedMemory *shm; 1.49 + PRIntn *counter_addr; 1.50 + PRInt32 exit_code; 1.51 + PLOptStatus os; 1.52 + PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h"); 1.53 + 1.54 + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { 1.55 + if (PL_OPT_BAD == os) continue; 1.56 + switch (opt->option) { 1.57 + case 'd': /* debug mode */ 1.58 + debug_mode = PR_TRUE; 1.59 + break; 1.60 + case 'c': /* loop count */ 1.61 + iterations = atoi(opt->value); 1.62 + break; 1.63 + case 'h': 1.64 + default: 1.65 + Help(); 1.66 + return 2; 1.67 + } 1.68 + } 1.69 + PL_DestroyOptState(opt); 1.70 + 1.71 + if (PR_DeleteSharedMemory(SHM_NAME) == PR_SUCCESS) { 1.72 + fprintf(stderr, "warning: removed shared memory %s left over " 1.73 + "from previous run\n", SHM_NAME); 1.74 + } 1.75 + if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) { 1.76 + fprintf(stderr, "warning: removed semaphore %s left over " 1.77 + "from previous run\n", SEM_NAME1); 1.78 + } 1.79 + if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) { 1.80 + fprintf(stderr, "warning: removed semaphore %s left over " 1.81 + "from previous run\n", SEM_NAME2); 1.82 + } 1.83 + 1.84 + shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), PR_SHM_CREATE, SHM_MODE); 1.85 + if (NULL == shm) { 1.86 + fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n", 1.87 + PR_GetError(), PR_GetOSError()); 1.88 + exit(1); 1.89 + } 1.90 + counter_addr = PR_AttachSharedMemory(shm, 0); 1.91 + if (NULL == counter_addr) { 1.92 + fprintf(stderr, "PR_AttachSharedMemory failed\n"); 1.93 + exit(1); 1.94 + } 1.95 + *counter_addr = 0; 1.96 + sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1); 1.97 + if (NULL == sem1) { 1.98 + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", 1.99 + PR_GetError(), PR_GetOSError()); 1.100 + exit(1); 1.101 + } 1.102 + sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0); 1.103 + if (NULL == sem2) { 1.104 + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", 1.105 + PR_GetError(), PR_GetOSError()); 1.106 + exit(1); 1.107 + } 1.108 + 1.109 + child_arg = &child_argv[0]; 1.110 + *child_arg++ = EXE_NAME; 1.111 + if (debug_mode != PR_FALSE) { 1.112 + *child_arg++ = "-d"; 1.113 + } 1.114 + if (iterations != ITERATIONS) { 1.115 + *child_arg++ = "-c"; 1.116 + PR_snprintf(iterations_buf, sizeof(iterations_buf), "%d", iterations); 1.117 + *child_arg++ = iterations_buf; 1.118 + } 1.119 + *child_arg = NULL; 1.120 + proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); 1.121 + if (NULL == proc) { 1.122 + fprintf(stderr, "PR_CreateProcess failed\n"); 1.123 + exit(1); 1.124 + } 1.125 + 1.126 + /* 1.127 + * Process 1 waits on semaphore 1 and posts to semaphore 2. 1.128 + */ 1.129 + for (i = 0; i < iterations; i++) { 1.130 + if (PR_WaitSemaphore(sem1) == PR_FAILURE) { 1.131 + fprintf(stderr, "PR_WaitSemaphore failed\n"); 1.132 + exit(1); 1.133 + } 1.134 + if (*counter_addr == 2*i) { 1.135 + if (debug_mode) printf("process 1: counter = %d\n", *counter_addr); 1.136 + } else { 1.137 + fprintf(stderr, "process 1: counter should be %d but is %d\n", 1.138 + 2*i, *counter_addr); 1.139 + exit(1); 1.140 + } 1.141 + (*counter_addr)++; 1.142 + if (PR_PostSemaphore(sem2) == PR_FAILURE) { 1.143 + fprintf(stderr, "PR_PostSemaphore failed\n"); 1.144 + exit(1); 1.145 + } 1.146 + } 1.147 + if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) { 1.148 + fprintf(stderr, "PR_DetachSharedMemory failed\n"); 1.149 + exit(1); 1.150 + } 1.151 + if (PR_CloseSharedMemory(shm) == PR_FAILURE) { 1.152 + fprintf(stderr, "PR_CloseSharedMemory failed\n"); 1.153 + exit(1); 1.154 + } 1.155 + if (PR_CloseSemaphore(sem1) == PR_FAILURE) { 1.156 + fprintf(stderr, "PR_CloseSemaphore failed\n"); 1.157 + } 1.158 + if (PR_CloseSemaphore(sem2) == PR_FAILURE) { 1.159 + fprintf(stderr, "PR_CloseSemaphore failed\n"); 1.160 + } 1.161 + 1.162 + if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) { 1.163 + fprintf(stderr, "PR_WaitProcess failed\n"); 1.164 + exit(1); 1.165 + } 1.166 + if (exit_code != 0) { 1.167 + fprintf(stderr, "process 2 failed with exit code %d\n", exit_code); 1.168 + exit(1); 1.169 + } 1.170 + 1.171 + if (PR_DeleteSharedMemory(SHM_NAME) == PR_FAILURE) { 1.172 + fprintf(stderr, "PR_DeleteSharedMemory failed\n"); 1.173 + } 1.174 + if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) { 1.175 + fprintf(stderr, "PR_DeleteSemaphore failed\n"); 1.176 + } 1.177 + if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) { 1.178 + fprintf(stderr, "PR_DeleteSemaphore failed\n"); 1.179 + } 1.180 + printf("PASS\n"); 1.181 + return 0; 1.182 +}