Skip to content

Commit f56154e

Browse files
authored
thread-mgr: Fix locking problems around aux stack allocation (#3073)
Fixes: #3069
1 parent 0eb788d commit f56154e

File tree

1 file changed

+44
-57
lines changed

1 file changed

+44
-57
lines changed

core/iwasm/libraries/thread-mgr/thread_manager.c

Lines changed: 44 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,10 @@ safe_traverse_exec_env_list(WASMCluster *cluster, list_visitor visitor,
137137
return ret;
138138
}
139139

140-
/* The caller must lock cluster->lock */
141-
static bool
142-
allocate_aux_stack(WASMExecEnv *exec_env, uint32 *start, uint32 *size)
140+
/* The caller must not have any locks */
141+
bool
142+
wasm_cluster_allocate_aux_stack(WASMExecEnv *exec_env, uint32 *p_start,
143+
uint32 *p_size)
143144
{
144145
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
145146
#if WASM_ENABLE_HEAP_AUX_STACK_ALLOCATION != 0
@@ -149,36 +150,42 @@ allocate_aux_stack(WASMExecEnv *exec_env, uint32 *start, uint32 *size)
149150

150151
stack_end = wasm_runtime_module_malloc_internal(module_inst, exec_env,
151152
cluster->stack_size, NULL);
152-
*start = stack_end + cluster->stack_size;
153-
*size = cluster->stack_size;
153+
*p_start = stack_end + cluster->stack_size;
154+
*p_size = cluster->stack_size;
154155

155156
return stack_end != 0;
156157
#else
157158
uint32 i;
158159

159160
/* If the module doesn't have aux stack info,
160161
it can't create any threads */
161-
if (!cluster->stack_segment_occupied)
162+
163+
os_mutex_lock(&cluster->lock);
164+
if (!cluster->stack_segment_occupied) {
165+
os_mutex_unlock(&cluster->lock);
162166
return false;
167+
}
163168

164169
for (i = 0; i < cluster_max_thread_num; i++) {
165170
if (!cluster->stack_segment_occupied[i]) {
166-
if (start)
167-
*start = cluster->stack_tops[i];
168-
if (size)
169-
*size = cluster->stack_size;
171+
if (p_start)
172+
*p_start = cluster->stack_tops[i];
173+
if (p_size)
174+
*p_size = cluster->stack_size;
170175
cluster->stack_segment_occupied[i] = true;
176+
os_mutex_unlock(&cluster->lock);
171177
return true;
172178
}
173179
}
180+
os_mutex_unlock(&cluster->lock);
174181

175182
return false;
176183
#endif
177184
}
178185

179-
/* The caller must lock cluster->lock */
180-
static bool
181-
free_aux_stack(WASMExecEnv *exec_env, uint32 start)
186+
/* The caller must not have any locks */
187+
bool
188+
wasm_cluster_free_aux_stack(WASMExecEnv *exec_env, uint32 start)
182189
{
183190
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
184191

@@ -199,43 +206,19 @@ free_aux_stack(WASMExecEnv *exec_env, uint32 start)
199206
#else
200207
uint32 i;
201208

209+
os_mutex_lock(&cluster->lock);
202210
for (i = 0; i < cluster_max_thread_num; i++) {
203211
if (start == cluster->stack_tops[i]) {
204212
cluster->stack_segment_occupied[i] = false;
213+
os_mutex_unlock(&cluster->lock);
205214
return true;
206215
}
207216
}
217+
os_mutex_unlock(&cluster->lock);
208218
return false;
209219
#endif
210220
}
211221

212-
bool
213-
wasm_cluster_allocate_aux_stack(WASMExecEnv *exec_env, uint32 *p_start,
214-
uint32 *p_size)
215-
{
216-
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
217-
bool ret;
218-
219-
os_mutex_lock(&cluster->lock);
220-
ret = allocate_aux_stack(exec_env, p_start, p_size);
221-
os_mutex_unlock(&cluster->lock);
222-
223-
return ret;
224-
}
225-
226-
bool
227-
wasm_cluster_free_aux_stack(WASMExecEnv *exec_env, uint32 start)
228-
{
229-
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
230-
bool ret;
231-
232-
os_mutex_lock(&cluster->lock);
233-
ret = free_aux_stack(exec_env, start);
234-
os_mutex_unlock(&cluster->lock);
235-
236-
return ret;
237-
}
238-
239222
WASMCluster *
240223
wasm_cluster_create(WASMExecEnv *exec_env)
241224
{
@@ -535,6 +518,13 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
535518
goto fail1;
536519
}
537520

521+
if (!wasm_cluster_allocate_aux_stack(exec_env, &aux_stack_start,
522+
&aux_stack_size)) {
523+
LOG_ERROR("thread manager error: "
524+
"failed to allocate aux stack space for new thread");
525+
goto fail1;
526+
}
527+
538528
os_mutex_lock(&cluster->lock);
539529

540530
if (cluster->has_exception || cluster->processing) {
@@ -561,37 +551,30 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
561551
goto fail2;
562552
}
563553

564-
if (!allocate_aux_stack(exec_env, &aux_stack_start, &aux_stack_size)) {
565-
LOG_ERROR("thread manager error: "
566-
"failed to allocate aux stack space for new thread");
567-
goto fail3;
568-
}
569-
570554
/* Set aux stack for current thread */
571555
if (!wasm_exec_env_set_aux_stack(new_exec_env, aux_stack_start,
572556
aux_stack_size)) {
573-
goto fail4;
557+
goto fail3;
574558
}
575559

576560
/* Inherit suspend_flags of parent thread */
577561
new_exec_env->suspend_flags.flags =
578562
(exec_env->suspend_flags.flags & WASM_SUSPEND_FLAG_INHERIT_MASK);
579563

580564
if (!wasm_cluster_add_exec_env(cluster, new_exec_env)) {
581-
goto fail4;
565+
goto fail3;
582566
}
583567

584568
os_mutex_unlock(&cluster->lock);
585569

586570
return new_exec_env;
587571

588-
fail4:
589-
/* free the allocated aux stack space */
590-
free_aux_stack(exec_env, aux_stack_start);
591572
fail3:
592573
wasm_exec_env_destroy_internal(new_exec_env);
593574
fail2:
594575
os_mutex_unlock(&cluster->lock);
576+
/* free the allocated aux stack space */
577+
wasm_cluster_free_aux_stack(exec_env, aux_stack_start);
595578
fail1:
596579
wasm_runtime_deinstantiate_internal(new_module_inst, true);
597580

@@ -618,10 +601,12 @@ wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env)
618601
exec_env_tls = exec_env;
619602
}
620603

