Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions test/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5011,9 +5011,13 @@ def test_wasm_worker_futex_wait(self, args):

# Tests Wasm Worker thread stack setup
@also_with_minimal_runtime
def test_wasm_worker_thread_stack(self):
for mode in (0, 1, 2):
self.btest('wasm_worker/thread_stack.c', expected='0', args=['-sWASM_WORKERS', f'-sSTACK_OVERFLOW_CHECK={mode}'])
@parameterized({
'0': (0,),
'1': (1,),
'2': (2,),
})
def test_wasm_worker_thread_stack(self, mode):
self.btest('wasm_worker/thread_stack.c', expected='0', args=['-sWASM_WORKERS', f'-sSTACK_OVERFLOW_CHECK={mode}'])

# Tests emscripten_malloc_wasm_worker() and emscripten_current_thread_is_wasm_worker() functions
@also_with_minimal_runtime
Expand Down
9 changes: 3 additions & 6 deletions test/wasm_worker/c11__Thread_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@

_Thread_local int __attribute__((aligned(64))) tls = 1;

void main_thread_func()
{
void main_thread_func() {
assert(!emscripten_current_thread_is_wasm_worker());
EM_ASM(out($0), tls);
#ifdef REPORT_RESULT
REPORT_RESULT(tls);
#endif
}

void worker_main()
{
void worker_main() {
assert(emscripten_current_thread_is_wasm_worker());
assert(((intptr_t)&tls % 64) == 0);
assert(tls != 42);
Expand All @@ -27,8 +25,7 @@ void worker_main()

char stack[1024];

int main()
{
int main() {
EM_ASM(out($0), tls);
assert(((intptr_t)&tls % 64) == 0);
assert(!emscripten_current_thread_is_wasm_worker());
Expand Down
9 changes: 3 additions & 6 deletions test/wasm_worker/cancel_all_wait_asyncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,20 @@ volatile int32_t addr = 1;

bool testSucceeded = 1;

void asyncWaitFinishedShouldNotBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData)
{
void asyncWaitFinishedShouldNotBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData) {
emscripten_console_log("asyncWaitFinishedShouldNotBeCalled");
testSucceeded = 0;
assert(0); // We should not reach here
}

void asyncWaitFinishedShouldBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData)
{
void asyncWaitFinishedShouldBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData) {
emscripten_console_log("asyncWaitFinishedShouldBeCalled");
#ifdef REPORT_RESULT
REPORT_RESULT(testSucceeded);
#endif
}

int main()
{
int main() {
emscripten_console_log("Async waiting on address should give a wait token");
ATOMICS_WAIT_TOKEN_T ret = emscripten_atomic_wait_async((int32_t*)&addr, 1, asyncWaitFinishedShouldNotBeCalled, (void*)42, EMSCRIPTEN_WAIT_ASYNC_INFINITY);
assert(EMSCRIPTEN_IS_VALID_WAIT_TOKEN(ret));
Expand Down
9 changes: 3 additions & 6 deletions test/wasm_worker/cancel_all_wait_asyncs_at_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,20 @@ volatile int32_t addr = 1;

bool testSucceeded = 1;

void asyncWaitFinishedShouldNotBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData)
{
void asyncWaitFinishedShouldNotBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData) {
emscripten_console_log("asyncWaitFinishedShouldNotBeCalled");
testSucceeded = 0;
assert(0); // We should not reach here
}

void asyncWaitFinishedShouldBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData)
{
void asyncWaitFinishedShouldBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData) {
emscripten_console_log("asyncWaitFinishedShouldBeCalled");
#ifdef REPORT_RESULT
REPORT_RESULT(testSucceeded);
#endif
}

int main()
{
int main() {
emscripten_console_log("Async waiting on address should give a wait token");
ATOMICS_WAIT_TOKEN_T ret = emscripten_atomic_wait_async((int32_t*)&addr, 1, asyncWaitFinishedShouldNotBeCalled, (void*)42, EMSCRIPTEN_WAIT_ASYNC_INFINITY);
assert(EMSCRIPTEN_IS_VALID_WAIT_TOKEN(ret));
Expand Down
9 changes: 3 additions & 6 deletions test/wasm_worker/cancel_wait_async.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,20 @@ volatile int32_t addr = 1;

bool testSucceeded = 1;

void asyncWaitFinishedShouldNotBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData)
{
void asyncWaitFinishedShouldNotBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData) {
emscripten_console_log("asyncWaitFinishedShouldNotBeCalled");
testSucceeded = 0;
assert(0); // We should not reach here
}

void asyncWaitFinishedShouldBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData)
{
void asyncWaitFinishedShouldBeCalled(int32_t *ptr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData) {
emscripten_console_log("asyncWaitFinishedShouldBeCalled");
#ifdef REPORT_RESULT
REPORT_RESULT(testSucceeded);
#endif
}

int main()
{
int main() {
emscripten_console_log("Async waiting on address should give a wait token");
ATOMICS_WAIT_TOKEN_T ret = emscripten_atomic_wait_async((int32_t*)&addr, 1, asyncWaitFinishedShouldNotBeCalled, (void*)42, EMSCRIPTEN_WAIT_ASYNC_INFINITY);
assert(EMSCRIPTEN_IS_VALID_WAIT_TOKEN(ret));
Expand Down
9 changes: 3 additions & 6 deletions test/wasm_worker/gcc___Thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@

__thread int tls = 1;

void main_thread_func()
{
void main_thread_func() {
assert(!emscripten_current_thread_is_wasm_worker());
EM_ASM(out($0), tls);
#ifdef REPORT_RESULT
REPORT_RESULT(tls);
#endif
}

void worker_main()
{
void worker_main() {
assert(emscripten_current_thread_is_wasm_worker());
assert(tls != 42);
assert(tls != 0);
Expand All @@ -26,8 +24,7 @@ void worker_main()

char stack[1024];

int main()
{
int main() {
EM_ASM(out($0), tls);
assert(!emscripten_current_thread_is_wasm_worker());
tls = 42;
Expand Down
9 changes: 3 additions & 6 deletions test/wasm_worker/hardware_concurrency_is_lock_free.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

// Test emscripten_navigator_hardware_concurrency() and emscripten_atomics_is_lock_free() functions

void test()
{
void test() {
// Assume that test suite does have navigator.hardwareConcurrency.
assert(emscripten_navigator_hardware_concurrency() >= 2);
assert(emscripten_atomics_is_lock_free(1));
Expand All @@ -17,8 +16,7 @@ void test()
assert(!emscripten_atomics_is_lock_free(31));
}

void worker_main()
{
void worker_main() {
test();
#ifdef REPORT_RESULT
REPORT_RESULT(0);
Expand All @@ -27,8 +25,7 @@ void worker_main()

char stack[1024];

int main()
{
int main() {
test();
emscripten_wasm_worker_t worker = emscripten_create_wasm_worker(stack, sizeof(stack));
emscripten_wasm_worker_post_function_v(worker, worker_main);
Expand Down
6 changes: 2 additions & 4 deletions test/wasm_worker/hello_wasm_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@

// This is the code example in site/source/docs/api_reference/wasm_workers.rst

void run_in_worker()
{
void run_in_worker() {
emscripten_console_log("Hello from wasm worker!\n");
#ifdef REPORT_RESULT
REPORT_RESULT(0);
#endif
}

int main()
{
int main() {
emscripten_wasm_worker_t worker = emscripten_malloc_wasm_worker(/*stack size: */1024);
assert(worker);
emscripten_wasm_worker_post_function_v(worker, run_in_worker);
Expand Down
52 changes: 21 additions & 31 deletions test/wasm_worker/lock_async_acquire.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,32 @@ bool testFinished = false;
int numTimesMainThreadAcquiredLock = 0;
int numTimesWasmWorkerAcquiredLock = 0;

void work()
{
// emscripten_console_log("work");
void work() {
// emscripten_console_log("work");
volatile int x = sharedState0;
volatile int y = sharedState1;
assert(x == y+1 || y == x+1);

if (emscripten_current_thread_is_wasm_worker())
if (emscripten_current_thread_is_wasm_worker()) {
++numTimesWasmWorkerAcquiredLock;
else
} else {
++numTimesMainThreadAcquiredLock;
}

if (x < y)
{
if (x < y) {
x = y + 1;
if (emscripten_current_thread_is_wasm_worker())
if (emscripten_current_thread_is_wasm_worker()) {
emscripten_wasm_worker_sleep(/*nsecs=*/(rand()%100000));
}
sharedState0 = x;
}
else
{
} else {
y = x + 1;
if (emscripten_current_thread_is_wasm_worker())
emscripten_wasm_worker_sleep(/*nsecs=*/(rand()%100000));
sharedState1 = y;

if (y > 100 && numTimesMainThreadAcquiredLock && numTimesWasmWorkerAcquiredLock)
{
if (!testFinished)
{
if (y > 100 && numTimesMainThreadAcquiredLock && numTimesWasmWorkerAcquiredLock) {
if (!testFinished) {
emscripten_console_log("test finished");
#ifdef REPORT_RESULT
REPORT_RESULT(0);
Expand All @@ -59,33 +55,29 @@ void work()

void schedule_work(void *userData);

void lock_async_acquired(volatile void *addr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData)
{
// emscripten_console_log("async lock acquired");
void lock_async_acquired(volatile void *addr, uint32_t val, ATOMICS_WAIT_RESULT_T waitResult, void *userData) {
// emscripten_console_log("async lock acquired");
assert(addr == &lock);
assert(val == 0 || val == 1);
assert(waitResult == ATOMICS_WAIT_OK);
assert(userData == (void*)42);
work();
emscripten_lock_release(&lock);

if (!testFinished)
if (!testFinished) {
emscripten_set_timeout(schedule_work, 10, 0);
}
}

void schedule_work(void *userData)
{
if (emscripten_current_thread_is_wasm_worker() && emscripten_random() > 0.5)
{
void schedule_work(void *userData) {
if (emscripten_current_thread_is_wasm_worker() && emscripten_random() > 0.5) {
emscripten_lock_waitinf_acquire(&lock);
// emscripten_console_log("sync lock acquired");
// emscripten_console_log("sync lock acquired");
work();
emscripten_lock_release(&lock);
if (!testFinished)
emscripten_set_timeout(schedule_work, 0, 0);
}
else
{
} else {
emscripten_lock_async_acquire(&lock, lock_async_acquired, (void*)42, EMSCRIPTEN_WAIT_ASYNC_INFINITY);
}
}
Expand All @@ -94,11 +86,9 @@ void start_worker(int arg) {
schedule_work(0);
}

int main()
{
int main() {
#define NUM_THREADS 10
for(int i = 0; i < NUM_THREADS; ++i)
{
for (int i = 0; i < NUM_THREADS; ++i) {
emscripten_wasm_worker_t worker = emscripten_malloc_wasm_worker(1024);
emscripten_wasm_worker_post_function_vi(worker, start_worker, 0);
}
Expand Down
27 changes: 16 additions & 11 deletions test/wasm_worker/lock_busyspin_wait_acquire.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,37 @@

emscripten_lock_t lock = EMSCRIPTEN_LOCK_T_STATIC_INITIALIZER;

void test()
{
bool success = emscripten_lock_busyspin_wait_acquire(&lock, 0); // Expect no contention on free lock.
void test() {
// Expect no contention on free lock.
bool success = emscripten_lock_busyspin_wait_acquire(&lock, 0);
assert(success == true);

double t0 = emscripten_performance_now();
success = emscripten_lock_busyspin_wait_acquire(&lock, 0); // We already have the lock, and emscripten_lock is not recursive, so this should fail.
// We already have the lock, and emscripten_lock is not recursive, so this
// should fail.
success = emscripten_lock_busyspin_wait_acquire(&lock, 0);
double t1 = emscripten_performance_now();
assert(!success);
assert(t1 - t0 < 25); // Shouldn't have taken too much time to try the lock.
// Shouldn't have taken too much time to try the lock.
assert(t1 - t0 < 25);

success = emscripten_lock_try_acquire(&lock);
assert(!success); // We already have the lock.

t0 = emscripten_performance_now();
success = emscripten_lock_busyspin_wait_acquire(&lock, 1000.0); // We already have the lock, and emscripten_lock is not recursive, so this should fail.
// We already have the lock, and emscripten_lock is not recursive, so this
// should fail.
success = emscripten_lock_busyspin_wait_acquire(&lock, 1000.0);
t1 = emscripten_performance_now();
assert(!success);
assert(t1 - t0 >= 900); // We should have waited for the requested duration for the lock.. apply some slack since timing can have some noise.
// We should have waited for the requested duration for the lock.. apply some
// slack since timing can have some noise.
assert(t1 - t0 >= 900);

emscripten_lock_release(&lock);
}

void worker_main()
{
void worker_main() {
test();
#ifdef REPORT_RESULT
REPORT_RESULT(0);
Expand All @@ -41,8 +47,7 @@ void worker_main()

char stack[1024];

int main()
{
int main() {
test();

emscripten_wasm_worker_t worker = emscripten_create_wasm_worker(stack, sizeof(stack));
Expand Down
9 changes: 3 additions & 6 deletions test/wasm_worker/lock_busyspin_waitinf_acquire.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ emscripten_lock_t lock = EMSCRIPTEN_LOCK_T_STATIC_INITIALIZER;

volatile int sharedState = 0;

void worker_main()
{
void worker_main() {
emscripten_lock_busyspin_waitinf_acquire(&lock);
emscripten_atomic_add_u32((void*)&sharedState, 1);
#ifdef REPORT_RESULT
Expand All @@ -21,14 +20,12 @@ void worker_main()

char stack[1024];

void releaseLock(void *userData)
{
void releaseLock(void *userData) {
emscripten_atomic_sub_u32((void*)&sharedState, 1);
emscripten_lock_release(&lock);
}

int main()
{
int main() {
// Acquire the lock at startup.
emscripten_lock_busyspin_waitinf_acquire(&lock);
emscripten_atomic_add_u32((void*)&sharedState, 1);
Expand Down
Loading
Loading