Skip to content

Commit da25906

Browse files
authored
debug-interp: Only add lock when signal_flag is SIG_SINGSTEP (bytecodealliance#3704)
As reported in bytecodealliance#3500, when debug interpreter is enabled, the classic interpreter performs a lock operation to read `exec_env->current_status->signal_flag` and do further handling before fetching next opcode, which makes the interpreter run slower. This PR atomic loads the `exec_env->current_status->signal_flag` without mutex lock when 32-bit atomic load is supported, and only adding lock for further handling when the signal_flag is WAMR_SIG_SINGSTEP, which improves the performance.
1 parent 37d7439 commit da25906

File tree

2 files changed

+59
-26
lines changed

2 files changed

+59
-26
lines changed

core/iwasm/interpreter/wasm_interp_classic.c

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,17 +1399,64 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
13991399
#endif /* WASM_ENABLE_DEBUG_INTERP */
14001400
#endif /* WASM_ENABLE_THREAD_MGR */
14011401

1402+
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
1403+
#if BH_ATOMIC_32_IS_ATOMIC != 0
1404+
#define GET_SIGNAL_FLAG() \
1405+
do { \
1406+
signal_flag = \
1407+
BH_ATOMIC_32_LOAD(exec_env->current_status->signal_flag); \
1408+
} while (0)
1409+
#else
1410+
#define GET_SIGNAL_FLAG() \
1411+
do { \
1412+
os_mutex_lock(&exec_env->wait_lock); \
1413+
signal_flag = exec_env->current_status->signal_flag; \
1414+
os_mutex_unlock(&exec_env->wait_lock); \
1415+
} while (0)
1416+
#endif
1417+
#endif
1418+
14021419
#if WASM_ENABLE_LABELS_AS_VALUES != 0
14031420

14041421
#define HANDLE_OP(opcode) HANDLE_##opcode:
14051422
#define FETCH_OPCODE_AND_DISPATCH() goto *handle_table[*frame_ip++]
14061423

1424+
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
1425+
#define HANDLE_OP_END() \
1426+
do { \
1427+
/* Record the current frame_ip, so when exception occurs, \
1428+
debugger can know the exact opcode who caused the exception */ \
1429+
frame_ip_orig = frame_ip; \
1430+
/* Atomic load the exec_env's signal_flag first, and then handle \
1431+
more with lock if it is WAMR_SIG_SINGSTEP */ \
1432+
GET_SIGNAL_FLAG(); \
1433+
if (signal_flag == WAMR_SIG_SINGSTEP) { \
1434+
os_mutex_lock(&exec_env->wait_lock); \
1435+
while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
1436+
&& exec_env->current_status->step_count++ == 1) { \
1437+
exec_env->current_status->step_count = 0; \
1438+
SYNC_ALL_TO_FRAME(); \
1439+
wasm_cluster_thread_waiting_run(exec_env); \
1440+
} \
1441+
os_mutex_unlock(&exec_env->wait_lock); \
1442+
} \
1443+
goto *handle_table[*frame_ip++]; \
1444+
} while (0)
1445+
#else
1446+
#define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
1447+
#endif
1448+
1449+
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
1450+
#define HANDLE_OP(opcode) case opcode:
14071451
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
14081452
#define HANDLE_OP_END() \
1409-
do { \
1410-
/* Record the current frame_ip, so when exception occurs, \
1411-
debugger can know the exact opcode who caused the exception */ \
1412-
frame_ip_orig = frame_ip; \
1453+
/* Record the current frame_ip, so when exception occurs, \
1454+
debugger can know the exact opcode who caused the exception */ \
1455+
frame_ip_orig = frame_ip; \
1456+
/* Atomic load the exec_env's signal_flag first, and then handle \
1457+
more with lock if it is WAMR_SIG_SINGSTEP */ \
1458+
GET_SIGNAL_FLAG(); \
1459+
if (signal_flag == WAMR_SIG_SINGSTEP) { \
14131460
os_mutex_lock(&exec_env->wait_lock); \
14141461
while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
14151462
&& exec_env->current_status->step_count++ == 1) { \
@@ -1418,25 +1465,8 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
14181465
wasm_cluster_thread_waiting_run(exec_env); \
14191466
} \
14201467
os_mutex_unlock(&exec_env->wait_lock); \
1421-
goto *handle_table[*frame_ip++]; \
1422-
} while (0)
1423-
#else
1424-
#define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
1425-
#endif
1426-
1427-
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
1428-
#define HANDLE_OP(opcode) case opcode:
1429-
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
1430-
#define HANDLE_OP_END() \
1431-
os_mutex_lock(&exec_env->wait_lock); \
1432-
if (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
1433-
&& exec_env->current_status->step_count++ == 1) { \
1434-
exec_env->current_status->step_count = 0; \
1435-
SYNC_ALL_TO_FRAME(); \
1436-
wasm_cluster_thread_waiting_run(exec_env); \
1437-
} \
1438-
os_mutex_unlock(&exec_env->wait_lock); \
1439-
continue
1468+
} \
1469+
continue;
14401470
#else
14411471
#define HANDLE_OP_END() continue
14421472
#endif
@@ -1545,6 +1575,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
15451575
debug_instance ? &debug_instance->watch_point_list_read : NULL;
15461576
bh_list *watch_point_list_write =
15471577
debug_instance ? &debug_instance->watch_point_list_write : NULL;
1578+
#if WASM_ENABLE_THREAD_MGR != 0
1579+
uint32 signal_flag;
1580+
#endif
15481581
#endif
15491582

15501583
#if WASM_ENABLE_LABELS_AS_VALUES != 0

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,9 @@ wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env);
184184
((signo) == WAMR_SIG_STOP || (signo) == WAMR_SIG_TRAP)
185185

186186
struct WASMCurrentEnvStatus {
187-
uint64 signal_flag : 32;
188-
uint64 step_count : 16;
189-
uint64 running_status : 16;
187+
uint32 signal_flag;
188+
uint16 step_count;
189+
uint16 running_status;
190190
};
191191

192192
WASMCurrentEnvStatus *

0 commit comments

Comments
 (0)