.. | ||
atomic_add_sub.c | ||
atomic_fence.c | ||
atomic_logical.c | ||
atomic_store.c | ||
atomic_wait_notify.c | ||
atomic_xchg.c | ||
CMakeLists.txt | ||
peterson_native.c | ||
peterson.h | ||
README.md |
"Unit Test" Testsuite for Threads Opcode
These tests are meant to test the atomicity of threads code. Initially, they were meant to test if the fast JIT implementation is correct, but they can also be used to test other running modes. The semantics correctness (operating with the correct number of bytes in memory and returning the correct value) have already been tested in spec tests (single-thread environment).
Test Cases Opcode Coverage
Atomicity of all threads opcodes are fully tested with these cases.
☑ Only indicates there is a WASM test case to test the atomicity directly. The atomicity of other opcodes without ☑ is tested indirectly. Indirect testing means that it is either implicit with other cases in this directory or tested pragmatically correct (atomicity and semantic correctness together) in pthread or WASI-threads test cases.
Click the link to see the details of how each opcode is tested.
-
RMW (Read-Modify-Write):
- CMPXCHG opcode ☑
- Arithmetic:
- ADD opcode ☑
- SUB opcode ☑
- XCHG opcode ☑
- Logical:
-
STORE ☑
-
FENCE ☑
Details
atomic rmw
arithmetic (add
, sub
) and xchg
-
add, sub
: in atomic_add_sub.c, __atomic_fetch_add/sub() to generate wasm opcode atomic.add/sub -
xchg
: in x86-64 implementation, wasm code atomicstore
andxchg
generate same asm instruction xchg, should be enough to only test with store(tested in atomic_store.c). But add aatomic_xchg.c
to use __atomic_exchange() to generate wasm opcode xchg and test it anyways(tested in atomic_xchg.c).
logical or
, xor
, and
-
logical
or
,xor
,and
: those three opcodes are similar, it all generate a loop, inside which uses corresponding asm instruction do logical operation and locked cmpxchg to atomically modify the memory. So in a sense, test it will implicitly test the atomicity of cmpxchg.in atomic_logical.c, tested
xor
wasm opcode to test the atomicity of the generated loop:- make use of operation "n
xor
n -> 0", when n range from 1 to 9999, 4 thread concurrently xor the same variable, the final result should be 0.
The generated loop of
xor
is atomic -> generated loop ofor
,and
is also atomic - make use of operation "n
cmpxchg
- wasm opcode
cmpxchg
already tested together with other opcodes in multiple wasi-thread cases. Logical opcodes generate asm instruction lock cmpxchg, the atomicity of generated asm code is proven in logical opcode. In atomic_wait&¬ify.c, it also tests the opcodecmpxchg
atomic ld/st/fence
use peterson lock algorithm, in atomic_fence.c to test the atomicity of fence
PS: since the interpreter is relatively slow compared to JIT/AOT mode, it's less likely(almost impossible) to trigger processor-level behavior: instructions to be ordered within a single thread
The prerequisite for peterson lock properly is that load and store have to be Sequential Consistency
, which can be achieved use:
- LOAD (without fence) and STORE + MFENCE -> use it to test
fence
opcode - LOAD (without fence) and LOCK XCHG -> use it to test atomic
store
opcode - MFENCE + LOAD and STORE (without fence)
- LOCK XADD ( 0 ) and STORE (without fence)
atomic wait¬ify
Actually in every pthread tests, it will generate wait
and notify
, it is also tested in in multiple wasi-thread cases.
But add a atomic_wait&¬ify.c to test it anyways.