forked from emscripten-core/emscripten
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_pthread_thread_local_storage.cpp
95 lines (83 loc) · 2.29 KB
/
test_pthread_thread_local_storage.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <emscripten.h>
#include <emscripten/threading.h>
#include <errno.h>
#include <assert.h>
#include <inttypes.h>
#define NUM_THREADS 8
#define NUM_KEYS 16
#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]);
// EM_ASM_INT( { Module['printErr']('Thread ' + $0 + ': Read value ' + $1 + ' from TLS for key at index ' + $2); }, 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]);
// EM_ASM_INT( { Module['printErr']('Thread ' + $0 + ' final verify: Read value ' + $1 + ' from TLS for key at index ' + $2); }, pthread_self(), (int)local_keys[i], i);
if (local_keys[i] != NUM_ITERS)
pthread_exit((void*)1);
}
pthread_exit(0);
}
pthread_t thread[NUM_THREADS];
int numThreadsToCreate = 32;
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()
{
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_INT( { 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
int result = 0;
REPORT_RESULT();
#endif
for(int i = 0; i < NUM_KEYS; ++i)
pthread_key_delete(keys[i]);
}