diff --git a/components/pthreads/pthread.h b/components/pthreads/pthread.h index dfa3c11050..3ff7231707 100644 --- a/components/pthreads/pthread.h +++ b/components/pthreads/pthread.h @@ -23,6 +23,8 @@ typedef rt_thread_t pthread_t; typedef long pthread_condattr_t; +typedef long pthread_rwlockattr_t; + typedef int pthread_key_t; typedef int pthread_once_t; @@ -34,8 +36,8 @@ enum { PTHREAD_CANCELED }; -#define PTHREAD_COND_INITIALIZER -#define PTHREAD_RWLOCK_INITIALIZER +#define PTHREAD_COND_INITIALIZER {-1, 0} +#define PTHREAD_RWLOCK_INITIALIZER {-1, 0} #define PTHREAD_MUTEX_INITIALIZER {-1, 0} #define PTHREAD_CREATE_JOINABLE 0x00 diff --git a/components/pthreads/pthread_cond.c b/components/pthreads/pthread_cond.c index b0c85aefc0..3154086641 100644 --- a/components/pthreads/pthread_cond.c +++ b/components/pthreads/pthread_cond.c @@ -1,5 +1,32 @@ #include "pthread_cond.h" +int pthread_condattr_destroy(pthread_condattr_t *attr) +{ + if (!attr) return EINVAL; + + return 0; +} + +int pthread_condattr_init(pthread_condattr_t *attr) +{ + if (!attr) return EINVAL; + *attr = PTHREAD_PROCESS_PRIVATE; + + return 0; +} + +int pthread_condattr_getclock(const pthread_condattr_t *attr, + clockid_t *clock_id) +{ + return 0; +} + +int pthread_condattr_setclock(pthread_condattr_t *attr, + clockid_t clock_id) +{ + return 0; +} + int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared) { if (!attr || !pshared) return EINVAL; @@ -21,37 +48,132 @@ int pthread_condattr_setpshared(pthread_condattr_t*attr, int pshared) int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { + rt_err_t result; + rt_uint8_t cond_name[RT_NAME_MAX]; + static rt_uint16_t cond_num = 0; + /* parameter check */ if (cond == RT_NULL) return EINVAL; if ((attr != RT_NULL) && (*attr != PTHREAD_PROCESS_PRIVATE)) return EINVAL; + rt_snprintf(cond_name, sizeof(cond_name), + "cond%02d", cond_num++); + + cond->attr = *attr; + result = rt_sem_init(&cond->sem, cond_name, 0, RT_IPC_FLAG_FIFO); + if (result != RT_EOK) return EINVAL; + + /* detach the object from system object container */ + rt_object_detach(&(cond->sem.parent.parent)); + return 0; } int pthread_cond_destroy(pthread_cond_t *cond) { + rt_err_t result; + if (cond == RT_NULL) return EINVAL; + if (cond->attr == -1) return 0; /* which is not initialized */ + + result = rt_sem_trytake(&(cond->sem)); + if (result != RT_EOK) return EBUSY; + + /* clean condition */ + rt_memset(cond, 0, sizeof(pthread_cond_t)); + cond->attr = -1; + return 0; } int pthread_cond_broadcast(pthread_cond_t *cond) { + rt_err_t result; + if (cond->attr == -1) + pthread_cond_init(cond, RT_NULL); + + rt_enter_critical(); + while (1) + { + /* try to take condition semaphore */ + result = rt_sem_trytake(&(cond->sem)); + if (result == -RT_ETIMEOUT) + { + /* it's timeout, release this semaphore */ + rt_sem_release(&(cond->sem)); + } + else if (result == RT_EOK) + { + /* has taken this semaphore, release it */ + rt_sem_release(&(cond->sem)); + break; + } + else + { + rt_exit_critical(); + return EINVAL; + } + } + rt_exit_critical(); + return 0; } int pthread_cond_signal(pthread_cond_t *cond) { + rt_err_t result; + + if (cond->attr == -1) + pthread_cond_init(cond, RT_NULL); + + result = rt_sem_release(&(cond->sem)); + if (result == RT_EOK) return 0; + return 0; } +rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + rt_int32_t timeout) +{ + rt_err_t result; + + if (!cond || !mutex) return -RT_ERROR; + /* check whether initialized */ + if (cond->attr == -1) pthread_cond_init(cond, RT_NULL); + + /* The mutex was not owned by the current thread at the time of the call. */ + if (mutex->lock.owner != pthread_self()) return -RT_ERROR; + /* unlock a mutex failed */ + if (pthread_mutex_unlock(mutex) != 0) + return -RT_ERROR; + + result = rt_sem_take(&(cond->sem), timeout); + /* lock mutex again */ + pthred_mutex_lock(mutex); + return result; +} + int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - return 0; + rt_err_t result; + + result = _pthread_cond_timedwait(cond, mutex, RT_WAITING_FOREVER); + if (result == RT_EOK) return 0; + + return EINVAL; } int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t * mutex, const struct timespec *abstime) { - return 0; -} + rt_int32_t timeout; + rt_err_t result; + timeout = abstime->tv_sec * RT_TICK_PER_SECOND + + abstime->tv_nsec * RT_TICK_PER_SECOND/1000000000; + result = _pthread_cond_timedwait(cond, mutex, timeout); + if (result == RT_EOK) return 0; + if (result == -RT_ETIMEOUT) return ETIMEDOUT; + + return EINVAL; +} diff --git a/components/pthreads/pthread_cond.h b/components/pthreads/pthread_cond.h index 02b0412a9e..b81ca527d4 100644 --- a/components/pthreads/pthread_cond.h +++ b/components/pthreads/pthread_cond.h @@ -3,13 +3,24 @@ #include #include +#include struct pthread_cond { - pthread_mutex_t *mutex; + pthread_condattr_t attr; + struct rt_semaphore sem; }; typedef struct pthread_cond pthread_cond_t; +int pthread_condattr_destroy(pthread_condattr_t *attr); +int pthread_condattr_init(pthread_condattr_t *attr); + +/* ADVANCED REALTIME feature in IEEE Std 1003.1, 2004 Edition */ +int pthread_condattr_getclock(const pthread_condattr_t *attr, + clockid_t *clock_id); +int pthread_condattr_setclock(pthread_condattr_t *attr, + clockid_t clock_id); + int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); diff --git a/components/pthreads/pthread_rwlock.c b/components/pthreads/pthread_rwlock.c index e69de29bb2..343b9a51a1 100644 --- a/components/pthreads/pthread_rwlock.c +++ b/components/pthreads/pthread_rwlock.c @@ -0,0 +1,82 @@ +#include "pthread_rwlock.h" + +int pthread_rwlockattr_init (pthread_rwlockattr_t * attr) +{ + if (!attr) return EINVAL; + *attr = PTHREAD_PROCESS_PRIVATE; + + return 0; +} + +int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr) +{ + if (!attr) return EINVAL; + + return 0; +} + +int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, int *pshared) +{ + if (!attr || !pshared) return EINVAL; + + *pshared = PTHREAD_PROCESS_PRIVATE; + return 0; +} + +int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared) +{ + if (!attr || pshared != PTHREAD_PROCESS_PRIVATE) return EINVAL; + + return 0; +} + +int pthread_rwlock_init (pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr) +{ + return 0; +} + +int pthread_rwlock_destroy (pthread_rwlock_t * rwlock) +{ + return 0; +} + +int pthread_rwlock_rdlock (pthread_rwlock_t * rwlock) +{ + return 0; +} + +int pthread_rwlock_tryrdlock (pthread_rwlock_t * rwlock) +{ + if (!rwlock) return EINVAL; + return 0; +} + +int pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock, const struct timespec *abstime) +{ + if (!rwlock) return EINVAL; + return 0; +} + +int pthread_rwlock_timedwrlock (pthread_rwlock_t * rwlock, const struct timespec *abstime) +{ + if (!rwlock) return EINVAL; + return 0; +} + +int pthread_rwlock_trywrlock (pthread_rwlock_t * rwlock) +{ + if (!rwlock) return EINVAL; + return 0; +} + +int pthread_rwlock_unlock (pthread_rwlock_t * rwlock) +{ + if (!rwlock) return EINVAL; + + return 0; +} + +int pthread_rwlock_wrlock (pthread_rwlock_t * rwlock) +{ + return 0; +} diff --git a/components/pthreads/pthread_rwlock.h b/components/pthreads/pthread_rwlock.h index ee7dfaa91c..9d308f1bca 100644 --- a/components/pthreads/pthread_rwlock.h +++ b/components/pthreads/pthread_rwlock.h @@ -1,21 +1,36 @@ #ifndef __PTHREAD_RWLOCK_H__ #define __PTHREAD_RWLOCK_H__ -int pthread_rwlock_init (pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr); -int pthread_rwlock_destroy (pthread_rwlock_t * rwlock); +#include +#include +#include -int pthread_rwlock_rdlock (pthread_rwlock_t * rwlock); -int pthread_rwlock_tryrdlock (pthread_rwlock_t * rwlock); -int pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock, const struct timespec *abstime); +struct pthread_rwlock +{ + pthread_rwlockattr_t attr; -int pthread_rwlock_timedwrlock (pthread_rwlock_t * rwlock, const struct timespec *abstime); -int pthread_rwlock_trywrlock (pthread_rwlock_t * rwlock); -int pthread_rwlock_unlock (pthread_rwlock_t * rwlock); -int pthread_rwlock_wrlock (pthread_rwlock_t * rwlock); + struct rt_semaphore wrlock; + struct rt_semaphore rdlock; +}; +typedef struct pthread_rwlock pthread_rwlock_t; -int pthread_rwlockattr_init (pthread_rwlockattr_t * attr); -int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); -int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, int *pshared); -int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared); +int pthread_rwlockattr_init (pthread_rwlockattr_t *attr); +int pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr); +int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared); +int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared); + +int pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); +int pthread_rwlock_destroy (pthread_rwlock_t *rwlock); + +int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock); +int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock); + +int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, const struct timespec *abstime); +int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, const struct timespec *abstime); + +int pthread_rwlock_unlock (pthread_rwlock_t *rwlock); + +int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock); +int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock); #endif diff --git a/components/pthreads/pthread_spin.c b/components/pthreads/pthread_spin.c index 4332ec1db8..c38c611616 100644 --- a/components/pthreads/pthread_spin.c +++ b/components/pthreads/pthread_spin.c @@ -2,25 +2,50 @@ int pthread_spin_init (pthread_spinlock_t *lock, int pshared) { + if (!lock) return EINVAL; + + lock->lock = 0; return 0; } int pthread_spin_destroy (pthread_spinlock_t *lock) { + if (!lock) return EINVAL; + return 0; } -int pthread_spin_lock (pthread_spinlock_t * lock) +int pthread_spin_lock (pthread_spinlock_t *lock) { + if (!lock) return EINVAL; + + while (!(lock->lock)) + { + lock->lock = 1; + } + return 0; } -int pthread_spin_trylock (pthread_spinlock_t * lock) +int pthread_spin_trylock (pthread_spinlock_t *lock) { - return 0; + if (!lock) return EINVAL; + + if (!(lock->lock)) + { + lock->lock = 1; + return 0; + } + + return EBUSY; } -int pthread_spin_unlock (pthread_spinlock_t * lock) +int pthread_spin_unlock (pthread_spinlock_t *lock) { + if (!lock) return EINVAL; + if (!(lock->lock)) return EPERM; + + lock->lock = 0; + return 0; } diff --git a/components/pthreads/pthread_spin.h b/components/pthreads/pthread_spin.h index 4b66c8bdc2..b870c4524c 100644 --- a/components/pthreads/pthread_spin.h +++ b/components/pthreads/pthread_spin.h @@ -2,9 +2,10 @@ #define __PTHREAD_SPIN_H__ #include +/* spinlock implementation, (ADVANCED REALTIME THREADS)*/ struct pthread_spinlock { - int pshared; + int lock; }; typedef struct pthread_spinlock pthread_spinlock_t;