File: test_pthread_run_on_main_thread_flood.cpp

package info (click to toggle)
emscripten 2.0.12~dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 108,440 kB
  • sloc: ansic: 510,324; cpp: 384,763; javascript: 84,341; python: 51,362; sh: 50,019; pascal: 4,159; makefile: 3,409; asm: 2,150; lisp: 1,869; ruby: 488; cs: 142
file content (103 lines) | stat: -rw-r--r-- 2,536 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright 2016 The Emscripten Authors.  All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License.  Both these licenses can be
// found in the LICENSE file.

#include <emscripten/threading.h>
#include <stdio.h>
#include <assert.h>
#include <math.h>

volatile int func_called = 0;

void v()
{
	emscripten_atomic_add_u32((void*)&func_called, 1);
}

void test_sync()
{
	printf("Testing sync proxied runs:\n");
	emscripten_atomic_store_u32((void*)&func_called, 0);
	for(int i = 0; i < 1000; ++i)
	{
		emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_V, v);
		assert(emscripten_atomic_load_u32((void*)&func_called) == i+1);
	}
}

void test_async()
{
	printf("Testing async proxied runs:\n");
	emscripten_atomic_store_u32((void*)&func_called, 0);
	for(int i = 0; i < 1000; ++i)
	{
		emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_V, v);
	}

	while(emscripten_atomic_load_u32((void*)&func_called) != 1000)
		;
}

void test_async_waitable()
{
	printf("Testing waitable async proxied runs:\n");
	emscripten_atomic_store_u32((void*)&func_called, 0);
	em_queued_call* handles[1000];

	for(int i = 0; i < 1000; ++i)
	{
		handles[i] = emscripten_async_waitable_run_in_main_runtime_thread(EM_FUNC_SIG_V, v);
	}

	EMSCRIPTEN_RESULT r = emscripten_wait_for_call_v(handles[999], INFINITY);
	assert(r == EMSCRIPTEN_RESULT_SUCCESS);

	// Since ordering is guaranteed we know that all the other tasks must
	// also have already been completed.
	int final_count = emscripten_atomic_load_u32((void*)&func_called);
	printf("final_count: %d\n", final_count);
	assert(final_count == 1000);

	// Cleanup/free all the handles.  Waiting on the 1000th a second time is
	// allowed by the API.
	for(int i = 0; i < 1000; ++i)
	{
		EMSCRIPTEN_RESULT r = emscripten_wait_for_call_v(handles[i], INFINITY);
		assert(r == EMSCRIPTEN_RESULT_SUCCESS);
		emscripten_async_waitable_close(handles[i]);
	}
}

void *thread_main(void*)
{
	test_sync();
	test_async();
	test_async_waitable();
	printf("thread_main done\n");
	pthread_exit(NULL);
}

int main()
{
	if (emscripten_has_threading_support())
	{
		test_sync();
		test_async_waitable();

		pthread_t thread;
		int rc = pthread_create(&thread, NULL, thread_main, NULL);
		assert(rc == 0);
		void* retval;
		rc = pthread_join(thread, &retval);
		assert(rc == 0);
		printf("pthread_join done: %ld\n", (intptr_t)retval);
		assert(retval == NULL);
	}

	test_async();

#ifdef REPORT_RESULT
	REPORT_RESULT(0);
#endif
}