diff options
| author | [email protected] <[email protected]> | 2010-11-15 00:25:37 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2010-11-15 00:25:37 +0000 |
| commit | 468db501592d68a3576a42cc42e2c7c7fb527b8d (patch) | |
| tree | 9cde7754f5147ecccfb013528cf8bf1a85eef60d /components/pthreads/pthread_cond.c | |
| parent | 45461f8afe87d96c3bdb5fe26c94c323dff1452d (diff) | |
update pthreads components.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1046 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/pthreads/pthread_cond.c')
| -rw-r--r-- | components/pthreads/pthread_cond.c | 128 |
1 files changed, 125 insertions, 3 deletions
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;
+}
|
