From 87e3cde79b75b143f59ea2ae1325de19ee6e87ab Mon Sep 17 00:00:00 2001 From: Ali Mashtizadeh Date: Sun, 1 Feb 2015 19:21:16 -0800 Subject: [PATCH] pthread condition variable implementation --- lib/libc/posix/pthread.c | 84 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/lib/libc/posix/pthread.c b/lib/libc/posix/pthread.c index 532f6f0..cc9199c 100644 --- a/lib/libc/posix/pthread.c +++ b/lib/libc/posix/pthread.c @@ -301,40 +301,112 @@ pthread_mutex_unlock(pthread_mutex_t *mutex) * Condition Variables */ -struct pthread_cond { +struct pthread_condattr { + uint64_t _unused; }; -struct pthread_condattr { +struct pthread_cond { + CoreMutex mtx; + uint64_t enter; + uint64_t exit; }; int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { - return EINVAL; + struct pthread_cond *cnd = (struct pthread_cond *)malloc(sizeof(*cnd)); + + if (cnd == NULL) { + return ENOMEM; + } + + CoreMutex_Init(&cnd->mtx); + cnd->enter = 0; + cnd->exit = 0; + + *cond = cnd; + + return 0; } int pthread_cond_destroy(pthread_cond_t *cond) { + struct pthread_cond *cnd = *cond; + + *cond = NULL; + free(cnd); + return EINVAL; } int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - return EINVAL; + struct pthread_cond *cnd; + uint64_t level; + + if (*cond == NULL) { + int status = pthread_cond_init(cond, NULL); + if (status != 0) + return status; + } + cnd = *cond; + + if (mutex) + pthread_mutex_unlock(mutex); + + CoreMutex_Lock(&cnd->mtx); + level = cnd->enter; + cnd->enter++; + CoreMutex_Unlock(&cnd->mtx); + + while (level >= cnd->exit) { + OSThreadSleep(0); + } + + if (mutex) + pthread_mutex_lock(mutex); + + return 0; } int pthread_cond_signal(pthread_cond_t *cond) { - return EINVAL; + struct pthread_cond *cnd; + + if (*cond == NULL) { + int status = pthread_cond_init(cond, NULL); + if (status != 0) + return status; + } + cnd = *cond; + + CoreMutex_Lock(&cnd->mtx); + cnd->exit++; + CoreMutex_Unlock(&cnd->mtx); + + return 0; } int pthread_cond_broadcast(pthread_cond_t *cond) { - return EINVAL; + struct pthread_cond *cnd; + + if (*cond == NULL) { + int status = pthread_cond_init(cond, NULL); + if (status != 0) + return status; + } + cnd = *cond; + + CoreMutex_Lock(&cnd->mtx); + cnd->exit = cnd->enter; + CoreMutex_Unlock(&cnd->mtx); + + return 0; }