forked from bytecodealliance/wasm-micro-runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement async termination of blocking thread (bytecodealliance#2516)
Send a signal whose handler is no-op to a blocking thread to wake up the blocking syscall with either EINTR equivalent or partial success. Unlike the approach taken in the `dev/interrupt_block_insn` branch (that is, signal + longjmp similarly to `OS_ENABLE_HW_BOUND_CHECK`), this PR does not use longjmp because: * longjmp from signal handler doesn't work on nuttx refer to apache/nuttx#10326 * the singal+longjmp approach may be too difficult for average programmers who might implement host functions to deal with See also bytecodealliance#1910
- Loading branch information
Showing
21 changed files
with
1,029 additions
and
302 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* Copyright (C) 2023 Midokura Japan KK. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
*/ | ||
|
||
#include "wasm_runtime_common.h" | ||
|
||
#include "bh_platform.h" | ||
#include "bh_common.h" | ||
#include "bh_assert.h" | ||
|
||
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP) | ||
|
||
#define LOCK(env) WASM_SUSPEND_FLAGS_LOCK((env)->wait_lock) | ||
#define UNLOCK(env) WASM_SUSPEND_FLAGS_UNLOCK((env)->wait_lock) | ||
|
||
#define ISSET(env, bit) \ | ||
((WASM_SUSPEND_FLAGS_GET((env)->suspend_flags) & WASM_SUSPEND_FLAG_##bit) \ | ||
!= 0) | ||
#define SET(env, bit) \ | ||
WASM_SUSPEND_FLAGS_FETCH_OR((env)->suspend_flags, WASM_SUSPEND_FLAG_##bit) | ||
#define CLR(env, bit) \ | ||
WASM_SUSPEND_FLAGS_FETCH_AND((env)->suspend_flags, ~WASM_SUSPEND_FLAG_##bit) | ||
|
||
bool | ||
wasm_runtime_begin_blocking_op(wasm_exec_env_t env) | ||
{ | ||
LOCK(env); | ||
bh_assert(!ISSET(env, BLOCKING)); | ||
SET(env, BLOCKING); | ||
if (ISSET(env, TERMINATE)) { | ||
CLR(env, BLOCKING); | ||
UNLOCK(env); | ||
return false; | ||
} | ||
UNLOCK(env); | ||
os_begin_blocking_op(); | ||
return true; | ||
} | ||
|
||
void | ||
wasm_runtime_end_blocking_op(wasm_exec_env_t env) | ||
{ | ||
int saved_errno = errno; | ||
LOCK(env); | ||
bh_assert(ISSET(env, BLOCKING)); | ||
CLR(env, BLOCKING); | ||
UNLOCK(env); | ||
os_end_blocking_op(); | ||
errno = saved_errno; | ||
} | ||
|
||
void | ||
wasm_runtime_interrupt_blocking_op(wasm_exec_env_t env) | ||
{ | ||
/* | ||
* ISSET(BLOCKING) here means that the target thread | ||
* is in somewhere between wasm_begin_blocking_op and | ||
* wasm_end_blocking_op. | ||
* keep waking it up until it reaches wasm_end_blocking_op, | ||
* which clears the BLOCKING bit. | ||
* | ||
* this dumb loop is necessary because posix doesn't provide | ||
* a way to unmask signal and block atomically. | ||
*/ | ||
|
||
LOCK(env); | ||
SET(env, TERMINATE); | ||
while (ISSET(env, BLOCKING)) { | ||
UNLOCK(env); | ||
os_wakeup_blocking_op(env->handle); | ||
|
||
/* relax a bit */ | ||
os_usleep(50 * 1000); | ||
LOCK(env); | ||
} | ||
UNLOCK(env); | ||
} | ||
|
||
#else /* WASM_ENABLE_THREAD_MGR && OS_ENABLE_WAKEUP_BLOCKING_OP */ | ||
|
||
bool | ||
wasm_runtime_begin_blocking_op(wasm_exec_env_t env) | ||
{ | ||
return true; | ||
} | ||
|
||
void | ||
wasm_runtime_end_blocking_op(wasm_exec_env_t env) | ||
{} | ||
|
||
#endif /* WASM_ENABLE_THREAD_MGR && OS_ENABLE_WAKEUP_BLOCKING_OP */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.