Skip to content

Commit aabe830

Browse files
Improvements for platform thread APIs on Windows and Zephyr (#3941)
* improvements for os_thread_join on Windows and Zephyr
1 parent 739efd7 commit aabe830

File tree

3 files changed

+78
-11
lines changed

3 files changed

+78
-11
lines changed

core/shared/platform/windows/win_thread.c

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,63 @@ static DWORD thread_data_key;
6060
static void(WINAPI *GetCurrentThreadStackLimits_Kernel32)(PULONG_PTR,
6161
PULONG_PTR) = NULL;
6262

63+
static void
64+
thread_data_list_add(os_thread_data *thread_data)
65+
{
66+
os_mutex_lock(&thread_data_list_lock);
67+
/* If already in list, just return */
68+
os_thread_data *p = &supervisor_thread_data;
69+
while (p) {
70+
if (p == thread_data) {
71+
os_mutex_unlock(&thread_data_list_lock);
72+
return;
73+
}
74+
p = p->next;
75+
}
76+
thread_data->next = supervisor_thread_data.next;
77+
supervisor_thread_data.next = thread_data;
78+
os_mutex_unlock(&thread_data_list_lock);
79+
}
80+
81+
static void
82+
thread_data_list_remove(os_thread_data *thread_data)
83+
{
84+
os_mutex_lock(&thread_data_list_lock);
85+
/* Search and remove it from list */
86+
os_thread_data *p = &supervisor_thread_data;
87+
while (p && p->next != thread_data)
88+
p = p->next;
89+
90+
if (p && p->next) {
91+
bh_assert(p->next == thread_data);
92+
p->next = p->next->next;
93+
/* Release the resources in thread_data */
94+
os_cond_destroy(&thread_data->wait_cond);
95+
os_mutex_destroy(&thread_data->wait_lock);
96+
os_sem_destroy(&thread_data->wait_node.sem);
97+
BH_FREE(thread_data);
98+
}
99+
os_mutex_unlock(&thread_data_list_lock);
100+
}
101+
102+
static os_thread_data *
103+
thread_data_list_lookup(korp_tid tid)
104+
{
105+
os_thread_data *thread_data = (os_thread_data *)tid;
106+
os_mutex_lock(&thread_data_list_lock);
107+
os_thread_data *p = supervisor_thread_data.next;
108+
while (p) {
109+
if (p == thread_data) {
110+
/* Found */
111+
os_mutex_unlock(&thread_data_list_lock);
112+
return p;
113+
}
114+
p = p->next;
115+
}
116+
os_mutex_unlock(&thread_data_list_lock);
117+
return NULL;
118+
}
119+
63120
int
64121
os_sem_init(korp_sem *sem);
65122
int
@@ -254,10 +311,7 @@ os_thread_create_with_prio(korp_tid *p_tid, thread_start_routine_t start,
254311
}
255312

256313
/* Add thread data into thread data list */
257-
os_mutex_lock(&thread_data_list_lock);
258-
thread_data->next = supervisor_thread_data.next;
259-
supervisor_thread_data.next = thread_data;
260-
os_mutex_unlock(&thread_data_list_lock);
314+
thread_data_list_add(thread_data);
261315

262316
/* Wait for the thread routine to set thread_data's tid
263317
and add thread_data to thread data list */
@@ -302,8 +356,12 @@ os_thread_join(korp_tid thread, void **p_retval)
302356
curr_thread_data->wait_node.next = NULL;
303357

304358
/* Get thread data of thread to join */
305-
thread_data = (os_thread_data *)thread;
306-
bh_assert(thread_data);
359+
thread_data = thread_data_list_lookup(thread);
360+
361+
if (thread_data == NULL) {
362+
os_printf("Can't join thread %p, it does not exist", thread);
363+
return BHT_ERROR;
364+
}
307365

308366
os_mutex_lock(&thread_data->wait_lock);
309367

@@ -312,6 +370,7 @@ os_thread_join(korp_tid thread, void **p_retval)
312370
if (p_retval)
313371
*p_retval = thread_data->thread_retval;
314372
os_mutex_unlock(&thread_data->wait_lock);
373+
thread_data_list_remove(thread_data);
315374
return BHT_OK;
316375
}
317376

@@ -332,6 +391,7 @@ os_thread_join(korp_tid thread, void **p_retval)
332391
os_sem_wait(&curr_thread_data->wait_node.sem);
333392
if (p_retval)
334393
*p_retval = curr_thread_data->wait_node.retval;
394+
thread_data_list_remove(thread_data);
335395
return BHT_OK;
336396
}
337397

core/shared/platform/zephyr/zephyr_thread.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,17 +393,23 @@ os_thread_join(korp_tid thread, void **value_ptr)
393393
os_thread_data *thread_data;
394394
os_thread_wait_node *node;
395395

396+
/* Get thread data */
397+
thread_data = thread_data_list_lookup(thread);
398+
399+
if (thread_data == NULL) {
400+
os_printf(
401+
"Can't join thread %p, probably already exited or does not exist",
402+
thread);
403+
return BHT_OK;
404+
}
405+
396406
/* Create wait node and append it to wait list */
397407
if (!(node = BH_MALLOC(sizeof(os_thread_wait_node))))
398408
return BHT_ERROR;
399409

400410
sem_init(&node->sem, 0, 1);
401411
node->next = NULL;
402412

403-
/* Get thread data */
404-
thread_data = thread_data_list_lookup(thread);
405-
bh_assert(thread_data != NULL);
406-
407413
mutex_lock(&thread_data->wait_list_lock, K_FOREVER);
408414
if (!thread_data->thread_wait_list)
409415
thread_data->thread_wait_list = node;

core/shared/utils/bh_atomic.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ typedef uint16 bh_atomic_16_t;
114114
#endif
115115

116116
/* On some 32-bit platform, disable 64-bit atomic operations, otherwise
117-
* undefined reference to `__atomic_load_8' */
117+
* undefined reference to `__atomic_load_8', if on Zephyr, can add board related
118+
* macro in autoconf.h to control */
118119
#ifndef WASM_UINT64_IS_ATOMIC
119120
#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) \
120121
&& !defined(__OpenBSD__) && (defined(__riscv) || defined(__arm__)) \

0 commit comments

Comments
 (0)