Skip to content

Commit e7f8bc6

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 ac22f90 commit e7f8bc6

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
@@ -86,10 +86,10 @@ var LibraryPThread = {
8686
});
8787
#endif
8888

89-
// Pass the thread address inside the asm.js scope to store it for fast
90-
// access that avoids the need for a FFI out. Global constructors trying
89+
// Pass the thread address to the native code where they stored in wasm
90+
// globals which act as a form of TLS. Global constructors trying
9191
// to access this value will read the wrong value, but that is UB anyway.
92-
registerPthreadPtr(PThread.mainThreadBlock, /*isMainBrowserThread=*/!ENVIRONMENT_IS_WORKER, /*isMainRuntimeThread=*/1);
92+
__emscripten_thread_init(PThread.mainThreadBlock, /*isMainBrowserThread=*/!ENVIRONMENT_IS_WORKER, /*isMainRuntimeThread=*/1);
9393
_emscripten_register_main_browser_thread_id(PThread.mainThreadBlock);
9494
},
9595
initWorker: function() {
@@ -223,7 +223,7 @@ var LibraryPThread = {
223223
PThread.runExitHandlers();
224224

225225
_emscripten_futex_wake(tb + {{{ C_STRUCTS.pthread.threadStatus }}}, {{{ cDefine('INT_MAX') }}});
226-
registerPthreadPtr(0, 0, 0); // Unregister the thread block also inside the asm.js scope.
226+
__emscripten_thread_init(0, 0, 0); // Unregister the thread block also inside the asm.js scope.
227227
threadInfoStruct = 0;
228228
if (ENVIRONMENT_IS_PTHREAD) {
229229
// Note: in theory we would like to return any offscreen canvases back to the main thread,
@@ -239,7 +239,7 @@ var LibraryPThread = {
239239
Atomics.store(HEAPU32, (threadInfoStruct + {{{ C_STRUCTS.pthread.threadStatus }}} ) >> 2, 1); // Mark the thread as no longer running.
240240
_emscripten_futex_wake(threadInfoStruct + {{{ C_STRUCTS.pthread.threadStatus }}}, {{{ cDefine('INT_MAX') }}}); // wake all threads
241241
threadInfoStruct = selfThreadId = 0; // Not hosting a pthread anymore in this worker, reset the info structures to null.
242-
registerPthreadPtr(0, 0, 0); // Unregister the thread block also inside the asm.js scope.
242+
__emscripten_thread_init(0, 0, 0); // Unregister the thread block also inside the asm.js scope.
243243
postMessage({ 'cmd': 'cancelDone' });
244244
},
245245

@@ -1010,46 +1010,9 @@ var LibraryPThread = {
10101010
throw 'unwind';
10111011
},
10121012

1013-
_pthread_ptr: 0,
10141013
_pthread_is_main_runtime_thread: 0,
10151014
_pthread_is_main_browser_thread: 0,
10161015

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

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)