1#include <stdbool.h>
2#include <sync/spinlock.h>
3#include <thread/queue.h>
4#pragma once
5
6struct mutex_simple {
7 struct thread *owner;
8 struct thread_queue waiters;
9 struct spinlock lock;
10};
11
12void mutex_simple_init(struct mutex_simple *m);
13void mutex_simple_lock(struct mutex_simple *m);
14void mutex_simple_unlock(struct mutex_simple *m);
15
16/* mutex: pointer sized mutex
17 *
18 * ┌─────────────────────────┐
19 * Bits │ .... .... .... 3..0 │
20 * Use │ %%%% %%%% %%%% %rrh │
21 * └─────────────────────────┘
22 *
23 * h - "held" - is the lock held?
24 *
25 * r - reserved for future use
26 *
27 * %%%% - pointer to owner thread
28 *
29 */
30
31#define MUTEX_INIT {ATOMIC_VAR_INIT(0)}
32struct mutex {
33 _Atomic(uintptr_t) lock_word;
34};
35
36void mutex_init(struct mutex *mtx);
37void mutex_unlock(struct mutex *mutex);
38void mutex_lock(struct mutex *mutex);
39bool mutex_held(struct mutex *mtx);
40struct thread *mutex_get_owner(struct mutex *mtx);
41
42#define MUTEX_ASSERT_HELD(m) kassert(mutex_held(m))
43