Browse Source

update pthreads components.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1046 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 14 years ago
parent
commit
468db50159

+ 4 - 2
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

+ 125 - 3
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;
+}

+ 12 - 1
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);

+ 82 - 0
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;
+}

+ 31 - 16
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);
-
-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_trywrlock (pthread_rwlock_t * rwlock);
-int pthread_rwlock_unlock (pthread_rwlock_t * rwlock);
-int pthread_rwlock_wrlock (pthread_rwlock_t * rwlock);
-
-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);
+#include <rtthread.h>
+#include <pthread.h>
+#include <sys/time.h>
+
+struct pthread_rwlock
+{
+	pthread_rwlockattr_t attr;
+
+	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_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

+ 29 - 4
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;
 }

+ 2 - 1
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;