summaryrefslogtreecommitdiff
path: root/components/pthreads
diff options
context:
space:
mode:
Diffstat (limited to 'components/pthreads')
-rw-r--r--components/pthreads/pthread.h6
-rw-r--r--components/pthreads/pthread_cond.c128
-rw-r--r--components/pthreads/pthread_cond.h13
-rw-r--r--components/pthreads/pthread_rwlock.c82
-rw-r--r--components/pthreads/pthread_rwlock.h41
-rw-r--r--components/pthreads/pthread_spin.c33
-rw-r--r--components/pthreads/pthread_spin.h3
7 files changed, 282 insertions, 24 deletions
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 <pthread.h>
#include <sys/time.h>
+#include <rtthread.h>
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 <rtthread.h>
+#include <pthread.h>
+#include <sys/time.h>
-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 <pthread.h>
+/* spinlock implementation, (ADVANCED REALTIME THREADS)*/
struct pthread_spinlock
{
- int pshared;
+ int lock;
};
typedef struct pthread_spinlock pthread_spinlock_t;