| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include "native_client/src/include/portability.h" | 9 #include "native_client/src/include/portability.h" |
| 10 #include "native_client/src/include/nacl_macros.h" | 10 #include "native_client/src/include/nacl_macros.h" |
| 11 | 11 |
| 12 #include "native_client/src/shared/platform/nacl_semaphore.h" | 12 #include "native_client/src/shared/platform/nacl_semaphore.h" |
| 13 | 13 |
| 14 #include "native_client/src/shared/platform/nacl_sync.h" | 14 #include "native_client/src/shared/platform/nacl_sync.h" |
| 15 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
| 15 #include "native_client/src/shared/platform/nacl_threads.h" | 16 #include "native_client/src/shared/platform/nacl_threads.h" |
| 16 #include "native_client/src/shared/platform/nacl_time.h" | 17 #include "native_client/src/shared/platform/nacl_time.h" |
| 17 #include "native_client/src/shared/platform/platform_init.h" | 18 #include "native_client/src/shared/platform/platform_init.h" |
| 18 | 19 |
| 19 #include "native_client/src/trusted/service_runtime/include/sys/time.h" | 20 #include "native_client/src/trusted/service_runtime/include/sys/time.h" |
| 20 | 21 |
| 21 #define STACK_SIZE_BYTES (4 * 4096) | 22 #define STACK_SIZE_BYTES (4 * 4096) |
| 22 #define NUM_TRIES_SUFFICIENT (5) | 23 #define NUM_TRIES_SUFFICIENT (5) |
| 23 | 24 |
| 24 void ThreadSleepMs(uint64_t msec) { | 25 void ThreadSleepMs(uint64_t msec) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 47 int got_sem = 0; | 48 int got_sem = 0; |
| 48 int failed = 0; | 49 int failed = 0; |
| 49 | 50 |
| 50 for (sleep_count = 0; sleep_count < gNumTriesSufficient; ++sleep_count) { | 51 for (sleep_count = 0; sleep_count < gNumTriesSufficient; ++sleep_count) { |
| 51 /* the sem_trywait should not succeed the first time through */ | 52 /* the sem_trywait should not succeed the first time through */ |
| 52 if (NACL_SYNC_BUSY != NaClSemTryWait(&gSem)) { | 53 if (NACL_SYNC_BUSY != NaClSemTryWait(&gSem)) { |
| 53 got_sem = 1; | 54 got_sem = 1; |
| 54 break; | 55 break; |
| 55 } | 56 } |
| 56 if (0 == sleep_count) { | 57 if (0 == sleep_count) { |
| 57 NaClMutexLock(&gMu); | 58 NaClXMutexLock(&gMu); |
| 58 ++gNumThreadsTried; | 59 ++gNumThreadsTried; |
| 59 NaClMutexUnlock(&gMu); | 60 NaClXCondVarSignal(&gCv); |
| 60 NaClCondVarSignal(&gCv); | 61 NaClXMutexUnlock(&gMu); |
| 61 } | 62 } |
| 62 PauseSpinningThread(); | 63 PauseSpinningThread(); |
| 63 } | 64 } |
| 64 | 65 |
| 65 if (got_sem) { | 66 if (got_sem) { |
| 66 printf("Thread %d: NaClSemTryWait succeeded at %"NACL_PRId64"\n", | 67 printf("Thread %d: NaClSemTryWait succeeded at %"NACL_PRId64"\n", |
| 67 thread_num, | 68 thread_num, |
| 68 sleep_count); | 69 sleep_count); |
| 69 } else { | 70 } else { |
| 70 /* gNumThreadsTried == sleep_count */ | 71 /* gNumThreadsTried == sleep_count */ |
| 71 printf("Thread %d: NaClSemWait\n", thread_num); | 72 printf("Thread %d: NaClSemWait\n", thread_num); |
| 72 if (NACL_SYNC_OK != NaClSemWait(&gSem)) { | 73 if (NACL_SYNC_OK != NaClSemWait(&gSem)) { |
| 73 printf("FAILED\n"); | 74 printf("FAILED\n"); |
| 74 printf("NaClSemWait failed!?!\n"); | 75 printf("NaClSemWait failed!?!\n"); |
| 75 failed = 1; | 76 failed = 1; |
| 76 } | 77 } |
| 77 } | 78 } |
| 78 | 79 |
| 79 if (0 == sleep_count) { | 80 if (0 == sleep_count) { |
| 80 printf("FAILED\n"); | 81 printf("FAILED\n"); |
| 81 printf("Thread %d never actually waited at NaClSemTryWait\n", thread_num); | 82 printf("Thread %d never actually waited at NaClSemTryWait\n", thread_num); |
| 82 failed = 1; | 83 failed = 1; |
| 83 } else { | 84 } else { |
| 84 printf("OK -- thread %d\n", thread_num); | 85 printf("OK -- thread %d\n", thread_num); |
| 85 } | 86 } |
| 86 | 87 |
| 87 NaClMutexLock(&gMu); | 88 NaClXMutexLock(&gMu); |
| 88 gFailure += failed; | 89 gFailure += failed; |
| 89 ++gNumThreadsDone; | 90 ++gNumThreadsDone; |
| 90 NaClCondVarSignal(&gCv); | 91 NaClXCondVarSignal(&gCv); |
| 91 NaClMutexUnlock(&gMu); | 92 NaClXMutexUnlock(&gMu); |
| 92 } | 93 } |
| 93 | 94 |
| 94 int main(int ac, char **av) { | 95 int main(int ac, char **av) { |
| 95 int exit_status = -1; | 96 int exit_status = -1; |
| 96 int opt; | 97 int opt; |
| 97 size_t num_threads = 16; | 98 size_t num_threads = 16; |
| 98 size_t n; | 99 size_t n; |
| 99 struct NaClThread thr; | 100 struct NaClThread thr; |
| 100 | 101 |
| 101 while (EOF != (opt = getopt(ac, av, "n:s:t:"))) { | 102 while (EOF != (opt = getopt(ac, av, "n:s:t:"))) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 for (n = 0; n < num_threads; ++n) { | 134 for (n = 0; n < num_threads; ++n) { |
| 134 if (!NaClThreadCtor(&thr, ThreadMain, (void *) (uintptr_t) n, | 135 if (!NaClThreadCtor(&thr, ThreadMain, (void *) (uintptr_t) n, |
| 135 STACK_SIZE_BYTES)) { | 136 STACK_SIZE_BYTES)) { |
| 136 fprintf(stderr, | 137 fprintf(stderr, |
| 137 "nacl_semaphore_test: could not create thread %"NACL_PRIdS"\n", | 138 "nacl_semaphore_test: could not create thread %"NACL_PRIdS"\n", |
| 138 n); | 139 n); |
| 139 goto cleanup4; /* osx leak semaphore otherwise */ | 140 goto cleanup4; /* osx leak semaphore otherwise */ |
| 140 } | 141 } |
| 141 } | 142 } |
| 142 | 143 |
| 143 NaClMutexLock(&gMu); | 144 NaClXMutexLock(&gMu); |
| 144 while (gNumThreadsTried != num_threads) { | 145 while (gNumThreadsTried != num_threads) { |
| 145 NaClCondVarWait(&gCv, &gMu); | 146 NaClXCondVarWait(&gCv, &gMu); |
| 146 } | 147 } |
| 147 NaClMutexUnlock(&gMu); | 148 NaClXMutexUnlock(&gMu); |
| 148 | 149 |
| 149 for (n = 0; n < num_threads; ++n) { | 150 for (n = 0; n < num_threads; ++n) { |
| 150 NaClSemPost(&gSem); /* let a thread go */ | 151 NaClSemPost(&gSem); /* let a thread go */ |
| 151 } | 152 } |
| 152 | 153 |
| 153 NaClMutexLock(&gMu); | 154 NaClXMutexLock(&gMu); |
| 154 while (gNumThreadsDone != num_threads) { | 155 while (gNumThreadsDone != num_threads) { |
| 155 NaClCondVarWait(&gCv, &gMu); | 156 NaClXCondVarWait(&gCv, &gMu); |
| 156 } | 157 } |
| 157 exit_status = gFailure; | 158 exit_status = gFailure; |
| 158 NaClMutexUnlock(&gMu); | 159 NaClXMutexUnlock(&gMu); |
| 159 | 160 |
| 160 if (0 == exit_status) { | 161 if (0 == exit_status) { |
| 161 printf("SUCCESS\n"); | 162 printf("SUCCESS\n"); |
| 162 } | 163 } |
| 163 cleanup4: | 164 cleanup4: |
| 164 /* single exit with (ah hem) simulation of RAII via cleanup sled */ | 165 /* single exit with (ah hem) simulation of RAII via cleanup sled */ |
| 165 NaClCondVarDtor(&gCv); | 166 NaClCondVarDtor(&gCv); |
| 166 cleanup3: | 167 cleanup3: |
| 167 NaClMutexDtor(&gMu); | 168 NaClMutexDtor(&gMu); |
| 168 cleanup2: | 169 cleanup2: |
| 169 NaClSemDtor(&gSem); | 170 NaClSemDtor(&gSem); |
| 170 cleanup1: | 171 cleanup1: |
| 171 NaClPlatformFini(); | 172 NaClPlatformFini(); |
| 172 cleanup0: | 173 cleanup0: |
| 173 return exit_status; | 174 return exit_status; |
| 174 } | 175 } |
| OLD | NEW |