diff options
author | Ian Moffett <ian@osmora.org> | 2025-07-03 18:20:22 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-07-03 18:23:48 -0400 |
commit | 3a809b9faadfd0a8d898aede15cabfd24ee1a13f (patch) | |
tree | e44680b1526f42dda17212dbff9a503299fb2d82 /sys/kern | |
parent | 1caf181cd04090af77fd0aff8dd4b87df7a2ed66 (diff) |
kernel: synch: Add mutual exclusion locks
Add mutex locks, these differ from spinlocks as they are named and also
yield to the scheduler instead of just spinning if the lock is acquired.
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_synch.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 57b27d0..0d36d7f 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -28,12 +28,15 @@ */ #include <sys/types.h> +#include <sys/mutex.h> #include <sys/systm.h> #include <sys/errno.h> +#include <sys/sched.h> #include <sys/atomic.h> #include <sys/syslog.h> #include <sys/spinlock.h> #include <dev/timer.h> +#include <string.h> #define pr_trace(fmt, ...) kprintf("synch: " fmt, ##__VA_ARGS__) #define pr_error(...) pr_trace(__VA_ARGS__) @@ -136,3 +139,57 @@ sysrel(void) { spinlock_release(&__syslock); } + +/* + * Create a new mutex lock object + */ +struct mutex * +mutex_new(const char *name) +{ + struct mutex *mtx; + size_t namelen; + + mtx = dynalloc(sizeof(*mtx)); + if (mtx == NULL) { + return NULL; + } + + mtx->lock = 0; + namelen = strlen(name); + + /* Don't overflow the name buffer */ + if (namelen >= MUTEX_NAME_LEN) { + namelen = MUTEX_NAME_LEN - 1; + } + + memcpy(mtx->name, name, namelen); + return mtx; +} + +/* + * Acquire a mutex + * + * @mtx: Mutex to acquire + * @flags: Optional flags + */ +int +mutex_acquire(struct mutex *mtx, int flags) +{ + while (__atomic_test_and_set(&mtx->lock, __ATOMIC_ACQUIRE)) { + sched_yield(); + } + + return 0; +} + +void +mutex_release(struct mutex *mtx) +{ + __atomic_clear(&mtx->lock, __ATOMIC_RELEASE); +} + +void +mutex_free(struct mutex *mtx) +{ + dynfree(mtx); +} |