PatchworkOS  a7b3d61
A non-POSIX operating system.
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>
4#include <kernel/log/log.h>
9#include <kernel/sched/wait.h>
10#include <kernel/sync/lock.h>
11
12#include <assert.h>
13
15{
17 mtx->owner = NULL;
18 mtx->depth = 0;
19 lock_init(&mtx->lock);
20}
21
23{
24 assert(mtx->owner == NULL);
26}
27
29{
30 bool isAcquired = mutex_acquire_timeout(mtx, CLOCKS_NEVER);
31 assert(isAcquired);
32 (void)isAcquired;
33}
34
36{
37 assert(mtx != NULL);
38 thread_t* self = sched_thread();
39 assert(self != NULL);
40
41 if (mtx->owner == self)
42 {
43 mtx->depth++;
44 return true;
45 }
46
47 uint64_t spin = 0;
48 while (spin < CONFIG_MUTEX_MAX_SLOW_SPIN)
49 {
50 lock_acquire(&mtx->lock);
51 if (mtx->owner == NULL)
52 {
53 mtx->owner = self;
54 mtx->depth = 1;
55 lock_release(&mtx->lock);
56 return true;
57 }
58 lock_release(&mtx->lock);
59 spin++;
60 }
61
62 if (timeout == 0)
63 {
64 return false;
65 }
66
67 if (timeout == CLOCKS_NEVER)
68 {
69 lock_acquire(&mtx->lock);
70 while (WAIT_BLOCK_LOCK(&mtx->waitQueue, &mtx->lock, mtx->owner == NULL) == ERR)
71 {
72 }
73
74 mtx->owner = self;
75 mtx->depth = 1;
76 lock_release(&mtx->lock);
77 return true;
78 }
79
80 lock_acquire(&mtx->lock);
81 clock_t end = sys_time_uptime() + timeout;
82 while (true)
83 {
85 if (now >= end)
86 {
87 lock_release(&mtx->lock);
88 return false;
89 }
90
91 clock_t waitTime = end - now;
92 if (WAIT_BLOCK_LOCK_TIMEOUT(&mtx->waitQueue, &mtx->lock, mtx->owner == NULL, waitTime) == ERR)
93 {
94 lock_release(&mtx->lock);
95 return false;
96 }
97
98 mtx->owner = self;
99 mtx->depth = 1;
100 lock_release(&mtx->lock);
101 return true;
102 }
103}
104
106{
107 assert(mtx != NULL);
108 LOCK_SCOPE(&mtx->lock);
109
111
112 mtx->depth--;
113 if (mtx->depth == 0)
114 {
115 mtx->owner = NULL;
116 wait_unblock(&mtx->waitQueue, 1, EOK);
117 }
118}
#define assert(expression)
Definition assert.h:29
#define CLOCKS_NEVER
Definition clock_t.h:16
uint64_t wait_unblock(wait_queue_t *queue, uint64_t amount, errno_t err)
Unblock threads waiting on a wait queue.
Definition wait.c:295
void wait_queue_deinit(wait_queue_t *queue)
Deinitialize wait queue.
Definition wait.c:44
void wait_queue_init(wait_queue_t *queue)
Initialize wait queue.
Definition wait.c:38
#define WAIT_BLOCK_LOCK_TIMEOUT(queue, lock, condition, timeout)
Blocks until the condition is true, condition will be tested on every wakeup. Will release the lock b...
Definition wait.h:133
#define WAIT_BLOCK_LOCK(queue, lock, condition)
Blocks until the condition is true, condition will be tested on every wakeup. Will release the lock b...
Definition wait.h:106
thread_t * sched_thread(void)
Retrieves the currently running thread.
Definition sched.c:616
thread_t * sched_thread_unsafe(void)
Retrieves the currently running thread without disabling interrupts.
Definition sched.c:630
static void lock_init(lock_t *lock)
Initializes a lock.
Definition lock.h:86
#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:146
static void lock_acquire(lock_t *lock)
Acquires a lock, blocking until it is available.
Definition lock.h:103
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:35
void mutex_release(mutex_t *mtx)
Releases a mutex.
Definition mutex.c:105
void mutex_acquire(mutex_t *mtx)
Acquires a mutex, blocking until it is available.
Definition mutex.c:28
void mutex_deinit(mutex_t *mtx)
Deinitializes a mutex.
Definition mutex.c:22
void mutex_init(mutex_t *mtx)
Initializes a mutex.
Definition mutex.c:14
clock_t sys_time_uptime(void)
Time since boot.
Definition sys_time.c:99
#define CONFIG_MUTEX_MAX_SLOW_SPIN
Maximum mutex slow spin configuration.
Definition config.h:121
#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:41
lock_t lock
Definition mutex.h:45
wait_queue_t waitQueue
Definition mutex.h:42
thread_t * owner
Definition mutex.h:43
uint32_t depth
Definition mutex.h:44
Thread of execution structure.
Definition thread.h:63