-
Notifications
You must be signed in to change notification settings - Fork 0
/
mutex.c
63 lines (50 loc) · 1.65 KB
/
mutex.c
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
// SPDX-License-Identifier: MIT
#include "mutex.h"
#include "reactor-internal.h"
#include "jump_queue.h"
#include "todo_sigjmp.h"
#include <assert.h>
bool
iou_mutex_taken(reactor_t * reactor, const iou_mutex_t * mutex) {
assert(!mutex->owner || mutex->depth);
return mutex->owner;
}
bool
iou_mutex_probe(reactor_t * reactor, iou_mutex_t * mutex) {
assert(!mutex->owner || mutex->depth);
fiber_t * whoami = reactor->current ?: (fiber_t*)reactor;
if (!mutex->owner)
mutex->owner = whoami;
return mutex->owner == whoami && ++mutex->depth;
}
void
iou_mutex_enter(reactor_t * reactor, iou_mutex_t * mutex) {
assert(!mutex->owner || mutex->depth);
fiber_t * whoami = reactor->current ?: (fiber_t*)reactor;
while (!iou_mutex_probe(reactor, mutex)) {
todo_sigjmp_t todo;
if (!sigsetjmp(*make_todo_sigjmp(&todo, reactor->current), false)) {
jump_queue_enqueue((jump_queue_t*)&mutex->waiters, &todo.jump);
reactor_enter_core(reactor);
}
}
assert(mutex->owner == whoami);
}
bool
iou_mutex_owner(reactor_t * reactor, const iou_mutex_t * mutex) {
assert(!mutex->owner || mutex->depth);
fiber_t * whoami = reactor->current ?: (fiber_t*)reactor;
return mutex->owner == whoami;
}
void
iou_mutex_leave(reactor_t * reactor, iou_mutex_t * mutex) {
assert(mutex->depth);
fiber_t * whoami = reactor->current ?: (fiber_t*)reactor;
assert(mutex->owner == whoami);
if (--mutex->depth)
return;
mutex->owner = NULL;
if (!jump_queue_empty((jump_queue_t*)&mutex->waiters))
reactor_schedule(reactor, jump_queue_dequeue((jump_queue_t*)&mutex->waiters));
}
//