wasm-micro-runtime/core/iwasm/common/wasm_blocking_op.c

93 lines
2.3 KiB
C
Raw Normal View History

/*
* 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 */