blob: 477bce9c227cd0429a28f48a649de0610c1e75dc (
plain)
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
|
package sync
import "intrinsics"
Wait_Group :: struct {
counter: int,
mutex: Blocking_Mutex,
cond: Condition,
}
wait_group_init :: proc(wg: ^Wait_Group) {
wg.counter = 0;
blocking_mutex_init(&wg.mutex);
condition_init(&wg.cond, &wg.mutex);
}
wait_group_destroy :: proc(wg: ^Wait_Group) {
condition_destroy(&wg.cond);
blocking_mutex_destroy(&wg.mutex);
}
wait_group_add :: proc(wg: ^Wait_Group, delta: int) {
if delta == 0 {
return;
}
blocking_mutex_lock(&wg.mutex);
defer blocking_mutex_unlock(&wg.mutex);
intrinsics.atomic_add(&wg.counter, delta);
if wg.counter < 0 {
panic("sync.Wait_Group negative counter");
}
if wg.counter == 0 {
condition_broadcast(&wg.cond);
if wg.counter != 0 {
panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait");
}
}
}
wait_group_done :: proc(wg: ^Wait_Group) {
wait_group_add(wg, -1);
}
wait_group_wait :: proc(wg: ^Wait_Group) {
blocking_mutex_lock(&wg.mutex);
defer blocking_mutex_unlock(&wg.mutex);
if wg.counter != 0 {
condition_wait_for(&wg.cond);
if wg.counter != 0 {
panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait");
}
}
}
|