diff --git a/test/pthread/test_pthread_barrier.c b/test/pthread/test_pthread_barrier.c index 76201e7da1d07..5e220fd4dc928 100644 --- a/test/pthread/test_pthread_barrier.c +++ b/test/pthread/test_pthread_barrier.c @@ -20,63 +20,63 @@ int intermediate[N] = {}; pthread_barrier_t barr; // Sums a single row of a matrix. -int sum_row(long r) -{ - int sum = 0; - for(int i = 0; i < N; ++i) - sum += matrix[r][i]; - return sum; +int sum_row(long r) { + int sum = 0; + for (int i = 0; i < N; ++i) { + sum += matrix[r][i]; + } + return sum; } -void *thread_main(void *arg) -{ - // Each thread sums individual rows. - long id = (long)arg; - for(long i = id; i < N; i += THREADS) - intermediate[i] = sum_row(i); - - // Synchronization point - int rc = pthread_barrier_wait(&barr); - if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) - { - printf("Could not wait on barrier\n"); - exit(-1); - } +void* thread_main(void* arg) { + // Each thread sums individual rows. + long id = (long)arg; + for (long i = id; i < N; i += THREADS) { + intermediate[i] = sum_row(i); + } + + // Synchronization point + int rc = pthread_barrier_wait(&barr); + if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { + printf("Could not wait on barrier\n"); + exit(-1); + } - // Then each thread sums the one intermediate vector. - intptr_t totalSum = 0; - for(int i = 0; i < N; ++i) - totalSum += intermediate[i]; + // Then each thread sums the one intermediate vector. + intptr_t totalSum = 0; + for (int i = 0; i < N; ++i) { + totalSum += intermediate[i]; + } - pthread_exit((void*)totalSum); + pthread_exit((void*)totalSum); } -int main(int argc, char **argv) -{ - pthread_t thr[THREADS]; - - // Create the matrix and compute the expected result. - int expectedTotalSum = 0; - for(int i = 0; i < N; ++i) - for(int j = 0; j < N; ++j) - { - matrix[i][j] = rand(); - expectedTotalSum += matrix[i][j]; - } - printf("The sum of the matrix is %d.\n", expectedTotalSum); - - // Barrier initialization - int ret = pthread_barrier_init(&barr, NULL, THREADS); - assert(ret == 0); - - for(intptr_t i = 0; i < THREADS; ++i) { - pthread_create(&thr[i], NULL, &thread_main, (void*)i); - } - for(int i = 0; i < THREADS; ++i) { - int totalSum = 0; - pthread_join(thr[i], (void**)&totalSum); - assert(totalSum == expectedTotalSum); +int main(int argc, char** argv) { + pthread_t thr[THREADS]; + + // Create the matrix and compute the expected result. + int expectedTotalSum = 0; + for (int i = 0; i < N; ++i) { + for (int j = 0; j < N; ++j) { + matrix[i][j] = rand(); + expectedTotalSum += matrix[i][j]; } + } + printf("The sum of the matrix is %d.\n", expectedTotalSum); + + // Barrier initialization + int ret = pthread_barrier_init(&barr, NULL, THREADS); + assert(ret == 0); + + for (intptr_t i = 0; i < THREADS; ++i) { + pthread_create(&thr[i], NULL, &thread_main, (void*)i); + } + + for (int i = 0; i < THREADS; ++i) { + int totalSum = 0; + pthread_join(thr[i], (void**)&totalSum); + assert(totalSum == expectedTotalSum); + } - return 0; + return 0; } diff --git a/test/pthread/test_pthread_condition_variable.c b/test/pthread/test_pthread_condition_variable.c index 02c72c41e14e1..62283534ac28c 100644 --- a/test/pthread/test_pthread_condition_variable.c +++ b/test/pthread/test_pthread_condition_variable.c @@ -18,8 +18,7 @@ int thread_ids[3] = {0,1,2}; pthread_mutex_t count_mutex; pthread_cond_t count_threshold_cv; -void *inc_count(void *t) -{ +void* inc_count(void* t) { int i; long my_id = (long)t; @@ -44,8 +43,7 @@ void *inc_count(void *t) pthread_exit(NULL); } -void *watch_count(void *t) -{ +void *watch_count(void *t) { long my_id = (long)t; emscripten_outf("Starting watch_count(): thread %ld\n", my_id); @@ -68,8 +66,7 @@ void *watch_count(void *t) pthread_exit(NULL); } -int main (int argc, char *argv[]) -{ +int main (int argc, char *argv[]) { int i, rc; long t1=1, t2=2, t3=3; pthread_t threads[3]; diff --git a/test/pthread/test_pthread_gcc_atomics.c b/test/pthread/test_pthread_gcc_atomics.c index 0ab87efeb0687..dd3ce445e0cd7 100644 --- a/test/pthread/test_pthread_gcc_atomics.c +++ b/test/pthread/test_pthread_gcc_atomics.c @@ -13,6 +13,7 @@ // See https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html #define NUM_THREADS 8 +#define NUM_THREADS_ODD (NUM_THREADS-1) #define T int @@ -71,13 +72,12 @@ int main() { 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); + for (int i = 0; i < NUM_THREADS_ODD; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch, (void*)-1); + for (int i = 0; i < NUM_THREADS_ODD; ++i) pthread_join(thread[i], NULL); assert(nand_and_fetch_data == -1); } } @@ -87,12 +87,11 @@ int main() { 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); + for (int i = 0; i < NUM_THREADS_ODD; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch_bool, (void*)-1); + for (int i = 0; i < NUM_THREADS_ODD; ++i) pthread_join(thread[i], NULL); assert(nand_and_fetch_data == -1); } } diff --git a/test/pthread/test_pthread_locale.c b/test/pthread/test_pthread_locale.c index f0f4648d0512d..54707e8d970b5 100644 --- a/test/pthread/test_pthread_locale.c +++ b/test/pthread/test_pthread_locale.c @@ -32,15 +32,16 @@ int main (int argc, char *argv[]) { locale_t main_loc = do_test(); locale_t child_loc; - if (emscripten_has_threading_support()) { - long id = 1; - pthread_t thread; + pthread_t thread; + int rtn; - pthread_create(&thread, NULL, thread_test, (void *)id); + rtn = pthread_create(&thread, NULL, thread_test, (void *)NULL); + printf("create: %d\n", rtn); + assert(!rtn); + rtn = pthread_join(thread, (void**)&child_loc); + assert(!rtn); - pthread_join(thread, (void**)&child_loc); - assert(main_loc == child_loc); - } + assert(main_loc == child_loc); return 0; } diff --git a/test/pthread/test_pthread_once.c b/test/pthread/test_pthread_once.c index 2a8b9b41b383b..ac22498bb20e9 100644 --- a/test/pthread/test_pthread_once.c +++ b/test/pthread/test_pthread_once.c @@ -9,7 +9,7 @@ #include #include -_Atomic int numInitialized = 0; +int numInitialized = 0; void once_init() { numInitialized++; @@ -17,8 +17,7 @@ void once_init() { #define NUM_THREADS 8 -void *thread_main(void *arg) -{ +void *thread_main(void *arg) { static pthread_once_t control = PTHREAD_ONCE_INIT; pthread_once(&control, &once_init); assert(numInitialized == 1); @@ -33,10 +32,10 @@ int main() { 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); + for (int i = 0; i < NUM_THREADS; ++i) { + pthread_join(thread[i], NULL); } + assert(numInitialized == 1); return 0; } diff --git a/test/pthread/test_pthread_proxy_hammer.cpp b/test/pthread/test_pthread_proxy_hammer.cpp index 5e97147c6a369..d4fde03a0af5b 100644 --- a/test/pthread/test_pthread_proxy_hammer.cpp +++ b/test/pthread/test_pthread_proxy_hammer.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,48 +6,39 @@ #include #include -class random_device -{ - int __f_; -public: - // constructors - explicit random_device(); - ~random_device(); - - // generating functions - unsigned operator()(); -}; +class random_device { + int __f_; -random_device::random_device() -{ +public: + // constructors + explicit random_device() { __f_ = open("/dev/urandom", O_RDONLY); - if (__f_ < 0) abort(); -} + assert(__f_ >= 0); + } -random_device::~random_device() -{ + ~random_device() { close(__f_); -} + } -unsigned -random_device::operator()() -{ - unsigned r; - size_t n = sizeof(r); - char* p = reinterpret_cast(&r); - while (n > 0) - { - ssize_t s = read(__f_, p, 1); - if (s == 0) abort(); - if (s == -1) - { - if (errno != EINTR) abort(); - continue; - } - n -= static_cast(s); - p += static_cast(s); + // generating functions + unsigned operator()(); +}; + +unsigned random_device::operator()() { + unsigned r; + size_t n = sizeof(r); + char* p = reinterpret_cast(&r); + while (n > 0) { + ssize_t s = read(__f_, p, 1); + assert(s > 0); + if (s == -1) { + assert(errno == EINTR); + continue; } - return r; + n -= static_cast(s); + p += static_cast(s); + } + return r; } int main() { diff --git a/test/pthread/test_pthread_proxying_in_futex_wait.c b/test/pthread/test_pthread_proxying_in_futex_wait.c index 9190a65feba6f..89e16831f0f3e 100644 --- a/test/pthread/test_pthread_proxying_in_futex_wait.c +++ b/test/pthread/test_pthread_proxying_in_futex_wait.c @@ -11,42 +11,40 @@ #include _Atomic uint32_t main_thread_wait_val = 1; -_Atomic int result = 1; +_Atomic bool thread_done = false; -void *ThreadMain(void *arg) -{ - for(int i = 0; i < 10; ++i) - { - char str[256]; - sprintf(str, "file%d.txt", i); - printf("Writing file %s..\n", str); // Prints out to page console, this is a proxied operation. - FILE *handle = fopen(str, "w"); // fopen, fputs and fclose are currently proxied operations too (although hopefully not in the future) - fputs(str, handle); - fclose(handle); - } - main_thread_wait_val = 0; - emscripten_futex_wake(&main_thread_wait_val, 1); - result = 0; - pthread_exit(0); +void* ThreadMain(void* arg) { + for (int i = 0; i < 10; ++i) { + char str[256]; + sprintf(str, "file%d.txt", i); + // Prints out to page console, this is a proxied operation. + printf("Writing file %s..\n", str); + // fopen, fputs and fclose are currently proxied operations too (although hopefully not in the future) + FILE* handle = fopen(str, "w"); + fputs(str, handle); + fclose(handle); + } + main_thread_wait_val = 0; + emscripten_futex_wake(&main_thread_wait_val, 1); + thread_done = true; + return NULL; } -int main() -{ - pthread_t thread; - int rc = pthread_create(&thread, NULL, ThreadMain, 0); - assert(rc == 0); - while (main_thread_wait_val != 0) { - rc = emscripten_futex_wait(&main_thread_wait_val, 1, 15 * 1000); - // An rc of 0 means no error, and of EWOULDBLOCK means that the value is - // not the expected one, which can happen if the pthread manages to set it - // before we reach the futex_wait. - if (rc != 0 && rc != -EWOULDBLOCK) - { - printf("ERROR! futex wait errored %d!\n", rc); - return 2; - } - } - pthread_join(thread, 0); - - return result; +int main() { + pthread_t thread; + int rc = pthread_create(&thread, NULL, ThreadMain, 0); + assert(rc == 0); + while (main_thread_wait_val != 0) { + rc = emscripten_futex_wait(&main_thread_wait_val, 1, 15 * 1000); + // An rc of 0 means no error, and of EWOULDBLOCK means that the value is + // not the expected one, which can happen if the pthread manages to set it + // before we reach the futex_wait. + if (rc != 0 && rc != -EWOULDBLOCK) { + printf("ERROR! futex wait errored %d!\n", rc); + return 2; + } + } + pthread_join(thread, 0); + assert(thread_done); + return 0; } diff --git a/test/pthread/test_pthread_run_on_main_thread.c b/test/pthread/test_pthread_run_on_main_thread.c index 585580deb8daf..f0439e4ccffaf 100644 --- a/test/pthread/test_pthread_run_on_main_thread.c +++ b/test/pthread/test_pthread_run_on_main_thread.c @@ -142,16 +142,14 @@ void *thread_main(void* arg) { } int main() { - if (emscripten_has_threading_support()) { - test_sync(); - test_async_waitable(); - - pthread_t thread; - int rc = pthread_create(&thread, NULL, thread_main, NULL); - assert(rc == 0); - rc = pthread_join(thread, 0); - assert(rc == 0); - } + test_sync(); + test_async_waitable(); + + pthread_t thread; + int rc = pthread_create(&thread, NULL, thread_main, NULL); + assert(rc == 0); + rc = pthread_join(thread, 0); + assert(rc == 0); test_async(); return 0; diff --git a/test/pthread/test_pthread_run_on_main_thread_flood.c b/test/pthread/test_pthread_run_on_main_thread_flood.c index e06baae61c831..84119a0197bf2 100644 --- a/test/pthread/test_pthread_run_on_main_thread_flood.c +++ b/test/pthread/test_pthread_run_on_main_thread_flood.c @@ -69,19 +69,17 @@ void *thread_main(void* arg) { } int main() { - if (emscripten_has_threading_support()) { - test_sync(); - test_async_waitable(); - - pthread_t thread; - int rc = pthread_create(&thread, NULL, thread_main, NULL); - assert(rc == 0); - void* retval; - rc = pthread_join(thread, &retval); - assert(rc == 0); - printf("pthread_join done: %ld\n", (intptr_t)retval); - assert(retval == NULL); - } + test_sync(); + test_async_waitable(); + + pthread_t thread; + int rc = pthread_create(&thread, NULL, thread_main, NULL); + assert(rc == 0); + void* retval; + rc = pthread_join(thread, &retval); + assert(rc == 0); + printf("pthread_join done: %ld\n", (intptr_t)retval); + assert(retval == NULL); test_async(); diff --git a/test/pthread/test_pthread_spawns.c b/test/pthread/test_pthread_spawns.c index cf68fdf579ef9..d28e4f1f637b8 100644 --- a/test/pthread/test_pthread_spawns.c +++ b/test/pthread/test_pthread_spawns.c @@ -8,20 +8,20 @@ #define NUM_THREADS 2 -void *thread_main(void *arg) -{ - pthread_exit(0); +void *thread_main(void *arg) { + pthread_exit(0); } pthread_t thread[NUM_THREADS]; -int main() -{ - for(int x = 0; x < 100; ++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); - } - return 0; +int main() { + for (int x = 0; x < 100; ++x) { + for (int i = 0; i < NUM_THREADS; ++i) { + pthread_create(&thread[i], NULL, thread_main, 0); + } + for (int i = 0; i < NUM_THREADS; ++i) { + pthread_join(thread[i], NULL); + } + } + return 0; } diff --git a/test/pthread/test_pthread_supported.c b/test/pthread/test_pthread_supported.c index 2afade934fb91..3e40498d09019 100644 --- a/test/pthread/test_pthread_supported.c +++ b/test/pthread/test_pthread_supported.c @@ -12,7 +12,7 @@ #include void *ThreadMain(void *arg) { - pthread_exit(NULL); + return NULL; } int main() { diff --git a/test/pthread/test_pthread_thread_local_storage.c b/test/pthread/test_pthread_thread_local_storage.c index a10accf9a984c..bcb4e209f1475 100644 --- a/test/pthread/test_pthread_thread_local_storage.c +++ b/test/pthread/test_pthread_thread_local_storage.c @@ -17,31 +17,29 @@ #define NUM_ITERS 100 pthread_key_t keys[NUM_KEYS]; -void *ThreadMain(void *arg) -{ - uintptr_t local_keys[NUM_KEYS]; - for(int iter = 0; iter < NUM_ITERS; ++iter) - { - for(int i = 0; i < NUM_KEYS; ++i) - { - local_keys[i] = (uintptr_t)pthread_getspecific(keys[i]); -// emscripten_errf("Thread %d: Read value %d from TLS for key at index %d", pthread_self(), (int)local_keys[i], i); - } - - for(int i = 0; i < NUM_KEYS; ++i) - ++local_keys[i]; - - for(int i = 0; i < NUM_KEYS; ++i) - pthread_setspecific(keys[i], (void*)local_keys[i]); - } - - for(int i = 0; i < NUM_KEYS; ++i) - { - local_keys[i] = (uintptr_t)pthread_getspecific(keys[i]); -// emscripten_errf("Thread %d final verify: Read value %d from TLS for key at index %d", pthread_self(), (int)local_keys[i], i); - assert(local_keys[i] == NUM_ITERS); - } - return 0; +void* ThreadMain(void* arg) { + uintptr_t local_keys[NUM_KEYS]; + for (int iter = 0; iter < NUM_ITERS; ++iter) { + for (int i = 0; i < NUM_KEYS; ++i) { + local_keys[i] = (uintptr_t)pthread_getspecific(keys[i]); + // emscripten_errf("Thread %d: Read value %d from TLS for + //key at index %d", pthread_self(), (int)local_keys[i], i); + } + + for (int i = 0; i < NUM_KEYS; ++i) + ++local_keys[i]; + + for (int i = 0; i < NUM_KEYS; ++i) + pthread_setspecific(keys[i], (void*)local_keys[i]); + } + + for (int i = 0; i < NUM_KEYS; ++i) { + local_keys[i] = (uintptr_t)pthread_getspecific(keys[i]); + // emscripten_errf("Thread %d final verify: Read value %d from TLS for key + //at index %d", pthread_self(), (int)local_keys[i], i); + assert(local_keys[i] == NUM_ITERS); + } + return 0; } pthread_t thread[NUM_THREADS]; @@ -50,72 +48,64 @@ int numThreadsToCreate = 32; int threadCounter = 0; _Atomic int destructorCounter = 0; -void CreateThread(long i) -{ - printf("CreateThread %ld\n", i); - threadCounter++; - int rc = pthread_create(&thread[i], NULL, ThreadMain, (void*)i); - if (emscripten_has_threading_support()) assert(rc == 0); - else assert(rc == EAGAIN); +void CreateThread(long i) { + printf("CreateThread %ld\n", i); + threadCounter++; + int rc = pthread_create(&thread[i], NULL, ThreadMain, (void*)i); + assert(rc == 0); } void destructor1(void* val) { - destructorCounter++; + destructorCounter++; } -int main() -{ - for(int i = 0; i < NUM_KEYS; ++i) { - if (i == 0) - pthread_key_create(&keys[i], destructor1); - else - pthread_key_create(&keys[i], NULL); - } - - // Create initial threads. - for(long i = 0; i < NUM_THREADS; ++i) - CreateThread(i); - - // Join all threads and create more. - if (emscripten_has_threading_support()) - { - for(long i = 0; i < NUM_THREADS; ++i) - { - if (thread[i]) - { - intptr_t status; - int rc = pthread_join(thread[i], (void**)&status); - assert(rc == 0); - printf("Main: Joined thread idx %ld with status %lu\n", i, status); - assert(status == 0); - thread[i] = 0; - if (numThreadsToCreate > 0) - { - --numThreadsToCreate; - CreateThread(i); - } - } - } - } - - for(int i = 0; i < NUM_THREADS; ++i) - { - if (thread[i]) - { - intptr_t status = 1; - int rc = pthread_join(thread[i], (void**)&status); - assert(rc == 0); - printf("Main: Joined thread idx %d with status %lu\n", i, status); - assert(status == 0); - } - } - printf("destructorCounter: %d\n", destructorCounter); - printf("threadCounter: %d\n", threadCounter); - assert(destructorCounter == threadCounter); - - for(int i = 0; i < NUM_KEYS; ++i) - pthread_key_delete(keys[i]); - - printf("done\n"); - return 0; +int main() { + for (int i = 0; i < NUM_KEYS; ++i) { + if (i == 0) { + pthread_key_create(&keys[i], destructor1); + } else { + pthread_key_create(&keys[i], NULL); + } + } + + // Create initial threads. + for (long i = 0; i < NUM_THREADS; ++i) { + CreateThread(i); + } + + // Join all threads and create more. + for (long i = 0; i < NUM_THREADS; ++i) { + if (thread[i]) { + intptr_t status; + int rc = pthread_join(thread[i], (void**)&status); + assert(rc == 0); + printf("Main: Joined thread idx %ld with status %lu\n", i, status); + assert(status == 0); + thread[i] = 0; + if (numThreadsToCreate > 0) { + --numThreadsToCreate; + CreateThread(i); + } + } + } + + for (int i = 0; i < NUM_THREADS; ++i) { + if (thread[i]) { + intptr_t status = 1; + int rc = pthread_join(thread[i], (void**)&status); + assert(rc == 0); + printf("Main: Joined thread idx %d with status %lu\n", i, status); + assert(status == 0); + } + } + printf("destructorCounter: %d\n", destructorCounter); + printf("threadCounter: %d\n", threadCounter); + assert(destructorCounter == threadCounter); + + for (int i = 0; i < NUM_KEYS; ++i) { + pthread_key_delete(keys[i]); + } + + printf("done\n"); + return 0; } diff --git a/test/test_browser.py b/test/test_browser.py index bf935ec74a483..677aff1950283 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -4566,12 +4566,8 @@ def test_fetch_persist(self): def test_fetch_redirect(self): self.btest_exit('fetch/test_fetch_redirect.c', cflags=['-sFETCH', '-pthread', '-sPROXY_TO_PTHREAD', f'-DSERVER="{self.SERVER_URL}"']) - @parameterized({ - '': ([],), - 'mt': (['-pthread', '-sPTHREAD_POOL_SIZE=2'],), - }) - def test_pthread_locale(self, args): - self.btest_exit('pthread/test_pthread_locale.c', cflags=args) + def test_pthread_locale(self): + self.btest_exit('pthread/test_pthread_locale.c', cflags=['-pthread', '-sPTHREAD_POOL_SIZE=1']) # Tests the Emscripten HTML5 API emscripten_set_canvas_element_size() and # emscripten_get_canvas_element_size() functionality in singlethreaded programs. @@ -5417,7 +5413,7 @@ def test_browser_run_with_slash_in_query_and_hash(self): @disabled("only run this manually, to test for race conditions") @parameterized({ - 'normal': ([],), + '': ([],), 'assertions': (['-sASSERTIONS'],), }) def test_manual_pthread_proxy_hammer(self, args):