LibC: Implement unnamed semaphores

This commit is contained in:
Bananymous 2025-11-02 21:11:04 +02:00
parent 7367672570
commit e258fde25a
2 changed files with 32 additions and 23 deletions

View File

@ -10,7 +10,11 @@ __BEGIN_DECLS
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
typedef void* sem_t; typedef struct
{
int shared;
uint32_t value;
} sem_t;
#define SEM_FAILED ((sem_t*)0) #define SEM_FAILED ((sem_t*)0)

View File

@ -1,47 +1,52 @@
#include <BAN/Debug.h> #include <BAN/Atomic.h>
#include <errno.h> #include <errno.h>
#include <semaphore.h> #include <semaphore.h>
#include <sys/futex.h>
int sem_destroy(sem_t* sem) int sem_destroy(sem_t* sem)
{ {
(void)sem; (void)sem;
dwarnln("TODO: sem_destroy"); return 0;
errno = ENOTSUP;
return -1;
} }
int sem_init(sem_t* sem, int pshared, unsigned value) int sem_init(sem_t* sem, int pshared, unsigned value)
{ {
(void)sem; *sem = {
(void)pshared; .shared = pshared,
(void)value; .value = value,
dwarnln("TODO: sem_init"); };
errno = ENOTSUP; return 0;
return -1;
} }
int sem_post(sem_t* sem) int sem_post(sem_t* sem)
{ {
(void)sem; const auto old = BAN::atomic_fetch_add(sem->value, 1);
dwarnln("TODO: sem_post"); if (old == 0)
errno = ENOTSUP; futex(FUTEX_WAKE, &sem->value, 1, nullptr);
return -1; return 0;
} }
int sem_trywait(sem_t* sem) int sem_trywait(sem_t* sem)
{ {
(void)sem; uint32_t expected = BAN::atomic_load(sem->value);
dwarnln("TODO: sem_trywait"); while (expected)
errno = ENOTSUP; if (BAN::atomic_compare_exchange(sem->value, expected, expected - 1))
return 0;
errno = EAGAIN;
return -1; return -1;
} }
int sem_wait(sem_t* sem) int sem_wait(sem_t* sem)
{ {
(void)sem; for (;;)
dwarnln("TODO: sem_wait"); {
errno = ENOTSUP; uint32_t expected = BAN::atomic_load(sem->value);
if (expected > 0 && BAN::atomic_compare_exchange(sem->value, expected, expected - 1))
return 0;
const int op = FUTEX_WAIT | (sem->shared ? 0 : FUTEX_PRIVATE);
if (futex(op, &sem->value, expected, nullptr) == -1 && errno == EINTR)
return -1; return -1;
}
} }