OLD | NEW |
1 /* Copyright (c) 2011 The Native Client Authors. All rights reserved. | 1 /* Copyright (c) 2011 The Native Client Authors. All rights reserved. |
2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 */ | 4 */ |
5 | 5 |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #include "native_client/src/include/atomic_ops.h" | 7 #include "native_client/src/include/atomic_ops.h" |
8 #include "native_client/src/shared/platform/nacl_threads.h" | 8 #include "native_client/src/shared/platform/nacl_threads.h" |
9 #include "native_client/src/shared/platform/nacl_sync_checked.h" | 9 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
10 #include "native_client/src/shared/platform/nacl_sync.h" | 10 #include "native_client/src/shared/platform/nacl_sync.h" |
11 | 11 |
12 #define THREAD_STACK_SIZE (128*1024) | 12 #define THREAD_STACK_SIZE (128*1024) |
13 | 13 |
14 int32_t gIncrementsPerThread = 1000; | 14 int32_t gIncrementsPerThread = 1000; |
15 int32_t gNumThreads; | 15 int32_t gNumThreads; |
16 | 16 |
17 struct NaClMutex gMutex; | 17 struct NaClMutex gMutex; |
18 struct NaClCondVar gFinishedCv; | |
19 int32_t gFinishedCount = 0; | |
20 | 18 |
21 | 19 |
22 /* For atomic counter test */ | 20 /* For atomic counter test */ |
23 Atomic32 gCounter = 0; | 21 Atomic32 gCounter = 0; |
24 | 22 |
25 static void IncrementTest() { | 23 static void IncrementTest() { |
26 /* Increment the counter, gIncrementsPerThread times, | 24 /* Increment the counter, gIncrementsPerThread times, |
27 * with the values 1...gIncrementsPerThread | 25 * with the values 1...gIncrementsPerThread |
28 */ | 26 */ |
29 Atomic32 i; | 27 Atomic32 i; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 IncrementTest(); | 81 IncrementTest(); |
84 DecrementTest(); | 82 DecrementTest(); |
85 } else { | 83 } else { |
86 DecrementTest(); | 84 DecrementTest(); |
87 IncrementTest(); | 85 IncrementTest(); |
88 } | 86 } |
89 | 87 |
90 ExchangeTest(tid); | 88 ExchangeTest(tid); |
91 | 89 |
92 CompareAndSwapTest(tid); | 90 CompareAndSwapTest(tid); |
93 | |
94 /* Signal that we're finished */ | |
95 NaClXMutexLock(&gMutex); | |
96 gFinishedCount++; | |
97 NaClXCondVarSignal(&gFinishedCv); | |
98 NaClXMutexUnlock(&gMutex); | |
99 | |
100 NaClThreadExit(0); | |
101 } | 91 } |
102 | 92 |
103 int main(int argc, const char *argv[]) { | 93 int main(int argc, const char *argv[]) { |
104 struct NaClThread *threads; | 94 struct NaClThread *threads; |
105 int rv; | 95 int rv; |
106 int32_t tid; | 96 int32_t tid; |
107 int32_t tmp; | 97 int32_t tmp; |
108 | 98 |
109 if (argc != 2) { | 99 if (argc != 2) { |
110 fprintf(stderr, "Usage: %s <NumThreads>\n", argv[0]); | 100 fprintf(stderr, "Usage: %s <NumThreads>\n", argv[0]); |
111 exit(EXIT_FAILURE); | 101 exit(EXIT_FAILURE); |
112 } | 102 } |
113 | 103 |
114 gNumThreads = strtol(argv[1], NULL, 10); | 104 gNumThreads = strtol(argv[1], NULL, 10); |
115 | 105 |
116 threads = (struct NaClThread*)malloc(gNumThreads*sizeof(struct NaClThread)); | 106 threads = (struct NaClThread*)malloc(gNumThreads*sizeof(struct NaClThread)); |
117 if (threads == NULL) { | 107 if (threads == NULL) { |
118 fprintf(stderr, "malloc returned NULL\n"); | 108 fprintf(stderr, "malloc returned NULL\n"); |
119 exit(EXIT_FAILURE); | 109 exit(EXIT_FAILURE); |
120 } | 110 } |
121 | 111 |
122 if (!NaClMutexCtor(&gMutex)) { | 112 if (!NaClMutexCtor(&gMutex)) { |
123 fprintf(stderr, "NaClMutexCtor failed\n"); | 113 fprintf(stderr, "NaClMutexCtor failed\n"); |
124 exit(EXIT_FAILURE); | 114 exit(EXIT_FAILURE); |
125 } | 115 } |
126 | 116 |
127 if (!NaClCondVarCtor(&gFinishedCv)) { | |
128 fprintf(stderr, "NaClCondVarCtor failed\n"); | |
129 exit(EXIT_FAILURE); | |
130 } | |
131 NaClXMutexLock(&gMutex); | 117 NaClXMutexLock(&gMutex); |
132 | 118 |
133 for (tid = 1; tid <= gNumThreads; ++tid) { | 119 for (tid = 1; tid <= gNumThreads; ++tid) { |
134 fprintf(stderr, "Creating thread %d\n", (int)tid); | 120 fprintf(stderr, "Creating thread %d\n", (int)tid); |
135 | 121 |
136 rv = NaClThreadCtor(&threads[tid-1], | 122 rv = NaClThreadCreateJoinable(&threads[tid-1], |
137 ThreadMain, | 123 ThreadMain, |
138 (void*) (intptr_t) tid, | 124 (void*) (intptr_t) tid, |
139 THREAD_STACK_SIZE); | 125 THREAD_STACK_SIZE); |
140 if (!rv) { | 126 if (!rv) { |
141 fprintf(stderr, "NaClThreadCtor failed\n"); | 127 fprintf(stderr, "NaClThreadCtor failed\n"); |
142 exit(EXIT_FAILURE); | 128 exit(EXIT_FAILURE); |
143 } | 129 } |
144 } | 130 } |
145 | 131 |
146 while (gFinishedCount != gNumThreads) { | 132 NaClXMutexUnlock(&gMutex); |
147 /* This releases the mutex, so the tests begin */ | 133 |
148 NaClXCondVarWait(&gFinishedCv, &gMutex); | 134 for (tid = 1; tid <= gNumThreads; ++tid) { |
| 135 NaClThreadJoin(&threads[tid-1]); |
149 } | 136 } |
150 NaClXMutexUnlock(&gMutex); | |
151 | 137 |
152 /* Check the results */ | 138 /* Check the results */ |
153 tmp = gIncrementsPerThread * gNumThreads; | 139 tmp = gIncrementsPerThread * gNumThreads; |
154 if (gCounter != tmp) { | 140 if (gCounter != tmp) { |
155 fprintf(stderr, "ERROR: gCounter is wrong. Expected %d, got %d\n", | 141 fprintf(stderr, "ERROR: gCounter is wrong. Expected %d, got %d\n", |
156 (int)tmp, (int)gCounter); | 142 (int)tmp, (int)gCounter); |
157 exit(EXIT_FAILURE); | 143 exit(EXIT_FAILURE); |
158 } | 144 } |
159 | 145 |
160 tmp = gNumThreads*(gNumThreads+1)/2; | 146 tmp = gNumThreads*(gNumThreads+1)/2; |
161 if (gExchange + gExchangeSum != tmp) { | 147 if (gExchange + gExchangeSum != tmp) { |
162 fprintf(stderr, | 148 fprintf(stderr, |
163 "ERROR: gExchange+gExchangeSum is wrong. Expected %d, got %d\n", | 149 "ERROR: gExchange+gExchangeSum is wrong. Expected %d, got %d\n", |
164 (int)tmp, (int)(gExchange + gExchangeSum)); | 150 (int)tmp, (int)(gExchange + gExchangeSum)); |
165 exit(EXIT_FAILURE); | 151 exit(EXIT_FAILURE); |
166 } | 152 } |
167 | 153 |
168 if (gSwap != gNumThreads+1) { | 154 if (gSwap != gNumThreads+1) { |
169 fprintf(stderr, "ERROR: gSwap is wrong. Expected %d, got %d\n", | 155 fprintf(stderr, "ERROR: gSwap is wrong. Expected %d, got %d\n", |
170 (int)(gNumThreads+1), (int)gSwap); | 156 (int)(gNumThreads+1), (int)gSwap); |
171 exit(EXIT_FAILURE); | 157 exit(EXIT_FAILURE); |
172 } | 158 } |
173 | 159 |
174 fprintf(stderr, "PASSED\n"); | 160 fprintf(stderr, "PASSED\n"); |
175 NaClCondVarDtor(&gFinishedCv); | |
176 NaClMutexDtor(&gMutex); | 161 NaClMutexDtor(&gMutex); |
177 free(threads); | 162 free(threads); |
178 return 0; | 163 return 0; |
179 } | 164 } |
OLD | NEW |