summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbernard.xiong <[email protected]>2010-11-15 09:46:50 +0000
committerbernard.xiong <[email protected]>2010-11-15 09:46:50 +0000
commitaca1628a31c2acca262a90af921501368f8cfcc2 (patch)
treec16bc86bd18ffda0e7c9f604c75f3477119ea064
parentac407d25ae36ed2e4510867133a10009692052b4 (diff)
cleanup pthread implementation code.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1048 bbd45198-f89e-11dd-88c7-29a3b14d5316
-rw-r--r--components/pthreads/pthread.c26
-rw-r--r--components/pthreads/pthread.h149
-rw-r--r--components/pthreads/pthread_attr.h20
-rw-r--r--components/pthreads/pthread_barrier.c79
-rw-r--r--components/pthreads/pthread_barrier.h0
-rw-r--r--components/pthreads/pthread_cond.c2
-rw-r--r--components/pthreads/pthread_cond.h34
-rw-r--r--components/pthreads/pthread_mutex.h25
-rw-r--r--components/pthreads/pthread_rwlock.c218
-rw-r--r--components/pthreads/pthread_rwlock.h36
-rw-r--r--components/pthreads/pthread_spin.c2
-rw-r--r--components/pthreads/pthread_spin.h19
-rw-r--r--components/pthreads/pthread_tls.c19
-rw-r--r--components/pthreads/pthread_tls.h0
14 files changed, 469 insertions, 160 deletions
diff --git a/components/pthreads/pthread.c b/components/pthreads/pthread.c
index 8200b471ec..964f57ad29 100644
--- a/components/pthreads/pthread.c
+++ b/components/pthreads/pthread.c
@@ -274,3 +274,29 @@ int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(vo
return ENOTSUP;
}
+int pthread_kill(pthread_t thread, int sig)
+{
+ return ENOTSUP;
+}
+
+void pthread_cleanup_pop(int execute)
+{
+}
+
+void pthread_cleanup_push(void (*routine)(void*), void *arg)
+{
+}
+
+int pthread_setcancelstate(int state, int *oldstate)
+{
+}
+
+int pthread_setcanceltype(int type, int *oldtype)
+{
+ return 0;
+}
+
+void pthread_testcancel(void)
+{
+}
+
diff --git a/components/pthreads/pthread.h b/components/pthreads/pthread.h
index 3ff7231707..bd112b503f 100644
--- a/components/pthreads/pthread.h
+++ b/components/pthreads/pthread.h
@@ -16,14 +16,13 @@
#include <rtthread.h>
#include <errno.h>
-
-#include "pthread_attr.h"
-#include "pthread_mutex.h"
+#include <sys/types.h>
typedef rt_thread_t pthread_t;
-
typedef long pthread_condattr_t;
typedef long pthread_rwlockattr_t;
+typedef long pthread_mutexattr_t;
+typedef long pthread_barrierattr_t;
typedef int pthread_key_t;
typedef int pthread_once_t;
@@ -74,7 +73,62 @@ enum {
struct sched_param {
int sched_priority;
};
-
+
+struct pthread_attr
+{
+ void* stack_base;
+ rt_uint16_t stack_size; /* stack size of thread */
+
+ rt_uint8_t priority; /* priority of thread */
+ rt_uint8_t detachstate; /* detach state */
+ rt_uint8_t policy; /* scheduler policy */
+ rt_uint8_t inheritsched; /* Inherit parent prio/policy */
+};
+typedef struct pthread_attr pthread_attr_t;
+
+struct pthread_mutex
+{
+ pthread_mutexattr_t attr;
+ struct rt_mutex lock;
+};
+typedef struct pthread_mutex pthread_mutex_t;
+
+struct pthread_cond
+{
+ pthread_condattr_t attr;
+ struct rt_semaphore sem;
+};
+typedef struct pthread_cond pthread_cond_t;
+
+struct pthread_rwlock
+{
+ pthread_rwlockattr_t attr;
+
+ pthread_mutex_t rw_mutex; /* basic lock on this struct */
+ pthread_cond_t rw_condreaders; /* for reader threads waiting */
+ pthread_cond_t rw_condwriters; /* for writer threads waiting */
+
+ int rw_nwaitreaders; /* the number waiting */
+ int rw_nwaitwriters; /* the number waiting */
+ int rw_refcount;
+};
+typedef struct pthread_rwlock pthread_rwlock_t;
+
+/* spinlock implementation, (ADVANCED REALTIME THREADS)*/
+struct pthread_spinlock
+{
+ int lock;
+};
+typedef struct pthread_spinlock pthread_spinlock_t;
+
+struct pthread_barrier
+{
+ int count;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+};
+typedef struct pthread_barrier pthread_barrier_t;
+
/*
* Scheduling policies required by IEEE Std 1003.1-2001
*/
@@ -82,6 +136,10 @@ struct sched_param {
#define SCHED_FIFO 1
#define SCHED_RR 2
+/* pthread thread interface */
+int pthread_attr_destroy(pthread_attr_t *attr);
+int pthread_attr_init(pthread_attr_t *attr);
+
int pthread_init (void);
int pthread_create (pthread_t *tid, const pthread_attr_t *attr,
void *(*start) (void *), void *arg);
@@ -100,17 +158,94 @@ rt_inline pthread_t pthread_self (void)
}
void pthread_exit (void *value_ptr);
-
int pthread_once(pthread_once_t * once_control, void (*init_routine) (void));
+/* pthread cleanup */
+void pthread_cleanup_pop(int execute);
+void pthread_cleanup_push(void (*routine)(void*), void *arg);
+
/* pthread cancel */
int pthread_cancel(pthread_t thread);
void pthread_testcancel(void);
-
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
+int pthread_kill(pthread_t thread, int sig);
+
+/* pthread mutex interface */
+int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
+int pthread_mutex_destroy(pthread_mutex_t *mutex);
+int pthread_mutex_lock(pthread_mutex_t *mutex);
+int pthread_mutex_unlock(pthread_mutex_t *mutex);
+int pthread_mutex_trylock(pthread_mutex_t *mutex);
+
+int pthread_mutexattr_init(pthread_mutexattr_t *attr);
+int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
+int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
+int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared);
+
+/* pthread condition interface */
+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);
+int pthread_cond_signal(pthread_cond_t *cond);
+
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int pthread_cond_timedwait(pthread_cond_t *cond,
+ pthread_mutex_t * mutex,
+ const struct timespec *abstime);
+
+/* pthread rwlock interface */
+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);
+
+/* pthread spinlock interface */
+int pthread_spin_init (pthread_spinlock_t *lock, int pshared);
+int pthread_spin_destroy (pthread_spinlock_t *lock);
+
+int pthread_spin_lock (pthread_spinlock_t * lock);
+int pthread_spin_trylock (pthread_spinlock_t * lock);
+int pthread_spin_unlock (pthread_spinlock_t * lock);
+
+/* pthread barrier interface */
+int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
+int pthread_barrierattr_init(pthread_barrierattr_t *attr);
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared);
+
+int pthread_barrier_destroy(pthread_barrier_t *barrier);
+int pthread_barrier_init(pthread_barrier_t *barrier,
+ const pthread_barrierattr_t *attr, unsigned count);
+
+int pthread_barrier_wait(pthread_barrier_t *barrier);
#endif
diff --git a/components/pthreads/pthread_attr.h b/components/pthreads/pthread_attr.h
deleted file mode 100644
index f4950e20bf..0000000000
--- a/components/pthreads/pthread_attr.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __PTHREAD_ATTR_H__
-#define __PTHREAD_ATTR_H__
-
-struct pthread_attr
-{
- void* stack_base;
- rt_uint16_t stack_size; /* stack size of thread */
-
- rt_uint8_t priority; /* priority of thread */
- rt_uint8_t detachstate; /* detach state */
- rt_uint8_t policy; /* scheduler policy */
- rt_uint8_t inheritsched; /* Inherit parent prio/policy */
-};
-typedef struct pthread_attr pthread_attr_t;
-extern const pthread_attr_t pthread_default_attr;
-
-int pthread_attr_destroy(pthread_attr_t *attr);
-int pthread_attr_init(pthread_attr_t *attr);
-
-#endif
diff --git a/components/pthreads/pthread_barrier.c b/components/pthreads/pthread_barrier.c
index e69de29bb2..8908ab5d68 100644
--- a/components/pthreads/pthread_barrier.c
+++ b/components/pthreads/pthread_barrier.c
@@ -0,0 +1,79 @@
+#include <pthread.h>
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t *attr)
+{
+ if (!attr) return EINVAL;
+ return 0;
+}
+
+int pthread_barrierattr_init(pthread_barrierattr_t *attr)
+{
+ if (!attr) return EINVAL;
+ *attr = PTHREAD_PROCESS_PRIVATE;
+
+ return 0;
+}
+
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared)
+{
+ if (!attr) return EINVAL;
+ *pshared = (int)*attr;
+
+ return 0;
+}
+
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared)
+{
+ if (!attr) return EINVAL;
+ if (pshared == PTHREAD_PROCESS_PRIVATE) attr = PTHREAD_PROCESS_PRIVATE;
+
+ return EINVAL;
+}
+
+int pthread_barrier_destroy(pthread_barrier_t *barrier)
+{
+ rt_err_t result;
+
+ if (!barrier) return EINVAL;
+
+ result = pthread_cond_destroy(&(barrier->cond));
+
+ return result;
+}
+
+int pthread_barrier_init(pthread_barrier_t *barrier,
+ const pthread_barrierattr_t *attr, unsigned count)
+{
+ rt_err_t result;
+ if (!barrier) return EINVAL;
+ if (attr &&(*attr != PTHREAD_PROCESS_PRIVATE)) return EINVAL;
+
+ barrier->count = count;
+ pthread_cond_init(&(barrier->cond), NULL);
+ pthread_mutex_init(&(barrier->mutex), NULL);
+
+ return 0;
+}
+
+int pthread_barrier_wait(pthread_barrier_t *barrier)
+{
+ rt_err_t result;
+ if (!barrier) return EINVAL;
+
+ result = pthread_mutex_lock(&(barrier->mutex));
+ if (result != 0) return EINVAL;
+
+ if (barrier->count == 0) result = EINVAL;
+ else
+ {
+ barrier->count -= 1;
+ if (barrier->count == 0) /* broadcast condition */
+ pthread_cond_broadcast(&(barrier->cond));
+ else
+ pthread_cond_wait(&(barrier->cond), &(barrier->mutex));
+ }
+
+ pthread_mutex_unlock(&(barrier->mutex));
+ return result;
+}
+
diff --git a/components/pthreads/pthread_barrier.h b/components/pthreads/pthread_barrier.h
deleted file mode 100644
index e69de29bb2..0000000000
--- a/components/pthreads/pthread_barrier.h
+++ /dev/null
diff --git a/components/pthreads/pthread_cond.c b/components/pthreads/pthread_cond.c
index 3154086641..c4e876f49c 100644
--- a/components/pthreads/pthread_cond.c
+++ b/components/pthreads/pthread_cond.c
@@ -1,4 +1,4 @@
-#include "pthread_cond.h"
+#include <pthread.h>
int pthread_condattr_destroy(pthread_condattr_t *attr)
{
diff --git a/components/pthreads/pthread_cond.h b/components/pthreads/pthread_cond.h
deleted file mode 100644
index b81ca527d4..0000000000
--- a/components/pthreads/pthread_cond.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __PTHREAD_COND_H__
-#define __PTHREAD_COND_H__
-
-#include <pthread.h>
-#include <sys/time.h>
-#include <rtthread.h>
-
-struct pthread_cond
-{
- 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);
-int pthread_cond_signal(pthread_cond_t *cond);
-
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
-int pthread_cond_timedwait(pthread_cond_t *cond,
- pthread_mutex_t * mutex,
- const struct timespec *abstime);
-
-#endif
diff --git a/components/pthreads/pthread_mutex.h b/components/pthreads/pthread_mutex.h
deleted file mode 100644
index c12e9df0cc..0000000000
--- a/components/pthreads/pthread_mutex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __PTHREAD_MUTEX_H__
-#define __PTHREAD_MUTEX_H__
-
-typedef long pthread_mutexattr_t;
-struct pthread_mutex
-{
- pthread_mutexattr_t attr;
- struct rt_mutex lock;
-};
-typedef struct pthread_mutex pthread_mutex_t;
-
-int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
-int pthread_mutex_destroy(pthread_mutex_t *mutex);
-int pthread_mutex_lock(pthread_mutex_t *mutex);
-int pthread_mutex_unlock(pthread_mutex_t *mutex);
-int pthread_mutex_trylock(pthread_mutex_t *mutex);
-
-int pthread_mutexattr_init(pthread_mutexattr_t *attr);
-int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
-int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
-int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
-int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
-int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared);
-
-#endif
diff --git a/components/pthreads/pthread_rwlock.c b/components/pthreads/pthread_rwlock.c
index 343b9a51a1..5ee7a13531 100644
--- a/components/pthreads/pthread_rwlock.c
+++ b/components/pthreads/pthread_rwlock.c
@@ -1,4 +1,4 @@
-#include "pthread_rwlock.h"
+#include <pthread.h>
int pthread_rwlockattr_init (pthread_rwlockattr_t * attr)
{
@@ -30,53 +30,237 @@ int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared)
return 0;
}
-int pthread_rwlock_init (pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr)
+int pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t * attr)
{
+ if (!rwlock) return EINVAL;
+
+ rwlock->attr = PTHREAD_PROCESS_PRIVATE;
+ pthread_mutex_init(&(rwlock->rw_mutex), NULL);
+ pthread_cond_init(&(rwlock->rw_condreaders), NULL);
+ pthread_cond_init(&(rwlock->rw_condwriters), NULL);
+
+ rwlock->rw_nwaitwriters = 0;
+ rwlock->rw_nwaitreaders = 0;
+ rwlock->rw_refcount = 0;
+
return 0;
}
-int pthread_rwlock_destroy (pthread_rwlock_t * rwlock)
+int pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
{
- return 0;
+ int result;
+
+ if (!rwlock) return EINVAL;
+ if (rwlock->attr == -1) return 0; /* rwlock is not initialized */
+
+ if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+ return(result);
+
+ if (rwlock->rw_refcount != 0 ||
+ rwlock->rw_nwaitreaders != 0 || rwlock->rw_nwaitwriters != 0)
+ {
+ result = EBUSY;
+ return(EBUSY);
+ }
+ else
+ {
+ /* check whether busy */
+ result = rt_sem_trytake(&(rwlock->rw_condreaders.sem));
+ if (result == RT_EOK)
+ {
+ result = rt_sem_trytake(&(rwlock->rw_condwriters.sem));
+ if (result == RT_EOK)
+ {
+ rt_sem_release(&(rwlock->rw_condreaders.sem));
+ rt_sem_release(&(rwlock->rw_condwriters.sem));
+
+ pthread_cond_destroy(&rwlock->rw_condreaders);
+ pthread_cond_destroy(&rwlock->rw_condwriters);
+ }
+ else
+ {
+ rt_sem_release(&(rwlock->rw_condreaders.sem));
+ result = EBUSY;
+ }
+ }
+ else result = EBUSY;
+ }
+
+ pthread_mutex_unlock(&rwlock->rw_mutex);
+ if (result == 0) pthread_mutex_destroy(&rwlock->rw_mutex);
+
+ return result;
}
-int pthread_rwlock_rdlock (pthread_rwlock_t * rwlock)
+int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
{
- return 0;
+ int result;
+
+ if (!rwlock) return EINVAL;
+ if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
+
+ if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+ return(result);
+
+ /* give preference to waiting writers */
+ while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
+ {
+ rwlock->rw_nwaitreaders++;
+ result = pthread_cond_wait(&rwlock->rw_condreaders, &rwlock->rw_mutex);
+ rwlock->rw_nwaitreaders--;
+ if (result != 0)
+ break;
+ }
+
+ /* another reader has a read lock */
+ if (result == 0) rwlock->rw_refcount++;
+
+ pthread_mutex_unlock(&rwlock->rw_mutex);
+ return (result);
}
-int pthread_rwlock_tryrdlock (pthread_rwlock_t * rwlock)
+int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
{
+ int result;
+
if (!rwlock) return EINVAL;
- return 0;
+ if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
+
+ if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+ return(result);
+
+ if (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
+ result = EBUSY; /* held by a writer or waiting writers */
+ else
+ rwlock->rw_refcount++; /* increment count of reader locks */
+
+ pthread_mutex_unlock(&rwlock->rw_mutex);
+ return(result);
}
int pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock, const struct timespec *abstime)
{
+ int result;
+
if (!rwlock) return EINVAL;
- return 0;
+ if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
+
+ if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+ return(result);
+
+ /* give preference to waiting writers */
+ while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
+ {
+ rwlock->rw_nwaitreaders++;
+ result = pthread_cond_timedwait(&rwlock->rw_condreaders, &rwlock->rw_mutex, abstime);
+ rwlock->rw_nwaitreaders--;
+ if (result != 0)
+ break;
+ }
+
+ /* another reader has a read lock */
+ if (result == 0) rwlock->rw_refcount++;
+
+ pthread_mutex_unlock(&rwlock->rw_mutex);
+ return (result);
}
-int pthread_rwlock_timedwrlock (pthread_rwlock_t * rwlock, const struct timespec *abstime)
+int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, const struct timespec *abstime)
{
+ int result;
+
if (!rwlock) return EINVAL;
- return 0;
+ if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
+
+ if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+ return(result);
+
+ while (rwlock->rw_refcount != 0)
+ {
+ rwlock->rw_nwaitwriters++;
+ result = pthread_cond_timedwait(&rwlock->rw_condwriters, &rwlock->rw_mutex, abstime);
+ rwlock->rw_nwaitwriters--;
+
+ if (result != 0) break;
+ }
+
+ if (result == 0) rwlock->rw_refcount = -1;
+
+ pthread_mutex_unlock(&rwlock->rw_mutex);
+ return(result);
}
-int pthread_rwlock_trywrlock (pthread_rwlock_t * rwlock)
+int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
{
+ int result;
+
if (!rwlock) return EINVAL;
- return 0;
+ if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
+
+ if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+ return(result);
+
+ if (rwlock->rw_refcount != 0)
+ result = EBUSY; /* held by either writer or reader(s) */
+ else
+ rwlock->rw_refcount = -1; /* available, indicate a writer has it */
+
+ pthread_mutex_unlock(&rwlock->rw_mutex);
+ return(result);
}
-int pthread_rwlock_unlock (pthread_rwlock_t * rwlock)
+int pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
{
+ int result;
+
if (!rwlock) return EINVAL;
+ if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
- return 0;
+ if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+ return(result);
+
+ if (rwlock->rw_refcount > 0)
+ rwlock->rw_refcount--; /* releasing a reader */
+ else if (rwlock->rw_refcount == -1)
+ rwlock->rw_refcount = 0; /* releasing a reader */
+
+ /* give preference to waiting writers over waiting readers */
+ if (rwlock->rw_nwaitwriters > 0)
+ {
+ if (rwlock->rw_refcount == 0)
+ result = pthread_cond_signal(&rwlock->rw_condwriters);
+ }
+ else if (rwlock->rw_nwaitreaders > 0)
+ {
+ result = pthread_cond_broadcast(&rwlock->rw_condreaders);
+ }
+
+ pthread_mutex_unlock(&rwlock->rw_mutex);
+ return(result);
}
-int pthread_rwlock_wrlock (pthread_rwlock_t * rwlock)
+int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
{
- return 0;
+ int result;
+
+ if (!rwlock) return EINVAL;
+ if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
+
+ if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
+ return(result);
+
+ while (rwlock->rw_refcount != 0)
+ {
+ rwlock->rw_nwaitwriters++;
+ result = pthread_cond_wait(&rwlock->rw_condwriters, &rwlock->rw_mutex);
+ rwlock->rw_nwaitwriters--;
+
+ if (result != 0) break;
+ }
+
+ if (result == 0) rwlock->rw_refcount = -1;
+
+ pthread_mutex_unlock(&rwlock->rw_mutex);
+ return(result);
}
+
diff --git a/components/pthreads/pthread_rwlock.h b/components/pthreads/pthread_rwlock.h
deleted file mode 100644
index 9d308f1bca..0000000000
--- a/components/pthreads/pthread_rwlock.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __PTHREAD_RWLOCK_H__
-#define __PTHREAD_RWLOCK_H__
-
-#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
diff --git a/components/pthreads/pthread_spin.c b/components/pthreads/pthread_spin.c
index c38c611616..a9f0f4704a 100644
--- a/components/pthreads/pthread_spin.c
+++ b/components/pthreads/pthread_spin.c
@@ -1,4 +1,4 @@
-#include "pthread_spin.h"
+#include <pthread.h>
int pthread_spin_init (pthread_spinlock_t *lock, int pshared)
{
diff --git a/components/pthreads/pthread_spin.h b/components/pthreads/pthread_spin.h
deleted file mode 100644
index b870c4524c..0000000000
--- a/components/pthreads/pthread_spin.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef __PTHREAD_SPIN_H__
-#define __PTHREAD_SPIN_H__
-#include <pthread.h>
-
-/* spinlock implementation, (ADVANCED REALTIME THREADS)*/
-struct pthread_spinlock
-{
- int lock;
-};
-typedef struct pthread_spinlock pthread_spinlock_t;
-
-int pthread_spin_init (pthread_spinlock_t *lock, int pshared);
-int pthread_spin_destroy (pthread_spinlock_t *lock);
-
-int pthread_spin_lock (pthread_spinlock_t * lock);
-int pthread_spin_trylock (pthread_spinlock_t * lock);
-int pthread_spin_unlock (pthread_spinlock_t * lock);
-
-#endif
diff --git a/components/pthreads/pthread_tls.c b/components/pthreads/pthread_tls.c
index e69de29bb2..7efb0b3255 100644
--- a/components/pthreads/pthread_tls.c
+++ b/components/pthreads/pthread_tls.c
@@ -0,0 +1,19 @@
+#include <pthread.h>
+
+void *pthread_getspecific(pthread_key_t key)
+{
+}
+
+int pthread_setspecific(pthread_key_t key, const void *value)
+{
+}
+
+int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
+{
+ return 0;
+}
+
+int pthread_key_delete(pthread_key_t key)
+{
+ return 0;
+}
diff --git a/components/pthreads/pthread_tls.h b/components/pthreads/pthread_tls.h
deleted file mode 100644
index e69de29bb2..0000000000
--- a/components/pthreads/pthread_tls.h
+++ /dev/null