Handle threading after a fork() (XCC)
[akaros.git] / user / pthread / semaphore.c
index 5b8751c..96ee4cf 100644 (file)
-#include <uthread.h>
+#include <parlib/uthread.h>
+#include <parlib/assert.h>
 #include <semaphore.h>
-#include <mcs.h>
 #include <stdio.h>
+#include <errno.h>
 
-int sem_init (sem_t *__sem, int __pshared, unsigned int __value)
+int sem_init(sem_t *__sem, int __pshared, unsigned int __value)
 {
-       if(__pshared == TRUE) {
+       if (__pshared == TRUE) {
                printf("__pshared functionality of sem_init is not yet implemented!");
                return -1;
        }
-       __sem->count = __value;
-       TAILQ_INIT(&__sem->queue);
-       mcs_pdr_init(&__sem->lock);
+       uth_semaphore_init(&__sem->real_sem, __value);
        return 0;
 }
 
-int sem_destroy (sem_t *__sem)
+int sem_destroy(sem_t *__sem)
 {
+       uth_semaphore_destroy(&__sem->real_sem);
        return 0;
 }
 
-sem_t *sem_open (__const char *__name, int __oflag, ...)
+sem_t *sem_open(__const char *__name, int __oflag, ...)
 {
        printf("sem_open is not yet implemented!");
        return NULL;
 }
 
-int sem_close (sem_t *__sem)
+int sem_close(sem_t *__sem)
 {
        printf("sem_close is not yet implemented!");
        return -1;
 }
 
-int sem_unlink (__const char *__name)
+int sem_unlink(__const char *__name)
 {
        printf("sem_unlink is not yet implemented!");
        return -1;
 }
 
-static void __sem_block(struct uthread *uthread, void *arg)
+int sem_wait(sem_t *__sem)
 {
-       sem_t *__sem = (sem_t*)arg;
-       pthread_t pthread = (pthread_t)uthread;
-       __pthread_generic_yield(pthread);
-       pthread->state = PTH_BLK_MUTEX;
-       TAILQ_INSERT_TAIL(&__sem->queue, pthread, next);
-       mcs_pdr_unlock(&__sem->lock);
+       uth_semaphore_down(&__sem->real_sem);
+       return 0;
 }
 
-int sem_wait (sem_t *__sem)
+int sem_timedwait(sem_t *__sem, const struct timespec *abs_timeout)
 {
-       mcs_pdr_lock(&__sem->lock);
-       if(__sem->count > 0) {
-               __sem->count--;
-               mcs_pdr_unlock(&__sem->lock);
-       }
-       else {
-               // We unlock in the body of __sem_block
-               uthread_yield(TRUE, __sem_block, __sem);
+       if (!uth_semaphore_timed_down(&__sem->real_sem, abs_timeout)) {
+               errno = ETIMEDOUT;
+               return -1;
        }
        return 0;
 }
 
-int sem_trywait (sem_t *__sem)
+int sem_trywait(sem_t *__sem)
 {
-       int ret = -1;
-       mcs_pdr_lock(&__sem->lock);
-       if(__sem->count > 0) {
-               __sem->count--;
-               ret = 0;
-       }
-       mcs_pdr_unlock(&__sem->lock);
-       return ret;
+       if (!uth_semaphore_trydown(&__sem->real_sem))
+               return -1;
+       return 0;
 }
 
-int sem_post (sem_t *__sem)
+int sem_post(sem_t *__sem)
 {
-       mcs_pdr_lock(&__sem->lock);
-       pthread_t pthread = TAILQ_FIRST(&__sem->queue);
-       if(pthread)
-               TAILQ_REMOVE(&__sem->queue, pthread, next);
-       else
-               __sem->count++; 
-       mcs_pdr_unlock(&__sem->lock);
-
-       if(pthread) {
-               uthread_runnable((struct uthread*)pthread);
-       }
+       uth_semaphore_up(&__sem->real_sem);
        return 0;
 }
 
-int sem_getvalue (sem_t *__restrict __sem, int *__restrict __sval)
+int sem_getvalue(sem_t *__restrict __sem, int *__restrict __sval)
 {
-       mcs_pdr_lock(&__sem->lock);
-       *__sval = __sem->count;
-       mcs_pdr_unlock(&__sem->lock);
+       spin_pdr_lock(&__sem->real_sem.lock);
+       *__sval = __sem->real_sem.count;
+       spin_pdr_unlock(&__sem->real_sem.lock);
        return 0;
 }
-