text: #include <emscripten/threading.h>
  #include <stdio.h>
  #include <assert.h>
  #include <math.h>
  
  int v_called = 0;
  void v()
  {
  	assert(emscripten_is_main_runtime_thread());
  	printf("Hello!\n");
  	v_called = 1;
  }
  
  int vi_called = 0;
  void vi(int param0)
  {
  	assert(emscripten_is_main_runtime_thread());
  	printf("Hello %d!\n", param0);
  	vi_called = 1;
  }
  
  int vii_called = 0;
  void vii(int param0, int param1)
  {
  	assert(emscripten_is_main_runtime_thread());
  	printf("Hello %d %d!\n", param0, param1);
  	vii_called = 1;
  }
  
  int viii_called = 0;
  void viii(int param0, int param1, int param2)
  {
  	assert(emscripten_is_main_runtime_thread());
  	printf("Hello %d %d %d!\n", param0, param1, param2);
  	viii_called = 1;
  }
  
  int i_called = 0;
  int i()
  {
  	assert(emscripten_is_main_runtime_thread());
  	printf("Hello i!\n");
  	i_called = 1;
  	return 84;
  }
  
  int ii_called = 0;
  int ii(int param0)
  {
  	assert(emscripten_is_main_runtime_thread());
  	printf("Hello ii %d!\n", param0);
  	ii_called = 1;
  	return 85;
  }
  
  int iii_called = 0;
  int iii(int param0, int param1)
  {
  	assert(emscripten_is_main_runtime_thread());
  	printf("Hello iii %d %d!\n", param0, param1);
  	iii_called = 1;
  	return 86;
  }
  
  int iiii_called = 0;
  int iiii(int param0, int param1, int param2)
  {
  	assert(emscripten_is_main_runtime_thread());
  	printf("Hello iiii %d %d %d!\n", param0, param1, param2);
  	iiii_called = 1;
  	return 87;
  }
  
  void test_sync()
  {
  	printf("Testing sync proxied runs:\n");
  	int ret;
  	v_called = 0; emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_V, v); assert(v_called == 1);
  	vi_called = 0; emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VI, vi, 42); assert(vi_called == 1);
  	vii_called = 0; emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VII, vii, 42, 43); assert(vii_called == 1);
  	viii_called = 0; emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_VIII, viii, 42, 43, 44); assert(viii_called == 1);
  	i_called = 0; ret = emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_I, i); assert(i_called == 1); assert(ret == 84);
  	ii_called = 0; ret = emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_II, ii, 42); assert(ii_called == 1); assert(ret == 85);
  	iii_called = 0; ret = emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_III, iii, 42, 43); assert(iii_called == 1); assert(ret == 86);
  	iiii_called = 0; ret = emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_IIII, iiii, 42, 43, 44); assert(iiii_called == 1); assert(ret == 87);
  }
  
  void test_async()
  {
  	printf("Testing async proxied runs:\n");
  	emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_V, v);
  	emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_VI, vi, 42);
  	emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_VII, vii, 42, 43);
  	emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_VIII, viii, 42, 43, 44);
  	emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_I, i);
  	emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_II, ii, 42);
  	emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_III, iii, 42, 43);
  	emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_IIII, iiii, 42, 43, 44);
  }
  
  void test_async_waitable()
  {
  	printf("Testing waitable async proxied runs:\n");
  	em_queued_call *c1 = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_V, v);
  	em_queued_call *c2 = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_VI, vi, 42);
  	em_queued_call *c3 = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_VII, vii, 42, 43);
  	em_queued_call *c4 = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_VIII, viii, 42, 43, 44);
  	em_queued_call *c5 = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_I, i);
  	em_queued_call *c6 = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_II, ii, 42);
  	em_queued_call *c7 = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_III, iii, 42, 43);
  	em_queued_call *c8 = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_IIII, iiii, 42, 43, 44);
  	EMSCRIPTEN_RESULT r = emscripten_wait_for_call_v(c1, INFINITY); assert(r == EMSCRIPTEN_RESULT_SUCCESS);
  	r = emscripten_wait_for_call_v(c2, INFINITY); assert(r == EMSCRIPTEN_RESULT_SUCCESS);
  	r = emscripten_wait_for_call_v(c3, INFINITY); assert(r == EMSCRIPTEN_RESULT_SUCCESS);
  	r = emscripten_wait_for_call_v(c4, INFINITY); assert(r == EMSCRIPTEN_RESULT_SUCCESS);
  	int r1; r = emscripten_wait_for_call_i(c5, INFINITY, &r1); assert(r1 == 84); assert(r == EMSCRIPTEN_RESULT_SUCCESS);
  	int r2; r = emscripten_wait_for_call_i(c6, INFINITY, &r2); assert(r2 == 85); assert(r == EMSCRIPTEN_RESULT_SUCCESS);
  	int r3; r = emscripten_wait_for_call_i(c7, INFINITY, &r3); assert(r3 == 86); assert(r == EMSCRIPTEN_RESULT_SUCCESS);
  	int r4; r = emscripten_wait_for_call_i(c8, INFINITY, &r4); assert(r4 == 87); assert(r == EMSCRIPTEN_RESULT_SUCCESS);
  	emscripten_async_waitable_close(c1);
  	emscripten_async_waitable_close(c2);
  	emscripten_async_waitable_close(c3);
  	emscripten_async_waitable_close(c4);
  	emscripten_async_waitable_close(c5);
  	emscripten_async_waitable_close(c6);
  	emscripten_async_waitable_close(c7);
  	emscripten_async_waitable_close(c8);
  }
  
  void *thread_main(void*)
  {
  	test_sync();
  	test_async();
  	test_async_waitable();
  	pthread_exit(0);
  }
  
  int main()
  {
  	if (emscripten_has_threading_support())
  	{
  		test_sync();
  		test_async_waitable();
  
  		pthread_attr_t attr;
  		pthread_attr_init(&attr);
  		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  		pthread_t thread;
  		int rc = pthread_create(&thread, &attr, thread_main, 0);
  		assert(rc == 0);
  		rc = pthread_join(thread, 0);
  		assert(rc == 0);
  	}
  
  	test_async();
  
  #ifdef REPORT_RESULT
  	int result = 0;
  	REPORT_RESULT();
  #endif
  }
  