LibC: Implement unnamed semaphores
This commit is contained in:
parent
7367672570
commit
e258fde25a
|
|
@ -10,7 +10,11 @@ __BEGIN_DECLS
|
|||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef void* sem_t;
|
||||
typedef struct
|
||||
{
|
||||
int shared;
|
||||
uint32_t value;
|
||||
} sem_t;
|
||||
|
||||
#define SEM_FAILED ((sem_t*)0)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,47 +1,52 @@
|
|||
#include <BAN/Debug.h>
|
||||
#include <BAN/Atomic.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <semaphore.h>
|
||||
#include <sys/futex.h>
|
||||
|
||||
int sem_destroy(sem_t* sem)
|
||||
{
|
||||
(void)sem;
|
||||
dwarnln("TODO: sem_destroy");
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_init(sem_t* sem, int pshared, unsigned value)
|
||||
{
|
||||
(void)sem;
|
||||
(void)pshared;
|
||||
(void)value;
|
||||
dwarnln("TODO: sem_init");
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
*sem = {
|
||||
.shared = pshared,
|
||||
.value = value,
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_post(sem_t* sem)
|
||||
{
|
||||
(void)sem;
|
||||
dwarnln("TODO: sem_post");
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
|
||||
const auto old = BAN::atomic_fetch_add(sem->value, 1);
|
||||
if (old == 0)
|
||||
futex(FUTEX_WAKE, &sem->value, 1, nullptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_trywait(sem_t* sem)
|
||||
{
|
||||
(void)sem;
|
||||
dwarnln("TODO: sem_trywait");
|
||||
errno = ENOTSUP;
|
||||
uint32_t expected = BAN::atomic_load(sem->value);
|
||||
while (expected)
|
||||
if (BAN::atomic_compare_exchange(sem->value, expected, expected - 1))
|
||||
return 0;
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sem_wait(sem_t* sem)
|
||||
{
|
||||
(void)sem;
|
||||
dwarnln("TODO: sem_wait");
|
||||
errno = ENOTSUP;
|
||||
for (;;)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue