| 33 | } |
| 34 | |
| 35 | void *ThreadMain(void *arg) { |
| 36 | assert(pthread_self() != 0); |
| 37 | assert(globalDouble == 5.0); |
| 38 | assert(globalU64 == 5); |
| 39 | struct Test *t = (struct Test*)arg; |
| 40 | emscripten_outf("Thread %d for test %d: starting computation", t->threadId, t->op); |
| 41 | |
| 42 | for (int i = 0; i < 99999; ++i) { |
| 43 | for (int j = 0; j < DATA_COUNT; ++j) { |
| 44 | switch (t->op) { |
| 45 | case 0: emscripten_atomic_add_u64(&sharedData[j], 1); break; |
| 46 | case 1: emscripten_atomic_sub_u64(&sharedData[j], 1); break; |
| 47 | case 2: emscripten_atomic_and_u64(&sharedData[j], ~(1UL << t->threadId)); break; |
| 48 | case 3: emscripten_atomic_or_u64(&sharedData[j], 1UL << t->threadId); break; |
| 49 | case 4: emscripten_atomic_xor_u64(&sharedData[j], 1UL << t->threadId); break; |
| 50 | case 5: { |
| 51 | // Atomically load and store data, and test that each individual u8 is the same. |
| 52 | uint64_t data = emscripten_atomic_load_u64(&sharedData[j]); |
| 53 | uint8_t dataU8[8]; |
| 54 | memcpy(dataU8, &data, 8); |
| 55 | assert(dataU8[0] >= 10 && dataU8[0] < 10+NUM_THREADS); |
| 56 | assert(dataU8[0] == dataU8[1] && dataU8[0] == dataU8[2] && dataU8[0] == dataU8[3]); |
| 57 | assert(dataU8[0] == dataU8[4] && dataU8[0] == dataU8[5] && dataU8[0] == dataU8[6] && dataU8[0] == dataU8[7]); |
| 58 | dataU8[0] = dataU8[1] = dataU8[2] = dataU8[3] = dataU8[4] = dataU8[5] = dataU8[6] = dataU8[7] = 10 + t->threadId; |
| 59 | memcpy(&data, dataU8, 8); |
| 60 | emscripten_atomic_store_u64(&sharedData[j], data); |
| 61 | } |
| 62 | break; |
| 63 | case 6: { |
| 64 | uint64_t newData = rand_60(); |
| 65 | uint64_t data; |
| 66 | uint64_t prevData; |
| 67 | do { |
| 68 | data = emscripten_atomic_load_u64(&sharedData[j]); |
| 69 | prevData = emscripten_atomic_cas_u64(&sharedData[j], data, newData); |
| 70 | } while(prevData != data); |
| 71 | threadCasAccumulatedReadData[t->threadId] += data; |
| 72 | threadCasAccumulatedWrittenData[t->threadId] += newData; |
| 73 | } |
| 74 | break; |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | emscripten_outf("Thread %d for test %d: finished, exit()ing", t->threadId, t->op); |
| 79 | pthread_exit(0); |
| 80 | } |
| 81 | |
| 82 | struct Test t[NUM_THREADS] = {}; |
| 83 | pthread_t thread[NUM_THREADS]; |
nothing calls this directly
no test coverage detected