From ea6d0aa1d47175c248368292bb2e687c73e1d37a Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 14 Apr 2021 04:29:39 +0200 Subject: [PATCH] LibPthread: Implement semaphore functions --- Userland/Libraries/LibC/CMakeLists.txt | 1 - Userland/Libraries/LibPthread/CMakeLists.txt | 1 + .../{LibC => LibPthread}/semaphore.cpp | 79 ++++++++++++++++--- .../{LibC => LibPthread}/semaphore.h | 7 +- 4 files changed, 73 insertions(+), 15 deletions(-) rename Userland/Libraries/{LibC => LibPthread}/semaphore.cpp (57%) rename Userland/Libraries/{LibC => LibPthread}/semaphore.h (94%) 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 similarity index 57% rename from Userland/Libraries/LibC/semaphore.cpp rename to 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 +#include #include 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 similarity index 94% rename from Userland/Libraries/LibC/semaphore.h rename to 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 #include #include __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*);