File: test_futex_wake_all.cpp

package info (click to toggle)
emscripten 3.1.6~dfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 114,112 kB
  • sloc: ansic: 583,052; cpp: 391,943; javascript: 79,361; python: 54,180; sh: 49,997; pascal: 4,658; makefile: 3,426; asm: 2,191; lisp: 1,869; ruby: 488; cs: 142
file content (65 lines) | stat: -rw-r--r-- 1,579 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
// 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 <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <emscripten/threading.h>
#include <emscripten/emscripten.h>
#include <assert.h>
#include <math.h>
#include <limits.h>

#define NUM_THREADS 8

unsigned int futexVal = 0;

unsigned int numAwoken = 0;

pthread_t wakingThread;

pthread_t waitingThreads[NUM_THREADS];

void *WakingThread(void *arg)
{
	// Wake all threads waiting for the futex address
	emscripten_atomic_store_u32(&futexVal, 1);
	emscripten_futex_wake(&futexVal, INT_MAX);

	pthread_exit(0);
}

void *WaitingThread(void *arg)
{
	// Last waiting thread creates the waking thread - this simplifies mutual synchronization needs
	if ((long)arg == NUM_THREADS-1)
	{
		pthread_create(&wakingThread, 0, WakingThread, 0);
	}

	// Each waiting thread waits until wake thread changes the value at the wait address
	while(emscripten_atomic_load_u32(&futexVal) == 0)
	{
		emscripten_futex_wait(&futexVal, 0, INFINITY);
	}

	// Tally up the number of awoken threads - last one to wake up signals test success
	uint32_t old = emscripten_atomic_add_u32(&numAwoken, 1);
	if (old + 1 == NUM_THREADS)
	{
		emscripten_force_exit(0);
	}

	return 0;
}

int main()
{
	for(int i = 0; i < NUM_THREADS; ++i)
	{
		pthread_create(waitingThreads+i, 0, WaitingThread, (void*)i);
	}
	emscripten_exit_with_live_runtime();
}