From 810f7414427277dfa86d3821aef9ba584564ef64 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 19 Jul 2026 13:31:22 +0100 Subject: [PATCH] libc: pthread: implement mutexes --- lib/libc/pthread/include/pthread.h | 8 ++++++- lib/libc/pthread/mutex/pthread_mutex_lock.c | 24 +++++++++++++++++++ .../pthread/mutex/pthread_mutex_trylock.c | 18 ++++++++++++++ lib/libc/pthread/mutex/pthread_mutex_unlock.c | 8 +++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 lib/libc/pthread/mutex/pthread_mutex_lock.c create mode 100644 lib/libc/pthread/mutex/pthread_mutex_trylock.c create mode 100644 lib/libc/pthread/mutex/pthread_mutex_unlock.c diff --git a/lib/libc/pthread/include/pthread.h b/lib/libc/pthread/include/pthread.h index f029886..dcf4bef 100644 --- a/lib/libc/pthread/include/pthread.h +++ b/lib/libc/pthread/include/pthread.h @@ -3,7 +3,9 @@ #include -#define __PTHREAD_ATTR_SIZE__ 32 +#define __PTHREAD_ATTR_SIZE__ 32 + +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) {.__v = 0}) typedef struct __pthread *pthread_t; @@ -28,4 +30,8 @@ extern int pthread_join(pthread_t thread, void **retval); extern int pthread_detach(pthread_t thread); extern void pthread_exit(void *retval); +extern int pthread_mutex_lock(pthread_mutex_t *mut); +extern int pthread_mutex_trylock(pthread_mutex_t *mut); +extern int pthread_mutex_unlock(pthread_mutex_t *mut); + #endif diff --git a/lib/libc/pthread/mutex/pthread_mutex_lock.c b/lib/libc/pthread/mutex/pthread_mutex_lock.c new file mode 100644 index 0000000..97c0166 --- /dev/null +++ b/lib/libc/pthread/mutex/pthread_mutex_lock.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int pthread_mutex_lock(pthread_mutex_t *mut) +{ + kern_futex_t expected = 0; + while (1) { + expected = 0; + if (__atomic_compare_exchange_n( + &mut->__v, + &expected, + 1, + 0, + __ATOMIC_ACQUIRE, + __ATOMIC_ACQUIRE)) { + return 0; + } + + futex_wait(&mut->__v, 1, FUTEX_PRIVATE); + } + + return __set_errno(EAGAIN); +} diff --git a/lib/libc/pthread/mutex/pthread_mutex_trylock.c b/lib/libc/pthread/mutex/pthread_mutex_trylock.c new file mode 100644 index 0000000..d3d360e --- /dev/null +++ b/lib/libc/pthread/mutex/pthread_mutex_trylock.c @@ -0,0 +1,18 @@ +#include +#include + +int pthread_mutex_trylock(pthread_mutex_t *mut) +{ + kern_futex_t expected = 0; + if (__atomic_compare_exchange_n( + &mut->__v, + &expected, + 1, + 0, + __ATOMIC_ACQUIRE, + __ATOMIC_ACQUIRE)) { + return 0; + } + + return __set_errno(EBUSY); +} diff --git a/lib/libc/pthread/mutex/pthread_mutex_unlock.c b/lib/libc/pthread/mutex/pthread_mutex_unlock.c new file mode 100644 index 0000000..6fea185 --- /dev/null +++ b/lib/libc/pthread/mutex/pthread_mutex_unlock.c @@ -0,0 +1,8 @@ +#include +#include + +int pthread_mutex_unlock(pthread_mutex_t *mut) +{ + mut->__v = 0; + futex_wake(&mut->__v, 1, FUTEX_PRIVATE); +}