PatchworkOS
Loading...
Searching...
No Matches
mutex.c
Go to the documentation of this file.
1#include <kernel/sync/mutex.h>
2
3#include <kernel/config.h>
7#include <kernel/sched/wait.h>
8#include <kernel/sync/lock.h>
9
10#include <assert.h>
11
13{
15 mtx->owner = NULL;
16 mtx->depth = 0;
17 lock_init(&mtx->lock);
18}
19
21{
22 assert(mtx->owner == NULL);
24}
25
27{
28 bool isAcquired = mutex_acquire_timeout(mtx, CLOCKS_NEVER);
29 assert(isAcquired);
30 (void)isAcquired;
31}
32
34{
35 assert(mtx != NULL);
36 thread_t* self = sched_thread();
37 assert(self != NULL);
38
39 if (mtx->owner == self)
40 {
41 mtx->depth++;
42 return true;
43 }
44
45 uint64_t spin = 0;
46 while (spin < CONFIG_MUTEX_MAX_SLOW_SPIN)
47 {
48 lock_acquire(&mtx->lock);
49 if (mtx->owner == NULL)
50 {
51 mtx->owner = self;
52 mtx->depth = 1;
53 lock_release(&mtx->lock);
54 return true;
55 }
56 lock_release(&mtx->lock);
57 spin++;
58 }
59
60 if (timeout == 0)
61 {
62 return false;
63 }
64
65 if (timeout == CLOCKS_NEVER)
66 {
67 lock_acquire(&mtx->lock);
68 while (WAIT_BLOCK_LOCK(&mtx->waitQueue, &mtx->lock, mtx->owner == NULL) == ERR)
69 {
70 }
71
72 mtx->owner = self;
73 mtx->depth = 1;
74 lock_release(&mtx->lock);
75 return true;
76 }
77
78 lock_acquire(&mtx->lock);
79 clock_t end = timer_uptime() + timeout;
80 while (true)
81 {
82 clock_t now = timer_uptime();
83 if (now >= end)
84 {
85 lock_release(&mtx->lock);
86 return false;
87 }
88
89 clock_t waitTime = end - now;
90 if (WAIT_BLOCK_LOCK_TIMEOUT(&mtx->waitQueue, &mtx->lock, mtx->owner == NULL, waitTime) == ERR)
91 {
92 lock_release(&mtx->lock);
93 return false;
94 }
95
96 mtx->owner = self;
97 mtx->depth = 1;
98 lock_release(&mtx->lock);
99 return true;
100 }
101}
102
104{
105 assert(mtx != NULL);
106 LOCK_SCOPE(&mtx->lock);
107
109
110 mtx->depth--;
111 if (mtx->depth == 0)
112 {
113 mtx->owner = NULL;
114 wait_unblock(&mtx->waitQueue, 1, EOK);
115 }
116}
#define assert(expression)
Definition assert.h:29
#define CLOCKS_NEVER
Definition clock_t.h:16
#define WAIT_BLOCK_LOCK_TIMEOUT(waitQueue, lock, condition, timeout)
Block with a spinlock and timeout.
Definition wait.h:132
uint64_t wait_unblock(wait_queue_t *waitQueue, uint64_t amount, errno_t err)
Unblock threads waiting on a wait queue.
Definition wait.c:168
void wait_queue_init(wait_queue_t *waitQueue)
Initialize wait queue.
Definition wait.c:71
#define WAIT_BLOCK_LOCK(waitQueue, lock, condition)
Block with a spinlock.
Definition wait.h:101
void wait_queue_deinit(wait_queue_t *waitQueue)
Deinitialize wait queue.
Definition wait.c:77
thread_t * sched_thread(void)
Retrieves the currently running thread.
Definition sched.c:157
thread_t * sched_thread_unsafe(void)
Retrieves the currently running thread without disabling interrupts.
Definition sched.c:175
static void lock_init(lock_t *lock)
Initializes a lock.
Definition lock.h:80
#define LOCK_SCOPE(lock)
Acquires a lock for the reminder of the current scope.
Definition lock.h:57
static void lock_release(lock_t *lock)
Releases a lock.
Definition lock.h:140
static void lock_acquire(lock_t *lock)
Acquires a lock, blocking until it is available.
Definition lock.h:97
bool mutex_acquire_timeout(mutex_t *mtx, clock_t timeout)
Acquires a mutex, blocking until it is available or the timeout is reached.
Definition mutex.c:33
void mutex_release(mutex_t *mtx)
Releases a mutex.
Definition mutex.c:103
void mutex_acquire(mutex_t *mtx)
Acquires a mutex, blocking until it is available.
Definition mutex.c:26
void mutex_deinit(mutex_t *mtx)
Deinitializes a mutex.
Definition mutex.c:20
void mutex_init(mutex_t *mtx)
Initializes a mutex.
Definition mutex.c:12
clock_t timer_uptime(void)
Time since boot.
Definition timer.c:73
#define CONFIG_MUTEX_MAX_SLOW_SPIN
Maximum mutex slow spin configuration.
Definition config.h:154
#define EOK
No error.
Definition errno.h:32
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
Mutex structure.
Definition mutex.h:39
lock_t lock
Definition mutex.h:43
wait_queue_t waitQueue
Definition mutex.h:40
thread_t * owner
Definition mutex.h:41
uint32_t depth
Definition mutex.h:42
Thread of execution structure.
Definition thread.h:55