Skip to content

Commit 9ef57be

Browse files
committed
Move pthread TLS state native code using wasm globals
This moves pthead_self and other thread state into native code.
1 parent 4212020 commit 9ef57be

File tree

6 files changed

+51
-47
lines changed

6 files changed

+51
-47
lines changed

emcc.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1577,9 +1577,10 @@ def filter_out_duplicate_dynamic_libs(inputs):
15771577
# manually export them
15781578

15791579
shared.Settings.EXPORTED_FUNCTIONS += [
1580+
'__emscripten_thread_init',
15801581
'_emscripten_get_global_libc',
15811582
'___pthread_tsd_run_dtors',
1582-
'registerPthreadPtr', '_pthread_self',
1583+
'_pthread_self',
15831584
'___emscripten_pthread_data_constructor',
15841585
'_emscripten_futex_wake',
15851586
'_emscripten_stack_set_limits',

src/library_pthread.js

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
var LibraryPThread = {
88
$PThread__postset: 'if (!ENVIRONMENT_IS_PTHREAD) PThread.initMainThreadBlock();',
9-
$PThread__deps: ['$registerPthreadPtr',
9+
$PThread__deps: ['_emscripten_thread_init',
1010
'$ERRNO_CODES', 'emscripten_futex_wake', '$killThread',
1111
'$cancelThread', '$cleanupThread',
1212
#if USE_ASAN || USE_LSAN
@@ -81,10 +81,10 @@ var LibraryPThread = {
8181
});
8282
#endif
8383

84-
// Pass the thread address inside the asm.js scope to store it for fast
85-
// access that avoids the need for a FFI out. Global constructors trying
84+
// Pass the thread address to the native code where they stored in wasm
85+
// globals which act as a form of TLS. Global constructors trying
8686
// to access this value will read the wrong value, but that is UB anyway.
87-
registerPthreadPtr(PThread.mainThreadBlock, /*isMainBrowserThread=*/!ENVIRONMENT_IS_WORKER, /*isMainRuntimeThread=*/1);
87+
__emscripten_thread_init(PThread.mainThreadBlock, /*isMainBrowserThread=*/!ENVIRONMENT_IS_WORKER, /*isMainRuntimeThread=*/1);
8888
_emscripten_register_main_browser_thread_id(PThread.mainThreadBlock);
8989
},
9090
initWorker: function() {
@@ -218,7 +218,7 @@ var LibraryPThread = {
218218
PThread.runExitHandlers();
219219

220220
_emscripten_futex_wake(tb + {{{ C_STRUCTS.pthread.threadStatus }}}, {{{ cDefine('INT_MAX') }}});
221-
registerPthreadPtr(0, 0, 0); // Unregister the thread block also inside the asm.js scope.
221+
__emscripten_thread_init(0, 0, 0); // Unregister the thread block also inside the asm.js scope.
222222
threadInfoStruct = 0;
223223
if (ENVIRONMENT_IS_PTHREAD) {
224224
// Note: in theory we would like to return any offscreen canvases back to the main thread,
@@ -234,7 +234,7 @@ var LibraryPThread = {
234234
Atomics.store(HEAPU32, (threadInfoStruct + {{{ C_STRUCTS.pthread.threadStatus }}} ) >> 2, 1); // Mark the thread as no longer running.
235235
_emscripten_futex_wake(threadInfoStruct + {{{ C_STRUCTS.pthread.threadStatus }}}, {{{ cDefine('INT_MAX') }}}); // wake all threads
236236
threadInfoStruct = selfThreadId = 0; // Not hosting a pthread anymore in this worker, reset the info structures to null.
237-
registerPthreadPtr(0, 0, 0); // Unregister the thread block also inside the asm.js scope.
237+
__emscripten_thread_init(0, 0, 0); // Unregister the thread block also inside the asm.js scope.
238238
postMessage({ 'cmd': 'cancelDone' });
239239
},
240240

@@ -1005,46 +1005,9 @@ var LibraryPThread = {
10051005
throw 'unwind';
10061006
},
10071007

1008-
_pthread_ptr: 0,
10091008
_pthread_is_main_runtime_thread: 0,
10101009
_pthread_is_main_browser_thread: 0,
10111010

1012-
$registerPthreadPtr__deps: ['_pthread_ptr', '_pthread_is_main_runtime_thread', '_pthread_is_main_browser_thread'],
1013-
$registerPthreadPtr__asm: true,
1014-
$registerPthreadPtr__sig: 'viii',
1015-
$registerPthreadPtr: function(pthreadPtr, isMainBrowserThread, isMainRuntimeThread) {
1016-
pthreadPtr = pthreadPtr|0;
1017-
isMainBrowserThread = isMainBrowserThread|0;
1018-
isMainRuntimeThread = isMainRuntimeThread|0;
1019-
__pthread_ptr = pthreadPtr;
1020-
__pthread_is_main_browser_thread = isMainBrowserThread;
1021-
__pthread_is_main_runtime_thread = isMainRuntimeThread;
1022-
},
1023-
1024-
// Public pthread_self() function which returns a unique ID for the thread.
1025-
pthread_self__deps: ['_pthread_ptr'],
1026-
pthread_self__asm: true,
1027-
pthread_self__sig: 'i',
1028-
pthread_self: function() {
1029-
return __pthread_ptr|0;
1030-
},
1031-
1032-
emscripten_is_main_runtime_thread__asm: true,
1033-
emscripten_is_main_runtime_thread__sig: 'i',
1034-
emscripten_is_main_runtime_thread__deps: ['_pthread_is_main_runtime_thread'],
1035-
emscripten_is_main_runtime_thread: function() {
1036-
// Semantically the same as testing "!ENVIRONMENT_IS_PTHREAD" outside the asm.js scope
1037-
return __pthread_is_main_runtime_thread|0;
1038-
},
1039-
1040-
emscripten_is_main_browser_thread__asm: true,
1041-
emscripten_is_main_browser_thread__sig: 'i',
1042-
emscripten_is_main_browser_thread__deps: ['_pthread_is_main_browser_thread'],
1043-
emscripten_is_main_browser_thread: function() {
1044-
// Semantically the same as testing "!ENVIRONMENT_IS_WORKER" outside the asm.js scope
1045-
return __pthread_is_main_browser_thread|0;
1046-
},
1047-
10481011
pthread_getschedparam: function(thread, policy, schedparam) {
10491012
if (!policy && !schedparam) return ERRNO_CODES.EINVAL;
10501013

src/postamble_minimal.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ function initRuntime(asm) {
6262
Module['_emscripten_tls_init'] = _emscripten_tls_init;
6363
Module['HEAPU32'] = HEAPU32;
6464
Module['dynCall'] = dynCall;
65-
Module['registerPthreadPtr'] = registerPthreadPtr;
65+
Module['__emscripten_thread_init'] = __emscripten_thread_init;
6666
Module['_pthread_self'] = _pthread_self;
6767

6868
if (ENVIRONMENT_IS_PTHREAD) {
@@ -72,7 +72,7 @@ function initRuntime(asm) {
7272

7373
// Pass the thread address inside the asm.js scope to store it for fast access
7474
// that avoids the need for a FFI out.
75-
registerPthreadPtr(PThread.mainThreadBlock, /*isMainBrowserThread=*/!ENVIRONMENT_IS_WORKER, /*isMainRuntimeThread=*/1);
75+
__emscripten_thread_init(PThread.mainThreadBlock, /*isMainBrowserThread=*/!ENVIRONMENT_IS_WORKER, /*isMainRuntimeThread=*/1);
7676
_emscripten_register_main_browser_thread_id(PThread.mainThreadBlock);
7777
#endif
7878

src/worker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ this.onmessage = function(e) {
155155
threadInfoStruct = e.data.threadInfoStruct;
156156

157157
// Pass the thread address inside the asm.js scope to store it for fast access that avoids the need for a FFI out.
158-
Module['registerPthreadPtr'](threadInfoStruct, /*isMainBrowserThread=*/0, /*isMainRuntimeThread=*/0);
158+
Module['__emscripten_thread_init'](threadInfoStruct, /*isMainBrowserThread=*/0, /*isMainRuntimeThread=*/0);
159159

160160
selfThreadId = e.data.selfThreadId;
161161
parentThreadId = e.data.parentThreadId;

system/lib/pthread/pthread_self.s

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
.globaltype thread_id, i32
2+
thread_id:
3+
4+
.globaltype is_main_thread, i32
5+
is_main_thread:
6+
7+
.globaltype is_runtime_thread, i32
8+
is_runtime_thread:
9+
10+
.globl pthread_self
11+
pthread_self:
12+
.functype pthread_self () -> (i32)
13+
global.get thread_id
14+
end_function
15+
16+
.globl _emscripten_thread_init
17+
_emscripten_thread_init:
18+
.functype _emscripten_thread_init (i32, i32, i32) -> ()
19+
local.get 0
20+
global.set thread_id
21+
local.get 1
22+
global.set is_main_thread
23+
local.get 2
24+
global.set is_runtime_thread
25+
end_function
26+
27+
# Semantically the same as testing "!ENVIRONMENT_IS_PTHREAD" in JS
28+
.globl emscripten_is_main_runtime_thread
29+
emscripten_is_main_runtime_thread:
30+
.functype emscripten_is_main_runtime_thread () -> (i32)
31+
global.get is_runtime_thread
32+
end_function
33+
34+
# Semantically the same as testing "!ENVIRONMENT_IS_WORKER" in JS
35+
.globl emscripten_is_main_browser_thread
36+
emscripten_is_main_browser_thread:
37+
.functype emscripten_is_main_browser_thread () -> (i32)
38+
global.get is_browser_thread
39+
end_function

tools/system_libs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,7 @@ def get_files(self):
12001200
'library_pthread.c',
12011201
'emscripten_atomic.c',
12021202
'emscripten_tls_init.c',
1203+
'pthread_self.s',
12031204
])
12041205
return files
12051206
else:

0 commit comments

Comments
 (0)