void CreateThread(int i) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); int rc = pthread_create(&thread[i], &attr, ThreadMain, (void*)i); if (emscripten_has_threading_support()) assert(rc == 0); else assert(rc == EAGAIN); pthread_attr_destroy(&attr); }
int main() { { T x = 5; T y = nand_and_fetch(&x, 9); assert(y == -2); assert(x == -2); const int oddNThreads = NUM_THREADS-1; for(int x = 0; x < 100; ++x) // Test a few times for robustness, since this test is so short-lived. { nand_and_fetch_data = 0; __sync_synchronize(); // This has no effect in this code, but called in here just to test that the compiler generates a valid expression for this. if (emscripten_has_threading_support()) { for(int i = 0; i < oddNThreads; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch, (void*)-1); for(int i = 0; i < oddNThreads; ++i) pthread_join(thread[i], NULL); assert(nand_and_fetch_data == -1); } } } { T x = 5; T y = nand_and_fetch_bool(&x, 9); assert(y == -2); assert(x == -2); const int oddNThreads = NUM_THREADS-1; for(int x = 0; x < 100; ++x) // Test a few times for robustness, since this test is so short-lived. { nand_and_fetch_data = 0; if (emscripten_has_threading_support()) { for(int i = 0; i < oddNThreads; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch_bool, (void*)-1); for(int i = 0; i < oddNThreads; ++i) pthread_join(thread[i], NULL); assert(nand_and_fetch_data == -1); } } } #ifdef REPORT_RESULT REPORT_RESULT(0); #endif }
int main() { for(int x = 0; x < 1000; ++x) { for(int i = 0; i < NUM_THREADS; ++i) pthread_create(&thread[i], NULL, thread_main, 0); if (emscripten_has_threading_support()) for(int i = 0; i < NUM_THREADS; ++i) pthread_join(thread[i], NULL); } #ifdef REPORT_RESULT int result = 0; REPORT_RESULT(); #endif }
int main() { assert(numInitialized == 0); for(int i = 0; i < NUM_THREADS; ++i) pthread_create(&thread[i], NULL, thread_main, 0); if (emscripten_has_threading_support()) { for(int i = 0; i < NUM_THREADS; ++i) pthread_join(thread[i], NULL); assert(numInitialized == 1); } #ifdef REPORT_RESULT REPORT_RESULT(0); #endif }
int main(void) { pthread_t thread; puts("a"); pthread_create(&thread, NULL, thread_func, NULL); if (emscripten_has_threading_support()) { pthread_join(thread, NULL); } else { result = 1; } #ifdef REPORT_RESULT REPORT_RESULT(result); #endif return 0; }
int main() { int result; if (!emscripten_has_threading_support()) { #ifdef REPORT_RESULT result = 0; REPORT_RESULT(); #endif printf("Skipped: Threading is not supported.\n"); return 0; } sharedVar = 0; int s = pthread_create(&thr, NULL, thread_start, 0); assert(s == 0); // Wait until thread kicks in and sets the shared variable. while(sharedVar == 0) BusySleep(10); s = pthread_kill(thr, SIGKILL); assert(s == 0); // Wait until we see the shared variable stop incrementing. (This is a bit heuristic and hacky) for(;;) { int val = emscripten_atomic_load_u32((void*)&sharedVar); BusySleep(100); int val2 = emscripten_atomic_load_u32((void*)&sharedVar); if (val == val2) break; } // Reset to 0. sharedVar = 0; emscripten_atomic_store_u32((void*)&sharedVar, 0); // Wait for a long time, if the thread is still running, it should progress and set sharedVar by this time. BusySleep(3000); // Finally test that the thread is not doing any work and it is dead. assert(sharedVar == 0); assert(emscripten_atomic_load_u32((void*)&sharedVar) == 0); EM_ASM_INT( { Module['print']('Main: Done. Successfully killed thread. sharedVar: '+$0+'.'); }, sharedVar);
int main() { globalDouble = 5.0; globalU64 = 4; uint64_t prevU64 = emscripten_atomic_add_u64((void*)&globalU64, 1); assert(prevU64 == 4); if (!emscripten_has_threading_support()) { #ifdef REPORT_RESULT REPORT_RESULT(0); #endif printf("Skipped: Threading is not supported.\n"); return 0; } for(int i = 0; i < 7; ++i) RunTest(i); uint64_t totalRead = 0; uint64_t totalWritten = 0; for(int i = 0; i < NUM_THREADS; ++i) { totalRead += threadCasAccumulatedReadData[i]; totalWritten += threadCasAccumulatedWrittenData[i]; } for(int i = 0; i < N; ++i) totalRead += sharedData[i]; if (totalRead == totalWritten) printf("totalRead: %llu, totalWritten: %llu\n", totalRead, totalWritten); else printf("64-bit CAS test failed! totalRead != totalWritten (%llu != %llu)\n", totalRead, totalWritten); #ifdef REPORT_RESULT int result = (totalRead != totalWritten) ? 1 : 0; REPORT_RESULT(result); #else EM_ASM(out('Main: Test successfully finished.')); #endif }
int main() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&lock, &attr); pthread_mutex_lock(&lock); pthread_mutex_unlock(&lock); if (emscripten_has_threading_support()) { // Create new threads in parallel. for(int i = 0; i < NUM_THREADS; ++i) CreateThread(i, threadNum++); emscripten_set_main_loop(WaitToJoin, 0, 0); } else { #ifdef REPORT_RESULT REPORT_RESULT(50); #endif } }
int main() { for(int i = 0; i < NUM_KEYS; ++i) pthread_key_create(&keys[i], NULL); // Create initial threads. for(int i = 0; i < NUM_THREADS; ++i) CreateThread(i); // Join all threads and create more. if (emscripten_has_threading_support()) { for(int i = 0; i < NUM_THREADS; ++i) { if (thread[i]) { int status; int rc = pthread_join(thread[i], (void**)&status); assert(rc == 0); EM_ASM(Module['printErr']('Main: Joined thread idx ' + $0 + ' with status ' + $1), i, (int)status); assert(status == 0); thread[i] = 0; if (numThreadsToCreate > 0) { --numThreadsToCreate; CreateThread(i); } } } } #ifdef REPORT_RESULT REPORT_RESULT(0); #endif for(int i = 0; i < NUM_KEYS; ++i) pthread_key_delete(keys[i]); }
int main() { int result; if (!emscripten_has_threading_support()) { #ifdef REPORT_RESULT result = 1; REPORT_RESULT(); #endif printf("Skipped: Threading is not supported.\n"); return 0; } pthread_t thr; int rc = pthread_create(&thr, NULL, thread_start, (void*)0); if (rc != 0) { #ifdef REPORT_RESULT int result = (rc != EAGAIN); REPORT_RESULT(); return 0; #endif } #ifdef USE_C_VOLATILE while(sharedVar == 0) ; #else while(emscripten_atomic_load_u32((void*)&sharedVar) == 0) {} #endif #ifdef REPORT_RESULT result = sharedVar; REPORT_RESULT(); #endif }
int main() { { T x = HILO(5, 3); T y = __sync_add_and_fetch(&x, DUP(1)); assert(y == HILO(6, 4)); assert(x == HILO(6, 4)); volatile T n = HILO(2, 1); if (emscripten_has_threading_support()) { for(int i = 0; i < NUM_THREADS; ++i) pthread_create(&thread[i], NULL, thread_add_and_fetch, (void*)&n); for(int i = 0; i < NUM_THREADS; ++i) pthread_join(thread[i], NULL); printf("n: %llx\n", n); assert(n == HILO(NUM_THREADS*10000ULL+2ULL, NUM_THREADS*10000ULL+1ULL)); } } { T x = HILO(15, 13); T y = __sync_sub_and_fetch(&x, HILO(10, 10)); assert(y == HILO(5, 3)); assert(x == HILO(5, 3)); volatile T n = HILO(NUM_THREADS*10000ULL+5ULL, NUM_THREADS*10000ULL+3ULL); if (emscripten_has_threading_support()) { for(int i = 0; i < NUM_THREADS; ++i) pthread_create(&thread[i], NULL, thread_sub_and_fetch, (void*)&n); for(int i = 0; i < NUM_THREADS; ++i) pthread_join(thread[i], NULL); printf("n: %llx\n", n); assert(n == HILO(5,3)); } } { T x = HILO(32768 + 5, 5); T y = __sync_or_and_fetch(&x, HILO(65536 + 9, 9)); assert(y == HILO(32768 + 65536 + 13, 13)); assert(x == HILO(32768 + 65536 + 13, 13)); for(int x = 0; x < 100; ++x) // Test a few times for robustness, since this test is so short-lived. { or_and_fetch_data = HILO(65536 + (1<<NUM_THREADS), 1<<NUM_THREADS); if (emscripten_has_threading_support()) { for(int i = 0; i < NUM_THREADS; ++i) { threadArg[i] = DUP(1 << i); pthread_create(&thread[i], NULL, thread_or_and_fetch, (void*)&threadArg[i]); } for(int i = 0; i < NUM_THREADS; ++i) pthread_join(thread[i], NULL); assert(or_and_fetch_data == HILO(65536 + (1<<(NUM_THREADS+1))-1, (1<<(NUM_THREADS+1))-1)); } } } { T x = HILO(32768 + 5, 5); T y = __sync_and_and_fetch(&x, HILO(32768 + 9, 9)); assert(y == HILO(32768 + 1, 1)); assert(x == HILO(32768 + 1, 1)); if (emscripten_has_threading_support()) { for(int x = 0; x < 100; ++x) // Test a few times for robustness, since this test is so short-lived. { and_and_fetch_data = HILO(65536 + (1<<(NUM_THREADS+1))-1, (1<<(NUM_THREADS+1))-1); for(int i = 0; i < NUM_THREADS; ++i) { threadArg[i] = DUP(~(1UL<<i)); pthread_create(&thread[i], NULL, thread_and_and_fetch, (void*)&threadArg[i]); } for(int i = 0; i < NUM_THREADS; ++i) pthread_join(thread[i], NULL); assert(and_and_fetch_data == HILO(65536 + (1<<NUM_THREADS), 1<<NUM_THREADS)); } } } { T x = HILO(32768 + 5, 5); T y = __sync_xor_and_fetch(&x, HILO(16384 + 9, 9)); assert(y == HILO(32768 + 16384 + 12, 12)); assert(x == HILO(32768 + 16384 + 12, 12)); if (emscripten_has_threading_support()) { for(int x = 0; x < 100; ++x) // Test a few times for robustness, since this test is so short-lived. { xor_and_fetch_data = HILO(32768 + (1<<NUM_THREADS), 1<<NUM_THREADS); for(int i = 0; i < NUM_THREADS; ++i) { threadArg[i] = DUP(~(1UL<<i)); pthread_create(&thread[i], NULL, thread_xor_and_fetch, (void*)&threadArg[i]); } for(int i = 0; i < NUM_THREADS; ++i) pthread_join(thread[i], NULL); assert(xor_and_fetch_data == HILO(32768 + ((1<<(NUM_THREADS+1))-1), (1<<(NUM_THREADS+1))-1)); } } } // XXX NAND support does not exist in Atomics API. #if 0 { T x = 5; T y = __sync_nand_and_fetch(&x, 9); assert(y == 5); assert(x == -2); const int oddNThreads = NUM_THREADS-1; for(int x = 0; x < 100; ++x) // Test a few times for robustness, since this test is so short-lived. { nand_and_fetch_data = 0; for(int i = 0; i < oddNThreads; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch, (void*)-1); for(int i = 0; i < oddNThreads; ++i) pthread_join(thread[i], NULL); assert(nand_and_fetch_data == -1); } } #endif #ifdef REPORT_RESULT REPORT_RESULT(0); #endif }