Пример #1
0
int main()
{
  sharedVar = 0;
  int s = pthread_create(&thr, NULL, thread_start, 0);
  assert(s == 0);

  // Wait until thread kicks in and sets the shared variable.
  while(sharedVar == 0)
    BusySleep(10);

  s = pthread_kill(thr, SIGKILL);
  assert(s == 0);

  // Wait until we see the shared variable stop incrementing. (This is a bit heuristic and hacky)
  for(;;)
  {
    int val = emscripten_atomic_load_u32((void*)&sharedVar);
    BusySleep(100);
    int val2 = emscripten_atomic_load_u32((void*)&sharedVar);
    if (val == val2) break;
  }

  // Reset to 0.
  sharedVar = 0;
  emscripten_atomic_store_u32((void*)&sharedVar, 0);

  // Wait for a long time, if the thread is still running, it should progress and set sharedVar by this time.
  BusySleep(3000);

  // Finally test that the thread is not doing any work and it is dead.
  assert(sharedVar == 0);
  assert(emscripten_atomic_load_u32((void*)&sharedVar) == 0);
  EM_ASM_INT( { Module['print']('Main: Done. Successfully killed thread. sharedVar: '+$0+'.'); }, sharedVar);
EMSCRIPTEN_RESULT emscripten_fetch_wait(emscripten_fetch_t *fetch, double timeoutMsecs)
{
#if __EMSCRIPTEN_PTHREADS__
	if (!fetch) return EMSCRIPTEN_RESULT_INVALID_PARAM;
	uint32_t proxyState = emscripten_atomic_load_u32(&fetch->__proxyState);
	if (proxyState == 2) return EMSCRIPTEN_RESULT_SUCCESS; // already finished.
	if (proxyState != 1) return EMSCRIPTEN_RESULT_INVALID_PARAM; // the fetch should be ongoing?
// #ifdef FETCH_DEBUG
	EM_ASM({ console.log('fetch: emscripten_fetch_wait..') });
// #endif
	// TODO: timeoutMsecs is currently ignored. Return EMSCRIPTEN_RESULT_TIMED_OUT on timeout.
	while(proxyState == 1/*sent to proxy worker*/)
	{
		emscripten_futex_wait(&fetch->__proxyState, proxyState, 100 /*TODO HACK:Sleep sometimes doesn't wake up?*/);//timeoutMsecs);
		proxyState = emscripten_atomic_load_u32(&fetch->__proxyState);
	}
// #ifdef FETCH_DEBUG
	EM_ASM({ console.log('fetch: emscripten_fetch_wait done..') });
// #endif

	if (proxyState == 2) return EMSCRIPTEN_RESULT_SUCCESS;
	else return EMSCRIPTEN_RESULT_FAILED;
#else
	EM_ASM({ console.error('fetch: emscripten_fetch_wait is not available when building without pthreads!') });
	return EMSCRIPTEN_RESULT_FAILED;
#endif
}
// TEMP to make this test pass:
// Our Clang backend doesn't define this builtin function, so implement it ourselves.
// The current Atomics spec doesn't have the nand atomic op either, so must use a cas loop.
// TODO: Move this to Clang backend?
T __sync_nand_and_fetch(T *ptr, T x)
{
	for(;;)
	{
		T old = emscripten_atomic_load_u32(ptr);
		T newVal = ~(old & x);
		T old2 = emscripten_atomic_cas_u32(ptr, old, newVal);
		if (old2 == old) return old;
	}
}
Пример #4
0
// Test __sync_bool_compare_and_swap.
T nand_and_fetch_bool(T *ptr, T x)
{
	for(;;)
	{
		T old = emscripten_atomic_load_u32(ptr);
		T newVal = ~(old & x);
		Bool success = __sync_bool_compare_and_swap(ptr, old, newVal);
		if (success) return newVal;
	}
}
Пример #5
0
// Test __sync_val_compare_and_swap.
T nand_and_fetch(T *ptr, T x)
{
	for(;;)
	{
		T old = emscripten_atomic_load_u32(ptr);
		T newVal = ~(old & x);
		T old2 = __sync_val_compare_and_swap(ptr, old, newVal);
		if (old2 == old) return newVal;
	}
}
void PollThreadExit(void *)
{
  if (!emscripten_atomic_load_u32(&threadRunning))
  {
    EmscriptenWebGLContextAttributes attr;
    emscripten_webgl_init_context_attributes(&attr);
#ifdef TEST_MAIN_THREAD_EXPLICIT_COMMIT
    attr.explicitSwapControl = EM_TRUE;
#endif
    ctx = emscripten_webgl_create_context(0, &attr);
    emscripten_webgl_make_context_current(ctx);
    printf("Main thread rendering. You should see the WebGL canvas fade from black to green.\n");
    emscripten_set_main_loop(MainThreadRender, 0, 0);
  }
  else
  {
    emscripten_async_call(PollThreadExit, 0, 1000);
  }
}
Пример #7
0
int main()
{
  int result;
  if (!emscripten_has_threading_support())
  {
#ifdef REPORT_RESULT
    result = 1;
    REPORT_RESULT();
#endif
    printf("Skipped: Threading is not supported.\n");
    return 0;
  }

  pthread_t thr;
  int rc = pthread_create(&thr, NULL, thread_start, (void*)0);
  if (rc != 0)
  {
#ifdef REPORT_RESULT
    int result = (rc != EAGAIN);
    REPORT_RESULT();
    return 0;
#endif
  }

#ifdef USE_C_VOLATILE
  while(sharedVar == 0)
    ;
#else
  while(emscripten_atomic_load_u32((void*)&sharedVar) == 0) {}
#endif

#ifdef REPORT_RESULT
  result = sharedVar;
  REPORT_RESULT();
#endif
}