summaryrefslogtreecommitdiff
path: root/sys/kern/kern_synch.c
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-07-03 18:20:22 -0400
committerIan Moffett <ian@osmora.org>2025-07-03 18:23:48 -0400
commit3a809b9faadfd0a8d898aede15cabfd24ee1a13f (patch)
treee44680b1526f42dda17212dbff9a503299fb2d82 /sys/kern/kern_synch.c
parent1caf181cd04090af77fd0aff8dd4b87df7a2ed66 (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/kern_synch.c')
-rw-r--r--sys/kern/kern_synch.c57
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);
+}