Implement suspend flags as atomic variable#2361
Implement suspend flags as atomic variable#2361wenyongh merged 1 commit intobytecodealliance:mainfrom
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.
- 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.
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.
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.
The file right now includes the following:
- definitions of the suspend flag values (
WASM_SUSPEND_FLAG_*definitions) WASMSuspendFlagsdata 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_ATOMICdefinition) - macros for locking the flag if it's not atomic (
WASM_SUSPEND_FLAGS_(UN)LOCKmacros)
They all seem pretty related to suspend flags.
There was a problem hiding this comment.
availability check and wrappers on atomic builtins are generic.
nchamzn
left a comment
There was a problem hiding this comment.
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.
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.
not updating it for now as per @wenyongh 's comment
| 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.
forgot to take wait_lock? (not a fault of this PR though)
There was a problem hiding this comment.
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.
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.
| #if WASM_SUSPEND_FLAGS_IS_ATOMIC != 0 | ||
| #define WASM_SUSPEND_FLAGS_LOCK(lock) \ | ||
| do { \ | ||
| } while (0) |
| 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.
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.
| 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.
Had better change 0x01 to WASM_SUSPEND_FLAG_TERMINATE
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.