1 // Copyright 2019 The Emscripten Authors. All rights reserved. 2 // Emscripten is available under two separate licenses, the MIT license and the 3 // University of Illinois/NCSA Open Source License. Both these licenses can be 4 // found in the LICENSE file. 5 6 #include <pthread.h> 7 #include <sys/types.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <assert.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <emscripten.h> 14 #include <emscripten/threading.h> 15 #include <vector> 16 17 pthread_t threads[5]; 18 thread_start(void * arg)19static void *thread_start(void *arg) 20 { 21 // This should be long enough for threads to pile up. 22 int idx = (int)arg; 23 printf("Starting thread %d\n", idx); 24 while (true) { 25 sleep(1); 26 } 27 printf("Finishing thread %d\n", idx); 28 pthread_exit((void*)0); 29 } 30 CreateThread(int idx)31void CreateThread(int idx) { 32 EM_ASM(out('Main: Spawning thread '+$0+'...'), idx); 33 int rc = pthread_create(&threads[idx], NULL, thread_start, (void*)idx); 34 assert(rc == 0); 35 } 36 main()37int main() 38 { 39 if (!emscripten_has_threading_support()) 40 { 41 #ifdef REPORT_RESULT 42 REPORT_RESULT(0); 43 #endif 44 printf("Skipped: Threading is not supported.\n"); 45 return 0; 46 } 47 48 // This test should be run with a prewarmed pool of size 4. None 49 // of the threads are allocated yet. 50 assert(EM_ASM_INT(return PThread.unusedWorkers.length) == 4); 51 assert(EM_ASM_INT(return PThread.runningWorkers.length) == 0); 52 53 CreateThread(0); 54 55 // We have one running thread, allocated on demand. 56 assert(EM_ASM_INT(return PThread.unusedWorkers.length) == 3); 57 assert(EM_ASM_INT(return PThread.runningWorkers.length) == 1); 58 59 for (int i = 1; i < 5; ++i) { 60 CreateThread(i); 61 } 62 63 // All the preallocated workers should be used. 64 // We can't join the threads or we'll hang forever. The main thread 65 // won't give up the thread to let the 5th thread be created. This is 66 // solved in non-test cases by using PROXY_TO_PTHREAD, but we can't 67 // do that here since we need to eval the length of the various pthread 68 // arrays. 69 assert(EM_ASM_INT(return PThread.runningWorkers.length) == 5); 70 assert(EM_ASM_INT(return PThread.unusedWorkers.length) == 0); 71 72 #ifdef REPORT_RESULT 73 REPORT_RESULT(0); 74 #endif 75 } 76