1 // Copyright 2015 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 <signal.h>
14 #include <emscripten.h>
15 #include <emscripten/threading.h>
16
17 volatile int sharedVar = 0;
18
thread_start(void * arg)19 static void *thread_start(void *arg)
20 {
21 // As long as this thread is running, keep the shared variable latched to nonzero value.
22 for(;;)
23 {
24 ++sharedVar;
25 emscripten_atomic_store_u32((void*)&sharedVar, sharedVar+1);
26 }
27
28 pthread_exit(0);
29 }
30
31 pthread_t thr;
32
BusySleep(double msecs)33 void BusySleep(double msecs)
34 {
35 double t0 = emscripten_get_now();
36 while(emscripten_get_now() < t0 + msecs);
37 }
38
main()39 int main()
40 {
41 if (!emscripten_has_threading_support())
42 {
43 #ifdef REPORT_RESULT
44 REPORT_RESULT(0);
45 #endif
46 printf("Skipped: Threading is not supported.\n");
47 return 0;
48 }
49
50 sharedVar = 0;
51 int s = pthread_create(&thr, NULL, thread_start, 0);
52 assert(s == 0);
53
54 // Wait until thread kicks in and sets the shared variable.
55 while(sharedVar == 0)
56 BusySleep(10);
57
58 s = pthread_kill(thr, SIGKILL);
59 assert(s == 0);
60
61 // Wait until we see the shared variable stop incrementing. (This is a bit heuristic and hacky)
62 for(;;)
63 {
64 int val = emscripten_atomic_load_u32((void*)&sharedVar);
65 BusySleep(100);
66 int val2 = emscripten_atomic_load_u32((void*)&sharedVar);
67 if (val == val2) break;
68 }
69
70 // Reset to 0.
71 sharedVar = 0;
72 emscripten_atomic_store_u32((void*)&sharedVar, 0);
73
74 // Wait for a long time, if the thread is still running, it should progress and set sharedVar by this time.
75 BusySleep(3000);
76
77 // Finally test that the thread is not doing any work and it is dead.
78 assert(sharedVar == 0);
79 assert(emscripten_atomic_load_u32((void*)&sharedVar) == 0);
80 EM_ASM(out('Main: Done. Successfully killed thread. sharedVar: '+$0+'.'), sharedVar);
81 #ifdef REPORT_RESULT
82 REPORT_RESULT(sharedVar);
83 #endif
84 }
85