aboutsummaryrefslogtreecommitdiff
path: root/core/sync/sync2/primitives.odin
blob: d0a4439d225d2cc75558cbe8ece9207cbbbf5fbc (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
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package sync2

import "core:time"

current_thread_id :: proc "contextless" () -> int {
	return _current_thread_id();
}

// A Mutex is a mutual exclusion lock
// The zero value for a Mutex is an unlocked mutex
//
// A Mutex must not be copied after first use
Mutex :: struct {
	impl: _Mutex,
}

// mutex_lock locks m
mutex_lock :: proc(m: ^Mutex) {
	_mutex_lock(m);
}

// mutex_unlock unlocks m
mutex_unlock :: proc(m: ^Mutex) {
	_mutex_unlock(m);
}

// mutex_lock tries to lock m, will return true on success, and false on failure
mutex_try_lock :: proc(m: ^Mutex) -> bool {
	return _mutex_try_lock(m);
}

// Example:
//
// if mutex_guard(&m) {
//         ...
// }
//
@(deferred_in=mutex_unlock)
mutex_guard :: proc(m: ^Mutex) -> bool {
	mutex_lock(m);
	return true;
}

// A RW_Mutex is a reader/writer mutual exclusion lock
// The lock can be held by any arbitrary number of readers or a single writer
// The zero value for a RW_Mutex is an unlocked mutex
//
// A RW_Mutex must not be copied after first use
RW_Mutex :: struct {
	impl: _RW_Mutex,
}

// rw_mutex_lock locks rw for writing (with a single writer)
// If the mutex is already locked for reading or writing, the mutex blocks until the mutex is available.
rw_mutex_lock :: proc(rw: ^RW_Mutex) {
	_rw_mutex_lock(rw);
}

// rw_mutex_unlock unlocks rw for writing (with a single writer)
rw_mutex_unlock :: proc(rw: ^RW_Mutex) {
	_rw_mutex_unlock(rw);
}

// rw_mutex_try_lock tries to lock rw for writing (with a single writer)
rw_mutex_try_lock :: proc(rw: ^RW_Mutex) -> bool {
	return _rw_mutex_try_lock(rw);
}

// rw_mutex_shared_lock locks rw for reading (with arbitrary number of readers)
rw_mutex_shared_lock :: proc(rw: ^RW_Mutex) {
	_rw_mutex_shared_lock(rw);
}

// rw_mutex_shared_unlock unlocks rw for reading (with arbitrary number of readers)
rw_mutex_shared_unlock :: proc(rw: ^RW_Mutex) {
	_rw_mutex_shared_unlock(rw);
}

// rw_mutex_try_shared_lock tries to lock rw for reading (with arbitrary number of readers)
rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool {
	return _rw_mutex_try_shared_lock(rw);
}

// Example:
//
// if rw_mutex_guard(&m) {
//         ...
// }
//
@(deferred_in=rw_mutex_unlock)
rw_mutex_guard :: proc(m: ^RW_Mutex) -> bool {
	rw_mutex_lock(m);
	return true;
}

// Example:
//
// if rw_mutex_shared_guard(&m) {
//         ...
// }
//
@(deferred_in=rw_mutex_shared_unlock)
rw_mutex_shared_guard :: proc(m: ^RW_Mutex) -> bool {
	rw_mutex_shared_lock(m);
	return true;
}



// A Recursive_Mutex is a recursive mutual exclusion lock
// The zero value for a Recursive_Mutex is an unlocked mutex
//
// A Recursive_Mutex must not be copied after first use
Recursive_Mutex :: struct {
	impl: _Recursive_Mutex,
}

recursive_mutex_lock :: proc(m: ^Recursive_Mutex) {
	_recursive_mutex_lock(m);
}

recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) {
	_recursive_mutex_unlock(m);
}

recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool {
	return _recursive_mutex_try_lock(m);
}


// Example:
//
// if recursive_mutex_guard(&m) {
//         ...
// }
//
@(deferred_in=recursive_mutex_unlock)
recursive_mutex_guard :: proc(m: ^Recursive_Mutex) -> bool {
	recursive_mutex_lock(m);
	return true;
}


// Cond implements a condition variable, a rendezvous point for threads
// waiting for signalling the occurence of an event
//
// A Cond must not be copied after first use
Cond :: struct {
	impl: _Cond,
}

cond_wait :: proc(c: ^Cond, m: ^Mutex) {
	_cond_wait(c, m);
}

cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, timeout: time.Duration) -> bool {
	return _cond_wait_with_timeout(c, m, timeout);
}

cond_signal :: proc(c: ^Cond) {
	_cond_signal(c);
}

cond_broadcast :: proc(c: ^Cond) {
	_cond_broadcast(c);
}



// When waited upon, blocks until the internal count is greater than zero, then subtracts one.
// Posting to the semaphore increases the count by one, or the provided amount.
//
// A Sema must not be copied after first use
Sema :: struct {
	impl: _Sema,
}


sema_wait :: proc(s: ^Sema) {
	_sema_wait(s);
}

sema_post :: proc(s: ^Sema, count := 1) {
	_sema_post(s, count);
}