-
Notifications
You must be signed in to change notification settings - Fork 628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement suspend flags as atomic variable #2361
Conversation
dba41b7
to
fe64376
Compare
@wenyongh the build is passing now and the PR is ready for review. I'd appreciate your team's review. Many thanks |
@@ -0,0 +1,79 @@ | |||
/* | |||
* Copyright (C) 2023 Amazon Inc. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- most of the logic in this file seems not specific to suspend flags. how about using a bit more generic name?
- i guess the default implementation should be c11 atomics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, initially I've had an implementation based on stdatomics, but there are two problems with that:
- The size of the atomic variable is not guaranteed to be the size of the base type - and this is a requirement for JIT. We could potentially workaround it with set of ifs on code generation phase though
- this file is included (indirectly) by some c++ files (fast jit) and removing the dependency would require major refactoring. C11 stdatomics are not available in c++.
For those reasons I decided to go for a simple solution for now, but happy to iterate on that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about "most of the logic in this file seems not specific to suspend flags. how about using a bit more generic name?"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file right now includes the following:
- definitions of the suspend flag values (
WASM_SUSPEND_FLAG_*
definitions) WASMSuspendFlags
data structure- macros for operating on the suspend flag data structure (
WASM_SUSPEND_FLAGS_*
macros) - information whether the suspend flag is atomic (
WASM_SUSPEND_FLAGS_IS_ATOMIC
definition) - macros for locking the flag if it's not atomic (
WASM_SUSPEND_FLAGS_(UN)LOCK
macros)
They all seem pretty related to suspend flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
availability check and wrappers on atomic builtins are generic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have profiled this change and performance is now comparable to before the locks were added.
& WASM_SUSPEND_FLAG_SUSPEND) { \ | ||
/* suspend current thread */ \ | ||
SUSPENSION_LOCK() \ | ||
os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check WASM_SUSPEND_FLAG_SUSPEND with the lock held.
otherwise wasm_cluster_resume_thread can fail to wake up the thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not updating it for now as per @wenyongh 's comment
@@ -1214,7 +1219,8 @@ wasm_cluster_suspend_all_except_self(WASMCluster *cluster, | |||
void | |||
wasm_cluster_resume_thread(WASMExecEnv *exec_env) | |||
{ | |||
exec_env->suspend_flags.flags &= ~0x02; | |||
WASM_SUSPEND_FLAGS_FETCH_AND(exec_env->suspend_flags, | |||
~WASM_SUSPEND_FLAG_SUSPEND); | |||
os_cond_signal(&exec_env->wait_cond); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forgot to take wait_lock? (not a fault of this PR though)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The suspend/resume APIs (wasm_cluster_suspend_xxx
and wasm_cluster_resume_xxx
) are not called currently, and the current implementation is incomplete, I think let's ignore it here. It is a little complex to implement a full suspend/resume mechanism, we are trying to enable it, see #2320.
#define _WASM_SUSPEND_FLAGS_H | ||
|
||
#include "bh_platform.h" | ||
#include "gnuc.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you include "gnuc.h" in "bh_platform.h" instead? We often only include "bh_platfrom.h" to include all the required APIs in core/shared/platform
and core/shared/utils
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
#if WASM_SUSPEND_FLAGS_IS_ATOMIC != 0 | ||
#define WASM_SUSPEND_FLAGS_LOCK(lock) \ | ||
do { \ | ||
} while (0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about (void)0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -1214,7 +1219,8 @@ wasm_cluster_suspend_all_except_self(WASMCluster *cluster, | |||
void | |||
wasm_cluster_resume_thread(WASMExecEnv *exec_env) | |||
{ | |||
exec_env->suspend_flags.flags &= ~0x02; | |||
WASM_SUSPEND_FLAGS_FETCH_AND(exec_env->suspend_flags, | |||
~WASM_SUSPEND_FLAG_SUSPEND); | |||
os_cond_signal(&exec_env->wait_cond); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The suspend/resume APIs (wasm_cluster_suspend_xxx
and wasm_cluster_resume_xxx
) are not called currently, and the current implementation is incomplete, I think let's ignore it here. It is a little complex to implement a full suspend/resume mechanism, we are trying to enable it, see #2320.
@@ -1344,7 +1350,7 @@ wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env) | |||
{ | |||
os_mutex_lock(&exec_env->wait_lock); | |||
bool is_thread_terminated = | |||
(exec_env->suspend_flags.flags & 0x01) ? true : false; | |||
(WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) & 0x01) ? true : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had better change 0x01
to WASM_SUSPEND_FLAG_TERMINATE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
We have observed a significant performance degradation after merging bytecodealliance#1991 Instead of protecting suspend flags with a mutex, we implement the flags as atomic variable and only use mutex when atomics are not available on a given platform.
We have observed a significant performance degradation after merging bytecodealliance#1991 Instead of protecting suspend flags with a mutex, we implement the flags as atomic variable and only use mutex when atomics are not available on a given platform.
We have observed a significant performance degradation after merging #1991 Instead of protecting suspend flags with a mutex, we implement the flags as atomic variable and only use mutex when atomics are not available on a given platform.