@@ -106,61 +106,6 @@ search_module(WASMModuleCommon *module)
106106 return NULL ;
107107}
108108
109- static void
110- wait_map_address_count_callback (void * key , void * value ,
111- void * p_total_elem_count )
112- {
113- * (uint32 * )p_total_elem_count = * (uint32 * )p_total_elem_count + 1 ;
114- }
115-
116- static void
117- create_list_of_waiter_addresses (void * key , void * value , void * user_data )
118- {
119- AtomicWaitAddressArgs * data = (AtomicWaitAddressArgs * )user_data ;
120- data -> addr [data -> index ++ ] = key ;
121- }
122-
123- void
124- notify_stale_threads_on_exception (WASMModuleInstanceCommon * module_inst )
125- {
126- AtomicWaitAddressArgs args = { 0 };
127- uint32 i = 0 , total_elem_count = 0 ;
128- uint64 total_elem_count_size = 0 ;
129-
130- os_mutex_lock (& wait_map_lock ); /* Make the two traversals atomic */
131-
132- /* count number of addresses in wait_map */
133- bh_hash_map_traverse (wait_map , wait_map_address_count_callback ,
134- (void * )& total_elem_count );
135-
136- if (!total_elem_count ) {
137- os_mutex_unlock (& wait_map_lock );
138- return ;
139- }
140-
141- /* allocate memory */
142- total_elem_count_size = (uint64 )sizeof (void * ) * total_elem_count ;
143- if (total_elem_count_size >= UINT32_MAX
144- || !(args .addr = wasm_runtime_malloc ((uint32 )total_elem_count_size ))) {
145- LOG_ERROR (
146- "failed to allocate memory for list of atomic wait addresses" );
147- os_mutex_unlock (& wait_map_lock );
148- return ;
149- }
150-
151- /* set values in list of addresses */
152- bh_hash_map_traverse (wait_map , create_list_of_waiter_addresses , & args );
153- os_mutex_unlock (& wait_map_lock );
154-
155- /* notify */
156- for (i = 0 ; i < args .index ; i ++ ) {
157- wasm_runtime_atomic_notify (module_inst , args .addr [i ], UINT32_MAX );
158- }
159-
160- /* free memory allocated to args data */
161- wasm_runtime_free (args .addr );
162- }
163-
164109WASMSharedMemNode *
165110wasm_module_get_shared_memory (WASMModuleCommon * module )
166111{
@@ -413,7 +358,9 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
413358 AtomicWaitInfo * wait_info ;
414359 AtomicWaitNode * wait_node ;
415360 WASMSharedMemNode * node ;
361+ #if WASM_ENABLE_THREAD_MGR != 0
416362 WASMExecEnv * exec_env ;
363+ #endif
417364 bool check_ret , is_timeout , no_wait ;
418365
419366 bh_assert (module -> module_type == Wasm_Module_Bytecode
@@ -489,14 +436,47 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
489436 /* condition wait start */
490437 os_mutex_lock (& wait_node -> wait_lock );
491438
492- if (!no_wait
439+ if (!no_wait ) {
440+ /* unit of timeout is nsec, convert it to usec */
441+ uint64 timeout_left = (uint64 )timeout / 1000 , timeout_wait ;
442+ uint64 timeout_1sec = 1e6 ;
443+
444+ while (1 ) {
445+ if (timeout < 0 ) {
446+ /* wait forever until it is notified or terminatied
447+ here we keep waiting and checking every second */
448+ os_cond_reltimedwait (& wait_node -> wait_cond ,
449+ & wait_node -> wait_lock ,
450+ (uint64 )timeout_1sec );
451+ if (wait_node -> status
452+ == S_NOTIFIED /* notified by atomic.notify */
453+ #if WASM_ENABLE_THREAD_MGR != 0
454+ /* terminated by other thread */
455+ || wasm_cluster_is_thread_terminated (exec_env )
456+ #endif
457+ ) {
458+ break ;
459+ }
460+ /* continue to wait */
461+ }
462+ else {
463+ timeout_wait =
464+ timeout_left < timeout_1sec ? timeout_left : timeout_1sec ;
465+ os_cond_reltimedwait (& wait_node -> wait_cond ,
466+ & wait_node -> wait_lock , timeout_wait );
467+ if (wait_node -> status
468+ == S_NOTIFIED /* notified by atomic.notify */
469+ || timeout_left <= timeout_wait /* time out */
493470#if WASM_ENABLE_THREAD_MGR != 0
494- && !wasm_cluster_is_thread_terminated (exec_env )
471+ /* terminated by other thread */
472+ || wasm_cluster_is_thread_terminated (exec_env )
495473#endif
496- ) {
497- os_cond_reltimedwait (& wait_node -> wait_cond , & wait_node -> wait_lock ,
498- timeout < 0 ? BHT_WAIT_FOREVER
499- : (uint64 )timeout / 1000 );
474+ ) {
475+ break ;
476+ }
477+ timeout_left -= timeout_wait ;
478+ }
479+ }
500480 }
501481
502482 is_timeout = wait_node -> status == S_WAITING ? true : false;
0 commit comments