diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibC/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibPthread/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibPthread/semaphore.cpp (renamed from Userland/Libraries/LibC/semaphore.cpp) | 79 | ||||
-rw-r--r-- | Userland/Libraries/LibPthread/semaphore.h (renamed from Userland/Libraries/LibC/semaphore.h) | 7 |
4 files changed, 73 insertions, 15 deletions
diff --git a/Userland/Libraries/LibC/CMakeLists.txt b/Userland/Libraries/LibC/CMakeLists.txt index 1e2b7c4e83..56454f5609 100644 --- a/Userland/Libraries/LibC/CMakeLists.txt +++ b/Userland/Libraries/LibC/CMakeLists.txt @@ -24,7 +24,6 @@ set(LIBC_SOURCES qsort.cpp scanf.cpp sched.cpp - semaphore.cpp serenity.cpp signal.cpp spawn.cpp diff --git a/Userland/Libraries/LibPthread/CMakeLists.txt b/Userland/Libraries/LibPthread/CMakeLists.txt index c28f072b5e..0c29d56e60 100644 --- a/Userland/Libraries/LibPthread/CMakeLists.txt +++ b/Userland/Libraries/LibPthread/CMakeLists.txt @@ -1,6 +1,7 @@ set(SOURCES pthread.cpp pthread_once.cpp + semaphore.cpp ) serenity_libc(LibPthread pthread) diff --git a/Userland/Libraries/LibC/semaphore.cpp b/Userland/Libraries/LibPthread/semaphore.cpp index 618c3335f0..37361b4471 100644 --- a/Userland/Libraries/LibC/semaphore.cpp +++ b/Userland/Libraries/LibPthread/semaphore.cpp @@ -25,41 +25,94 @@ */ #include <AK/Assertions.h> +#include <errno.h> #include <semaphore.h> int sem_close(sem_t*) { - VERIFY_NOT_REACHED(); + errno = ENOSYS; + return -1; } -int sem_destroy(sem_t*) + +int sem_destroy(sem_t* sem) { - VERIFY_NOT_REACHED(); + pthread_mutex_destroy(&sem->mtx); + pthread_cond_destroy(&sem->cv); + return 0; } + int sem_getvalue(sem_t*, int*) { VERIFY_NOT_REACHED(); } -int sem_init(sem_t*, int, unsigned int) + +int sem_init(sem_t* sem, int shared, unsigned int value) { - VERIFY_NOT_REACHED(); + if (shared) + return ENOSYS; + + if (pthread_mutex_init(&sem->mtx, nullptr) != 0) + return -1; + + if (pthread_cond_init(&sem->cv, nullptr) != 0) + return -1; + + sem->value = value; + + return 0; } + sem_t* sem_open(const char*, int, ...) { - VERIFY_NOT_REACHED(); + errno = ENOSYS; + return nullptr; } -int sem_post(sem_t*) + +int sem_post(sem_t* sem) { - VERIFY_NOT_REACHED(); + sem->value++; + + pthread_cond_signal(&sem->cv); + + pthread_mutex_unlock(&sem->mtx); + + return 0; } -int sem_trywait(sem_t*) + +int sem_trywait(sem_t* sem) { - VERIFY_NOT_REACHED(); + if (pthread_mutex_lock(&sem->mtx) != 0) + return -1; + + if (sem->value == 0) { + pthread_mutex_unlock(&sem->mtx); + errno = EAGAIN; + return -1; + } + + sem->value--; + + return 0; } + int sem_unlink(const char*) { - VERIFY_NOT_REACHED(); + return ENOSYS; } -int sem_wait(sem_t*) + +int sem_wait(sem_t* sem) { - VERIFY_NOT_REACHED(); + if (pthread_mutex_lock(&sem->mtx) != 0) + return -1; + + while (sem->value == 0) { + if (pthread_cond_wait(&sem->cv, &sem->mtx) != 0) { + pthread_mutex_unlock(&sem->mtx); + return -1; + } + } + + sem->value--; + + return 0; } diff --git a/Userland/Libraries/LibC/semaphore.h b/Userland/Libraries/LibPthread/semaphore.h index 4d0444bef5..9371e51215 100644 --- a/Userland/Libraries/LibC/semaphore.h +++ b/Userland/Libraries/LibPthread/semaphore.h @@ -26,12 +26,17 @@ #pragma once +#include <pthread.h> #include <sys/cdefs.h> #include <sys/types.h> __BEGIN_DECLS -typedef int sem_t; +typedef struct { + pthread_mutex_t mtx; + pthread_cond_t cv; + int value; +} sem_t; int sem_close(sem_t*); int sem_destroy(sem_t*); |