mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 13:17:31 +00:00 
			
		
		
		
	 5a23ae465c
			
		
	
	
		5a23ae465c
		
			
		
	
	
	
	
		
			
			Fix issue reported in #2172: wasm-c-api `wasm_func_call` may use a wrong exec_env when multi-threading is enabled, with error "invalid exec env" reported Fix issue reported in #2149: main instance's `c_api_func_imports` are not passed to the counterpart of new thread's instance in wasi-threads mode Fix issue of invalid size calculated to copy `c_api_func_imports` in pthread mode And refactor the code to use `wasm_cluster_dup_c_api_imports` to copy the `c_api_func_imports` to new thread for wasi-threads mode and pthread mode.
		
			
				
	
	
		
			219 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2019 Intel Corporation.  All rights reserved.
 | |
|  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
|  */
 | |
| 
 | |
| #ifndef _THREAD_MANAGER_H
 | |
| #define _THREAD_MANAGER_H
 | |
| 
 | |
| #include "bh_common.h"
 | |
| #include "bh_log.h"
 | |
| #include "wasm_export.h"
 | |
| #include "../interpreter/wasm.h"
 | |
| #include "../common/wasm_runtime_common.h"
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| #if WASM_ENABLE_DEBUG_INTERP != 0
 | |
| typedef struct WASMDebugInstance WASMDebugInstance;
 | |
| #endif
 | |
| 
 | |
| struct WASMCluster {
 | |
|     struct WASMCluster *next;
 | |
| 
 | |
|     korp_mutex lock;
 | |
|     bh_list exec_env_list;
 | |
| 
 | |
| #if WASM_ENABLE_HEAP_AUX_STACK_ALLOCATION == 0
 | |
|     /* The aux stack of a module with shared memory will be
 | |
|         divided into several segments. This array store the
 | |
|         stack top of different segments */
 | |
|     uint32 *stack_tops;
 | |
|     /* Record which segments are occupied */
 | |
|     bool *stack_segment_occupied;
 | |
| #endif
 | |
|     /* Size of every stack segment */
 | |
|     uint32 stack_size;
 | |
|     /* When has_exception == true, this cluster should refuse any spawn thread
 | |
|      * requests, this flag can be cleared by calling
 | |
|      * wasm_runtime_clear_exception on instances of any threads of this cluster
 | |
|      */
 | |
|     bool has_exception;
 | |
|     /* When processing is true, this cluster should refuse any spawn thread
 | |
|      * requests. This is a short-lived state, must be cleared immediately once
 | |
|      * the processing finished.
 | |
|      * This is used to avoid dead lock when one thread waiting another thread
 | |
|      * with lock, see wams_cluster_wait_for_all and wasm_cluster_terminate_all
 | |
|      */
 | |
|     bool processing;
 | |
| #if WASM_ENABLE_DEBUG_INTERP != 0
 | |
|     WASMDebugInstance *debug_inst;
 | |
| #endif
 | |
| };
 | |
| 
 | |
| void
 | |
| wasm_cluster_set_max_thread_num(uint32 num);
 | |
| 
 | |
| bool
 | |
| thread_manager_init();
 | |
| 
 | |
| void
 | |
| thread_manager_destroy();
 | |
| 
 | |
| /* Create cluster */
 | |
| WASMCluster *
 | |
| wasm_cluster_create(WASMExecEnv *exec_env);
 | |
| 
 | |
| /* Destroy cluster */
 | |
| void
 | |
| wasm_cluster_destroy(WASMCluster *cluster);
 | |
| 
 | |
| /* Get the cluster of the current exec_env */
 | |
| WASMCluster *
 | |
| wasm_exec_env_get_cluster(WASMExecEnv *exec_env);
 | |
| 
 | |
| /* Forward registered functions to a new thread */
 | |
| bool
 | |
| wasm_cluster_dup_c_api_imports(WASMModuleInstanceCommon *module_inst_dst,
 | |
|                                const WASMModuleInstanceCommon *module_inst_src);
 | |
| 
 | |
| int32
 | |
| wasm_cluster_create_thread(WASMExecEnv *exec_env,
 | |
|                            wasm_module_inst_t module_inst, bool alloc_aux_stack,
 | |
|                            void *(*thread_routine)(void *), void *arg);
 | |
