@@ -10,6 +10,10 @@ static bh_list shared_memory_list_head;
1010static bh_list * const shared_memory_list = & shared_memory_list_head ;
1111static korp_mutex shared_memory_list_lock ;
1212
13+ static bh_list atomic_wait_address_list_head ;
14+ static bh_list * const atomic_wait_address_list = & atomic_wait_address_list_head ;
15+ static korp_mutex atomic_wait_address_list_lock ;
16+
1317/* clang-format off */
1418enum {
1519 S_WAITING ,
@@ -30,6 +34,11 @@ typedef struct AtomicWaitNode {
3034 korp_cond wait_cond ;
3135} AtomicWaitNode ;
3236
37+ typedef struct AtomicWaitAddressNode {
38+ bh_list_link l ;
39+ void * addr ;
40+ } AtomicWaitAddressNode ;
41+
3342/* Atomic wait map */
3443static HashMap * wait_map ;
3544
@@ -47,6 +56,8 @@ wasm_shared_memory_init()
4756{
4857 if (os_mutex_init (& shared_memory_list_lock ) != 0 )
4958 return false;
59+ if (os_mutex_init (& atomic_wait_address_list_lock ) != 0 )
60+ return false;
5061 /* wait map not exists, create new map */
5162 if (!(wait_map = bh_hash_map_create (32 , true, (HashFunc )wait_address_hash ,
5263 (KeyEqualFunc )wait_address_equal , NULL ,
6273wasm_shared_memory_destroy ()
6374{
6475 os_mutex_destroy (& shared_memory_list_lock );
76+ os_mutex_destroy (& atomic_wait_address_list_lock );
6577 if (wait_map ) {
6678 bh_hash_map_destroy (wait_map );
6779 }
@@ -87,41 +99,18 @@ search_module(WASMModuleCommon *module)
8799 return NULL ;
88100}
89101
90- static void
91- notify_stale_threads (void * key , void * value , void * user_data )
92- {
93- WASMModuleInstanceCommon * module_inst =
94- (WASMModuleInstanceCommon * )user_data ;
95- wasm_runtime_atomic_notify (module_inst , key , UINT32_MAX );
96- bh_hash_map_remove (wait_map , key , NULL , NULL );
97- }
98-
99- static void
100- create_copy_of_wait_map (void * key , void * value , void * map_copy )
101- {
102- bh_hash_map_insert ((HashMap * )map_copy , key , value );
103- }
104-
105102void
106103notify_stale_threads_on_exception (WASMModuleInstanceCommon * module_inst )
107104{
108- static HashMap * wait_map_without_lock ;
109- wait_map_without_lock = bh_hash_map_create (
110- 32 , false, (HashFunc )wait_address_hash ,
111- (KeyEqualFunc )wait_address_equal , NULL , destroy_wait_info );
112- /**
113- * create a copy of wait_map with no lock
114- * this allows invoking methods in the callback
115- * which require acquiring lock on the original map
116- */
117- os_mutex_lock (& shared_memory_list_lock );
118- bh_hash_map_traverse (wait_map , create_copy_of_wait_map ,
119- wait_map_without_lock );
120- os_mutex_unlock (& shared_memory_list_lock );
105+ AtomicWaitAddressNode * node ;
121106
122- // terminate stale threads
123- bh_hash_map_traverse (wait_map_without_lock , notify_stale_threads ,
124- module_inst );
107+ os_mutex_lock (& atomic_wait_address_list_lock );
108+ node = bh_list_first_elem (atomic_wait_address_list );
109+ while (node ) {
110+ wasm_runtime_atomic_notify (module_inst , node -> addr , UINT32_MAX );
111+ node = bh_list_elem_next (node );
112+ }
113+ os_mutex_unlock (& atomic_wait_address_list_lock );
125114}
126115
127116WASMSharedMemNode *
@@ -341,6 +330,11 @@ release_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, void *address)
341330
342331 if (wait_info -> wait_list -> len == 0 ) {
343332 bh_hash_map_remove (wait_map_ , address , NULL , NULL );
333+
334+ os_mutex_lock (& atomic_wait_address_list_lock );
335+ bh_list_remove (atomic_wait_address_list , address );
336+ os_mutex_unlock (& atomic_wait_address_list_lock );
337+
344338 destroy_wait_info (wait_info );
345339 }
346340
@@ -382,6 +376,22 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
382376
383377 os_mutex_lock (& wait_info -> wait_list_lock );
384378
379+ /* add waiter address to atomic wait list */
380+ AtomicWaitAddressNode * wait_address_node ;
381+
382+ os_mutex_lock (& atomic_wait_address_list_lock );
383+ if (!(wait_address_node =
384+ wasm_runtime_malloc (sizeof (AtomicWaitAddressNode )))) {
385+ wasm_runtime_set_exception (module ,
386+ "failed to create wait address node" );
387+ os_mutex_unlock (& atomic_wait_address_list_lock );
388+ return -1 ;
389+ }
390+ wait_address_node -> addr = address ;
391+ bh_assert (bh_list_insert (atomic_wait_address_list , wait_address_node )
392+ == BH_LIST_SUCCESS );
393+ os_mutex_unlock (& atomic_wait_address_list_lock );
394+
385395 if ((!wait64 && * (uint32 * )address != (uint32 )expect )
386396 || (wait64 && * (uint64 * )address != expect )) {
387397 os_mutex_unlock (& wait_info -> wait_list_lock );
0 commit comments