@@ -9,7 +9,6 @@ var LibraryPThread = {
9
9
$PThread__deps : [ '$registerPthreadPtr' ,
10
10
'$ERRNO_CODES' , 'emscripten_futex_wake' , '$killThread' ,
11
11
'$cancelThread' , '$cleanupThread' ,
12
- '_main_thread_futex_wait_address'
13
12
#if USE_ASAN || USE_LSAN
14
13
, '$withBuiltinMalloc'
15
14
#endif
@@ -28,6 +27,9 @@ var LibraryPThread = {
28
27
runningWorkers : [ ] ,
29
28
// Points to a pthread_t structure in the Emscripten main heap, allocated on demand if/when first needed.
30
29
// mainThreadBlock: undefined,
30
+ // Stores the memory address that the main thread is waiting on, if any. If
31
+ // the main thread is waiting, we wake it up before waking up any workers.
32
+ // mainThreadFutex: undefined,
31
33
initMainThreadBlock : function ( ) {
32
34
#if ASSERTIONS
33
35
assert ( ! ENVIRONMENT_IS_PTHREAD ) ;
@@ -69,7 +71,7 @@ var LibraryPThread = {
69
71
Atomics . store ( HEAPU32 , ( PThread . mainThreadBlock + { { { C_STRUCTS . pthread . tid } } } ) >> 2 , PThread . mainThreadBlock ) ; // Main thread ID.
70
72
Atomics . store ( HEAPU32 , ( PThread . mainThreadBlock + { { { C_STRUCTS . pthread . pid } } } ) >> 2 , { { { PROCINFO . pid } } } ) ; // Process ID.
71
73
72
- __main_thread_futex_wait_address = _malloc ( 4 ) ;
74
+ PThread . mainThreadFutex = _malloc ( 4 ) ;
73
75
74
76
#if PTHREADS_PROFILING
75
77
PThread . createProfilerBlock ( PThread . mainThreadBlock ) ;
@@ -87,6 +89,8 @@ var LibraryPThread = {
87
89
_emscripten_register_main_browser_thread_id ( PThread . mainThreadBlock ) ;
88
90
} ,
89
91
initWorker: function ( ) {
92
+ PThread . mainThreadFutex = Module [ 'mainThreadFutex' ] ;
93
+
90
94
#if USE_CLOSURE_COMPILER
91
95
// worker.js is not compiled together with us, and must access certain
92
96
// things.
@@ -394,6 +398,7 @@ var LibraryPThread = {
394
398
// object in Module['mainScriptUrlOrBlob'], or a URL to it, so that pthread Workers can
395
399
// independently load up the same main application file.
396
400
'urlOrBlob' : Module [ 'mainScriptUrlOrBlob' ] || _scriptDir ,
401
+ 'mainThreadFutex' : PThread . mainThreadFutex ,
397
402
#if WASM2JS
398
403
// the polyfill WebAssembly.Memory instance has function properties,
399
404
// which will fail in postMessage, so just send a custom object with the
@@ -1106,11 +1111,8 @@ var LibraryPThread = {
1106
1111
return 0 ;
1107
1112
} ,
1108
1113
1109
- // Stores the memory address that the main thread is waiting on, if any.
1110
- _main_thread_futex_wait_address : '0' ,
1111
-
1112
1114
// Returns 0 on success, or one of the values -ETIMEDOUT, -EWOULDBLOCK or -EINVAL on error.
1113
- emscripten_futex_wait__deps : [ '_main_thread_futex_wait_address' , ' emscripten_main_thread_process_queued_calls'] ,
1115
+ emscripten_futex_wait__deps : [ 'emscripten_main_thread_process_queued_calls' ] ,
1114
1116
emscripten_futex_wait : function ( addr , val , timeout ) {
1115
1117
if ( addr <= 0 || addr > HEAP8 . length || addr & 3 != 0 ) return - { { { cDefine ( 'EINVAL' ) } } } ;
1116
1118
if ( ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_WORKER ) {
@@ -1136,10 +1138,13 @@ var LibraryPThread = {
1136
1138
#if PTHREADS_PROFILING
1137
1139
PThread . setThreadStatusConditional ( _pthread_self ( ) , { { { cDefine ( 'EM_THREAD_STATUS_RUNNING' ) } } } , { { { cDefine ( 'EM_THREAD_STATUS_WAITFUTEX' ) } } } ) ;
1138
1140
#endif
1139
-
1140
1141
// Register globally which address the main thread is simulating to be waiting on. When zero, main thread is not waiting on anything,
1141
- // and on nonzero, the contents of address pointed by __main_thread_futex_wait_address tell which address the main thread is simulating its wait on.
1142
- Atomics . store ( HEAP32 , __main_thread_futex_wait_address >> 2 , addr ) ;
1142
+ // and on nonzero, the contents of address pointed by PThread.mainThreadFutex tell which address the main thread is simulating its wait on.
1143
+ var old = Atomics . exchange ( HEAP32 , PThread . mainThreadFutex >> 2 , addr ) ;
1144
+ #if ASSERTIONS
1145
+ assert ( PThread . mainThreadFutex > 0 ) ;
1146
+ assert ( old == 0 ) ; // we must not have been waiting before.
1147
+ #endif
1143
1148
var ourWaitAddress = addr ; // We may recursively re-enter this function while processing queued calls, in which case we'll do a spurious wakeup of the older wait operation.
1144
1149
while ( addr == ourWaitAddress ) {
1145
1150
tNow = performance . now ( ) ;
@@ -1150,7 +1155,7 @@ var LibraryPThread = {
1150
1155
return - { { { cDefine ( 'ETIMEDOUT' ) } } } ;
1151
1156
}
1152
1157
_emscripten_main_thread_process_queued_calls ( ) ; // We are performing a blocking loop here, so must pump any pthreads if they want to perform operations that are proxied.
1153
- addr = Atomics . load ( HEAP32 , __main_thread_futex_wait_address >> 2 ) ; // Look for a worker thread waking us up.
1158
+ addr = Atomics . load ( HEAP32 , PThread . mainThreadFutex >> 2 ) ; // Look for a worker thread waking us up.
1154
1159
}
1155
1160
#if PTHREADS_PROFILING
1156
1161
PThread . setThreadStatusConditional ( _pthread_self ( ) , { { { cDefine ( 'EM_THREAD_STATUS_RUNNING' ) } } } , { { { cDefine ( 'EM_THREAD_STATUS_WAITFUTEX' ) } } } ) ;
@@ -1161,7 +1166,6 @@ var LibraryPThread = {
1161
1166
1162
1167
// Returns the number of threads (>= 0) woken up, or the value -EINVAL on error.
1163
1168
// Pass count == INT_MAX to wake up all threads.
1164
- emscripten_futex_wake__deps : [ '_main_thread_futex_wait_address' ] ,
1165
1169
emscripten_futex_wake : function ( addr , count ) {
1166
1170
if ( addr <= 0 || addr > HEAP8 . length || addr & 3 != 0 || count < 0 ) return - { { { cDefine ( 'EINVAL' ) } } } ;
1167
1171
if ( count == 0 ) return 0 ;
@@ -1172,10 +1176,13 @@ var LibraryPThread = {
1172
1176
// See if main thread is waiting on this address? If so, wake it up by resetting its wake location to zero.
1173
1177
// Note that this is not a fair procedure, since we always wake main thread first before any workers, so
1174
1178
// this scheme does not adhere to real queue-based waiting.
1175
- var mainThreadWaitAddress = Atomics . load ( HEAP32 , __main_thread_futex_wait_address >> 2 ) ;
1179
+ #if ASSERTIONS
1180
+ assert ( PThread . mainThreadFutex > 0 ) ;
1181
+ #endif
1182
+ var mainThreadWaitAddress = Atomics . load ( HEAP32 , PThread . mainThreadFutex >> 2 ) ;
1176
1183
var mainThreadWoken = 0 ;
1177
1184
if ( mainThreadWaitAddress == addr ) {
1178
- var loadedAddr = Atomics . compareExchange ( HEAP32 , __main_thread_futex_wait_address >> 2 , mainThreadWaitAddress , 0 ) ;
1185
+ var loadedAddr = Atomics . compareExchange ( HEAP32 , PThread . mainThreadFutex >> 2 , mainThreadWaitAddress , 0 ) ;
1179
1186
if ( loadedAddr == mainThreadWaitAddress ) {
1180
1187
-- count ;
1181
1188
mainThreadWoken = 1 ;
0 commit comments