| 
 | |
| int32
 | |
| wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val);
 | |
| 
 | |
| int32
 | |
| wasm_cluster_detach_thread(WASMExecEnv *exec_env);
 | |
| 
 | |
| int32
 | |
| wasm_cluster_cancel_thread(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval);
 | |
| 
 | |
| bool
 | |
| wasm_cluster_register_destroy_callback(void (*callback)(WASMCluster *));
 | |
| 
 | |
| void
 | |
| wasm_cluster_cancel_all_callbacks();
 | |
| 
 | |
| void
 | |
| wasm_cluster_suspend_all(WASMCluster *cluster);
 | |
| 
 | |
| void
 | |
| wasm_cluster_suspend_all_except_self(WASMCluster *cluster,
 | |
|                                      WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_suspend_thread(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_resume_thread(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_resume_all(WASMCluster *cluster);
 | |
| 
 | |
| void
 | |
| wasm_cluster_terminate_all(WASMCluster *cluster);
 | |
| 
 | |
| void
 | |
| wasm_cluster_terminate_all_except_self(WASMCluster *cluster,
 | |
|                                        WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wams_cluster_wait_for_all(WASMCluster *cluster);
 | |
| 
 | |
| void
 | |
| wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
 | |
|                                       WASMExecEnv *exec_env);
 | |
| 
 | |
| bool
 | |
| wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env);
 | |
| 
 | |
| WASMExecEnv *
 | |
| wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst);
 | |
| 
 | |
| void
 | |
| wasm_cluster_spread_exception(WASMExecEnv *exec_env, bool clear);
 | |
| 
 | |
| WASMExecEnv *
 | |
| wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
 | |
|                                 void *custom_data);
 | |
| 
 | |
| bool
 | |
| wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env);
 | |
| 
 | |
| #if WASM_ENABLE_DEBUG_INTERP != 0
 | |
| #define WAMR_SIG_TRAP (5)
 | |
| #define WAMR_SIG_STOP (19)
 | |
| #define WAMR_SIG_TERM (15)
 | |
| #define WAMR_SIG_SINGSTEP (0x1ff)
 | |
| 
 | |
| #define STATUS_RUNNING (0)
 | |
| #define STATUS_STOP (1)
 | |
| #define STATUS_EXIT (2)
 | |
| #define STATUS_STEP (3)
 | |
| 
 | |
| #define IS_WAMR_TERM_SIG(signo) ((signo) == WAMR_SIG_TERM)
 | |
| 
 | |
| #define IS_WAMR_STOP_SIG(signo) \
 | |
|     ((signo) == WAMR_SIG_STOP || (signo) == WAMR_SIG_TRAP)
 | |
| 
 | |
| struct WASMCurrentEnvStatus {
 | |
|     uint64 signal_flag : 32;
 | |
|     uint64 step_count : 16;
 | |
|     uint64 running_status : 16;
 | |
| };
 | |
| 
 | |
| WASMCurrentEnvStatus *
 | |
| wasm_cluster_create_exenv_status();
 | |
| 
 | |
| void
 | |
| wasm_cluster_destroy_exenv_status(WASMCurrentEnvStatus *status);
 | |
| 
 | |
| void
 | |
| wasm_cluster_send_signal_all(WASMCluster *cluster, uint32 signo);
 | |
| 
 | |
| /* This function must be called with exec_env->wait_lock locked, otherwise we
 | |
|  * may miss the signal from debugger thread, see
 | |
|  * https://github.com/bytecodealliance/wasm-micro-runtime/issues/1860 */
 | |
| void
 | |
| wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_wait_thread_status(WASMExecEnv *exec_env, uint32 *status);
 | |
| 
 | |
| void
 | |
| wasm_cluster_thread_exited(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_thread_continue(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_thread_send_signal(WASMExecEnv *exec_env, uint32 signo);
 | |
| 
 | |
| void
 | |
| wasm_cluster_thread_step(WASMExecEnv *exec_env);
 | |
| 
 | |
| void
 | |
| wasm_cluster_set_debug_inst(WASMCluster *cluster, WASMDebugInstance *inst);
 | |
| 
 | |
| #endif /* end of WASM_ENABLE_DEBUG_INTERP != 0 */
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #endif /* end of _THREAD_MANAGER_H */
 |