604+
/* Free aux stack space */
605+
wasm_cluster_free_aux_stack(exec_env_tls,
606+
exec_env->aux_stack_bottom.bottom);
607+
621608
os_mutex_lock(&cluster->lock);
622609

623-
/* Free aux stack space */
624-
free_aux_stack(exec_env_tls, exec_env->aux_stack_bottom.bottom);
625610
/* Remove exec_env */
626611
wasm_cluster_del_exec_env_internal(cluster, exec_env, false);
627612
/* Destroy exec_env */
@@ -667,6 +652,9 @@ thread_manager_start_routine(void *arg)
667652
wasm_cluster_thread_exited(exec_env);
668653
#endif
669654

655+
/* Free aux stack space */
656+
wasm_cluster_free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
657+
670658
os_mutex_lock(&cluster_list_lock);
671659

672660
os_mutex_lock(&cluster->lock);
@@ -687,8 +675,6 @@ thread_manager_start_routine(void *arg)
687675
os_printf("========================================\n");
688676
#endif
689677

690-
/* Free aux stack space */
691-
free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
692678
/* Remove exec_env */
693679
wasm_cluster_del_exec_env_internal(cluster, exec_env, false);
694680
/* Destroy exec_env */
@@ -1063,6 +1049,9 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
10631049
wasm_cluster_thread_exited(exec_env);
10641050
#endif
10651051

1052+
/* Free aux stack space */
1053+
wasm_cluster_free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
1054+
10661055
/* App exit the thread, free the resources before exit native thread */
10671056

10681057
os_mutex_lock(&cluster_list_lock);
@@ -1081,8 +1070,6 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
10811070

10821071
module_inst = exec_env->module_inst;
10831072

1084-
/* Free aux stack space */
1085-
free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom);
10861073
/* Remove exec_env */
10871074
wasm_cluster_del_exec_env_internal(cluster, exec_env, false);
10881075
/* Destroy exec_env */

0 commit comments

Comments
 (0)