void *ThreadMain(void *arg) { for(int i = 0; i < 10; ++i) { char str[256]; sprintf(str, "file%d.txt", i); printf("Writing file %s..\n", str); // Prints out to page console, this is a proxied operation. FILE *handle = fopen(str, "w"); // fopen, fputs and fclose are currently proxied operations too (although hopefully not in the future) fputs(str, handle); fclose(handle); } emscripten_atomic_store_u32(&main_thread_wait_val, 0); emscripten_futex_wake(&main_thread_wait_val, 1); emscripten_atomic_store_u32(&result, 0); pthread_exit(0); }
static inline void unlock_requeue(volatile int *l, volatile int *r, int w) { a_store(l, 0); #ifdef __EMSCRIPTEN__ // Here the intent is to wake one waiter, and requeue all other waiters from waiting on address 'l' // to wait on address 'r' instead. This is not possible at the moment with SharedArrayBuffer Atomics, // as it does not have a "wake X waiters and requeue the rest" primitive. However this kind of // primitive is strictly not needed, since it is more like an optimization to avoid spuriously waking // all waiters, just to make them wait on another location immediately afterwards. Here we do exactly // that: wake every waiter. emscripten_futex_wake(l, 0x7FFFFFFF); #else if (w) __wake(l, 1, 1); else __syscall(SYS_futex, l, FUTEX_REQUEUE|128, 0, 1, r) != -ENOSYS || __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r); #endif }
void *mandelbrot_thread(void *arg) { int idx = (int)arg; for(;;) { emscripten_futex_wait(&tasksPending[idx], 0, INFINITY); emscripten_atomic_store_u32(&tasksPending[idx], 0); double t0 = emscripten_get_now(); int ni; if (use_sse) ni = ComputeMandelbrot_SSE(mandelReal, mandelImag, outputImage, sizeof(float)*W, sizeof(uint32_t)*W, 0, idx, numTasks, W, H, left, top, incrX, incrY, numItersDoneOnCanvas, numItersPerFrame); else ni = ComputeMandelbrot(mandelReal, mandelImag, outputImage, sizeof(float)*W, sizeof(uint32_t)*W, 0, idx, numTasks, W, H, left, top, incrX, incrY, numItersDoneOnCanvas, numItersPerFrame); //emscripten_atomic_add_u32(&numIters, ni); double t1 = emscripten_get_now(); numIters[idx] += ni; timeSpentInMandelbrot[idx] += t1-t0; emscripten_atomic_add_u32(&tasksDone, 1); emscripten_futex_wake(&tasksDone, 9999); } }