summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author[email protected] <[email protected]>2010-11-17 23:35:13 +0000
committer[email protected] <[email protected]>2010-11-17 23:35:13 +0000
commit32f65989126fbe1fb31013c577c11bbaa46a5e72 (patch)
treec321bc5fca933c6d181d4d236873e481b0f56218
parent5c148b670581c6b27b184ee28cd17a5b9deaf068 (diff)
add semaphore and sched implementation.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1056 bbd45198-f89e-11dd-88c7-29a3b14d5316
-rw-r--r--components/pthreads/pthread.c1
-rw-r--r--components/pthreads/pthread.h11
-rw-r--r--components/pthreads/pthread_attr.c1
-rw-r--r--components/pthreads/pthread_cond.c2
-rw-r--r--components/pthreads/pthread_test.c127
-rw-r--r--components/pthreads/sched.c28
-rw-r--r--components/pthreads/sched.h37
-rw-r--r--components/pthreads/sem.c98
-rw-r--r--components/pthreads/semaphore.c156
-rw-r--r--components/pthreads/semaphore.h (renamed from components/pthreads/sem.h)0
10 files changed, 224 insertions, 237 deletions
diff --git a/components/pthreads/pthread.c b/components/pthreads/pthread.c
index b2544ab320..e3958a5e20 100644
--- a/components/pthreads/pthread.c
+++ b/components/pthreads/pthread.c
@@ -1,4 +1,5 @@
#include <pthread.h>
+#include <sched.h>
#include "pthread_internal.h"
int pthread_system_init(void)
diff --git a/components/pthreads/pthread.h b/components/pthreads/pthread.h
index 5dab979c4e..9eb6c828f8 100644
--- a/components/pthreads/pthread.h
+++ b/components/pthreads/pthread.h
@@ -39,13 +39,6 @@ typedef long pthread_barrierattr_t;
typedef int pthread_key_t;
typedef int pthread_once_t;
-/*
- * Scheduling policies required by IEEE Std 1003.1-2001
- */
-#define SCHED_OTHER 0 /* Behavior can be FIFO or RR, or not */
-#define SCHED_FIFO 1
-#define SCHED_RR 2
-
enum {
PTHREAD_CANCEL_ASYNCHRONOUS = 0,
PTHREAD_CANCEL_ENABLE,
@@ -78,10 +71,6 @@ enum {
#define PTHREAD_SCOPE_PROCESS 0
#define PTHREAD_SCOPE_SYSTEM 1
-struct sched_param {
- int sched_priority;
-};
-
struct pthread_attr
{
void* stack_base;
diff --git a/components/pthreads/pthread_attr.c b/components/pthreads/pthread_attr.c
index 02b9ec6cdd..706e4819c3 100644
--- a/components/pthreads/pthread_attr.c
+++ b/components/pthreads/pthread_attr.c
@@ -1,5 +1,6 @@
#include <rtthread.h>
#include "pthread.h"
+#include "sched.h"
#include <string.h>
#define DEFAULT_STACK_SIZE 2048
diff --git a/components/pthreads/pthread_cond.c b/components/pthreads/pthread_cond.c
index c4e876f49c..d737955dbe 100644
--- a/components/pthreads/pthread_cond.c
+++ b/components/pthreads/pthread_cond.c
@@ -148,7 +148,7 @@ rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
result = rt_sem_take(&(cond->sem), timeout);
/* lock mutex again */
- pthred_mutex_lock(mutex);
+ pthread_mutex_lock(mutex);
return result;
}
diff --git a/components/pthreads/pthread_test.c b/components/pthreads/pthread_test.c
deleted file mode 100644
index 14c07e9249..0000000000
--- a/components/pthreads/pthread_test.c
+++ /dev/null
@@ -1,127 +0,0 @@
-#include <pthread.h>
-#include <finsh.h>
-
-#define _die_(x) do { rt_kprintf(x); RT_ASSERT(0); } while (0)
-#define pr(x) do { rt_kprintf(x); } while (0)
-#define sleep(n) rt_thread_sleep((n * RT_TICK_PER_SECOND)/1000)
-#define alarm(n)
-
-/* (0) once test */
-void test0_ok() { pr("(once called) "); }
-void test0_failed() { _die_("failed...\n"); }
-void pth_t0() {
- pthread_once_t v_once=PTHREAD_ONCE_INIT;
- pr("\nTEST 0: once test:\n\n");
- pr("testing once function... ");
- pthread_once(&v_once,test0_ok);
- pthread_once(&v_once,test0_failed);
- pr("OK.\n");
-}
-FINSH_FUNCTION_EXPORT(pth_t0, pthread testcase0);
-
-/* (1) mutex tests */
-void test_rec_mutex() {
- pthread_mutex_t tm;
- pthread_mutexattr_t ta;
- pthread_mutexattr_settype(&ta, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&tm, &ta);
- pr("testing recursive mutex... ");
- alarm(5);
- if (pthread_mutex_lock(&tm) != 0) _die_("failed... mutex_lock on unused rec-mutex (c=0)...\n");
- if (tm.lock.owner!=pthread_self()) _die_("failed.. wrong owner....\n");
- if (tm.lock.hold!=1) _die_("failed... wrong counting (c!=1)....\n");
- if (pthread_mutex_lock(&tm) != 0) _die_("failed... mutex_lock on taken rec-mutex (c=1)...\n");
- if (tm.lock.hold!=2) _die_("failed... wrong counting (c!=2)....\n");
- if (pthread_mutex_lock(&tm) != 0) _die_("failed... mutex_lock on taken rec-mutex (c=2)...\n");
- if (tm.lock.hold!=3) _die_("failed... wrong counting (c!=3)....\n");
- if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on taken rec-mutex (c=3)...\n");
- if (tm.lock.hold!=2) _die_("failed... wrong counting (c!=2)....\n");
- if (tm.lock.owner==0) _die_("failed... mutex has no owner?!?!\n");
- if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on taken rec-mutex (c=2)...\n");
- if (tm.lock.hold!=1) _die_("failed... wrong counting (c!=1)....\n");
- if (tm.lock.owner==0) _die_("failed... mutex has no owner?!?!\n");
- if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on taken rec-mutex (c=1)...\n");
- if (tm.lock.hold!=0) _die_("failed... wrong counting (c!=0)....\n");
- if (tm.lock.owner!=0) _die_("failed... mutex still owned ?!?!\n");
- if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on free rec-mutex (c=0)...\n");
- alarm(0);
- pr("OK.\n");
-}
-
-void test_err_mutex() {
- pthread_mutex_t tm;
- pthread_mutexattr_t ta;
-
- pthread_mutexattr_settype(&ta, PTHREAD_MUTEX_ERRORCHECK);
- pthread_mutex_init(&tm, &ta);
- pr("testing errorcheck mutex... ");
- alarm(5);
- if (pthread_mutex_lock(&tm) != 0) _die_("failed... mutex_lock on unused errchk-mutex...\n");
- if (tm.lock.owner!=pthread_self()) _die_("failed.. wrong owner....\n");
- if (pthread_mutex_lock(&tm) != EDEADLK) _die_("failed... mutex_lock on taken errchk-mutex...\n");
- if (pthread_mutex_unlock(&tm) != 0) _die_("failed... mutex_unlock on taken errchk-mutex...\n");
- if (tm.lock.owner!=0) _die_("failed... mutex still owned ?!?!\n");
- if (pthread_mutex_unlock(&tm) != EPERM) _die_("failed... mutex_unlock on free errchk-mutex...\n");
- alarm(0);
- pr("OK.\n");
-}
-
-void pth_t1() {
- pr("\nTEST 1: mutex test:\n\n");
- test_rec_mutex();
- test_err_mutex();
-}
-FINSH_FUNCTION_EXPORT(pth_t1, pthread testcase0);
-
-void* thread(void*arg)
-{
- if (0) { arg=0; }
- pr("(thread created) ");
- sleep(1);
- pr("(thread exit) ");
- return 0;
-}
-
-void test_thread() {
- pthread_t t;
- pr("testing basic thread creation and join... ");
- if ((pthread_create(&t,0,thread,0))!=0) _die_("failed...\n");
- if (pthread_join(t,0) != 0) _die_("failed... joining thread\n");
- pr("OK.\n");
-}
-
-void test_thread_join_detached() {
- pthread_t t;
- pthread_attr_t attr;
- pr("testing for failing join of a detached thread... ");
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
- if ((pthread_create(&t,&attr,thread,0))!=0) _die_("failed...\n");
- if (pthread_join(t,0) == 0) _die_("failed... I had joined a detached thread !\n");
- sleep(2);
- pr("OK.\n");
-}
-
-static char alt_stack[4096];
-void test_thread_alt_stack() {
- pthread_t t;
- pthread_attr_t attr;
- pr("testing alternate thread stack... ");
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr,sizeof(alt_stack));
- if ((pthread_create(&t,&attr,thread,0))!=0) _die_("failed... creating thread\n");
- if (pthread_join(t,0) != 0) _die_("failed... joining thread\n");
- pthread_attr_setstackaddr(&attr,alt_stack);
- if ((pthread_create(&t,&attr,thread,0))!=0) _die_("failed... creating thread\n");
- if (pthread_join(t,0) != 0) _die_("failed... joining thread\n");
- pr("OK.\n");
-}
-
-void pth_t2()
-{
- pr("\nTEST 2: thread creation & attributes:\n\n");
- test_thread();
- test_thread_join_detached();
- test_thread_alt_stack();
-}
-FINSH_FUNCTION_EXPORT(pth_t2, pthread testcase1);
diff --git a/components/pthreads/sched.c b/components/pthreads/sched.c
new file mode 100644
index 0000000000..f0dcedbfb7
--- /dev/null
+++ b/components/pthreads/sched.c
@@ -0,0 +1,28 @@
+#include <sched.h>
+
+int sched_yield(void)
+{
+ rt_thread_yield();
+ return 0;
+}
+
+int sched_get_priority_min(int policy)
+{
+ if (policy != SCHED_FIFO && policy != SCHED_RR)
+ return EINVAL;
+
+ return 0;
+}
+
+int sched_get_priority_max(int policy)
+{
+ if (policy != SCHED_FIFO && policy != SCHED_RR)
+ return EINVAL;
+
+ return RT_THREAD_PRIORITY_MAX - 1;
+}
+
+int sched_setscheduler(pid_t pid, int policy)
+{
+ return ENOTSUP;
+}
diff --git a/components/pthreads/sched.h b/components/pthreads/sched.h
new file mode 100644
index 0000000000..7d8e501cd6
--- /dev/null
+++ b/components/pthreads/sched.h
@@ -0,0 +1,37 @@
+#ifndef __SCHED_H__
+#define __SCHED_H__
+
+#include <rtthread.h>
+#include <sys/types.h>
+#include <errno.h>
+
+/* Thread scheduling policies */
+enum
+{
+ SCHED_OTHER = 0,
+ SCHED_FIFO,
+ SCHED_RR,
+ SCHED_MIN = SCHED_OTHER,
+ SCHED_MAX = SCHED_RR
+};
+
+struct sched_param
+{
+ int sched_priority;
+};
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int sched_yield(void);
+int sched_get_priority_min(int policy);
+int sched_get_priority_max(int policy);
+int sched_setscheduler(pid_t pid, int policy);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/pthreads/sem.c b/components/pthreads/sem.c
deleted file mode 100644
index e4cecab69a..0000000000
--- a/components/pthreads/sem.c
+++ /dev/null
@@ -1,98 +0,0 @@
-#include <errno.h>
-#include <sys/fcntl.h>
-
-#include "sem.h"
-
-int sem_close(sem_t *sem)
-{
-}
-
-int sem_destroy(sem_t *sem)
-{
-}
-
-int sem_unlink(const char *name)
-{
- return EACCES;
-}
-
-int sem_getvalue(sem_t *sem, int *sval)
-{
- RT_ASSERT(sem != RT_NULL);
- if (sval) *sval = sem->value;
-}
-
-int sem_init(sem_t *sem, int pshared, unsigned int value)
-{
- RT_ASSERT(sem != RT_NULL);
-}
-
-sem_t *sem_open(const char *name, int oflag, ...)
-{
- rt_sem_t sem;
-
- sem = RT_NULL;
- if (oflag == O_CREAT)
- {
- sem = rt_sem_create(name, 1, RT_IPC_FLAG_FIFO);
- if (sem == RT_NULL)
- rt_set_errno(ENOSPC);
- }
-
- if (oflag == O_EXCL)
- {
- rt_enter_critical();
- /* find semaphore object */
- rt_exit_critical();
-
- if (sem == RT_NULL) rt_set_errno(ENOENT);
- }
-
- return sem;
-}
-
-int sem_post(sem_t *sem)
-{
- rt_sem_release(sem);
-}
-
-int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
-{
- rt_err_t result;
- rt_int32_t tick;
-
- if (!sem || !abs_timeout) return EINVAL;
-
- /* calculate os tick */
- tick = abs_timeout->tv_sec/RT_TICK_PER_SECOND + (abs_timeout->tv_nsec/1000) * (1000/RT_TICK_PER_SECOND);
-
- result = rt_sem_take(sem, tick);
- if (result == -RT_ETIMEOUT) return ETIMEDOUT;
- if (result == RT_EOK) return 0;
-
- return EINTR;
-}
-
-int sem_trywait(sem_t *sem)
-{
- rt_err_t result;
-
- if (!sem) return EINVAL;
-
- result = rt_sem_take(sem, RT_WAITING_FOREVER);
- if (result == -RT_ETIMEOUT) return EAGAIN;
- if (result == RT_EOK) return 0;
-
- return EINTR;
-}
-
-int sem_wait(sem_t *sem)
-{
- rt_err_t result;
-
- result = rt_sem_take(sem, RT_WAITING_FOREVER);
- if (result == RT_EOK) return 0;
-
- return EINTR;
-}
-
diff --git a/components/pthreads/semaphore.c b/components/pthreads/semaphore.c
new file mode 100644
index 0000000000..8fbf243c70
--- /dev/null
+++ b/components/pthreads/semaphore.c
@@ -0,0 +1,156 @@
+#include <errno.h>
+#include <sys/fcntl.h>
+
+#include <rtthread.h>
+#include "semaphore.h"
+
+int sem_close(sem_t *sem)
+{
+ if (!sem) return EINVAL;
+
+ /* delete semaphore allocated in sem_open */
+ rt_sem_delete(sem);
+ return 0;
+}
+
+int sem_destroy(sem_t *sem)
+{
+ rt_err_t result;
+
+ if (!sem) return EINVAL;
+
+ /* check whether semaphore is busy or not */
+ result = rt_sem_trytake(sem);
+ if (result != RT_EOK) return EBUSY;
+
+ rt_memset(sem, 0, sizeof(sem_t));
+ return 0;
+}
+
+int sem_unlink(const char *name)
+{
+ return EACCES;
+}
+
+int sem_getvalue(sem_t *sem, int *sval)
+{
+ RT_ASSERT(sem != RT_NULL);
+ if (sval) *sval = sem->value;
+}
+
+int sem_init(sem_t *sem, int pshared, unsigned int value)
+{
+ rt_err_t result;
+ char name[RT_NAME_MAX];
+ static rt_uint16_t psem_number = 0;
+
+ RT_ASSERT(sem != RT_NULL);
+
+ rt_snprintf(name, sizeof(name), "psem%02d", psem_number++);
+ result = rt_sem_init(sem, name, value, RT_IPC_FLAG_FIFO);
+ if (result == RT_EOK)
+ {
+ /* detach kernel object */
+ rt_object_detach(&(sem->parent.parent));
+ return 0;
+ }
+
+ return ENOSPC;
+}
+
+/* introduce from kservice.c */
+#define rt_list_entry(node, type, member) \
+ ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
+
+sem_t *sem_open(const char *name, int oflag, ...)
+{
+ rt_sem_t sem;
+
+ sem = RT_NULL;
+ if (oflag == O_CREAT)
+ {
+ sem = rt_sem_create(name, 1, RT_IPC_FLAG_FIFO);
+ if (sem == RT_NULL)
+ rt_set_errno(ENOSPC);
+ }
+
+ /* find semaphore */
+ if (oflag == O_EXCL)
+ {
+ struct rt_object* object;
+ struct rt_list_node* node;
+ struct rt_object_information *information;
+ extern struct rt_object_information rt_object_container[];
+
+ /* enter critical */
+ rt_enter_critical();
+
+ /* try to find device object */
+ information = &rt_object_container[RT_Object_Class_Semaphore];
+ for (node = information->object_list.next; node != &(information->object_list); node = node->next)
+ {
+ object = rt_list_entry(node, struct rt_object, list);
+ if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
+ {
+ /* leave critical */
+ rt_exit_critical();
+
+ return (rt_sem_t)object;
+ }
+ }
+
+ /* leave critical */
+ rt_exit_critical();
+ rt_set_errno(ENOENT);
+
+ return RT_NULL;
+ }
+
+ return sem;
+}
+
+int sem_post(sem_t *sem)
+{
+ rt_sem_release(sem);
+}
+
+int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
+{
+ rt_err_t result;
+ rt_int32_t tick;
+
+ if (!sem || !abs_timeout) return EINVAL;
+
+ /* calculate os tick */
+ tick = abs_timeout->tv_sec/RT_TICK_PER_SECOND + (abs_timeout->tv_nsec/1000) * (1000/RT_TICK_PER_SECOND);
+
+ result = rt_sem_take(sem, tick);
+ if (result == -RT_ETIMEOUT) return ETIMEDOUT;
+ if (result == RT_EOK) return 0;
+
+ return EINTR;
+}
+
+int sem_trywait(sem_t *sem)
+{
+ rt_err_t result;
+
+ if (!sem) return EINVAL;
+
+ result = rt_sem_take(sem, RT_WAITING_FOREVER);
+ if (result == -RT_ETIMEOUT) return EAGAIN;
+ if (result == RT_EOK) return 0;
+
+ return EINTR;
+}
+
+int sem_wait(sem_t *sem)
+{
+ rt_err_t result;
+
+ result = rt_sem_take(sem, RT_WAITING_FOREVER);
+ if (result == RT_EOK) return 0;
+
+ return EINTR;
+}
+
diff --git a/components/pthreads/sem.h b/components/pthreads/semaphore.h
index 29e2911a54..29e2911a54 100644
--- a/components/pthreads/sem.h
+++ b/components/pthreads/semaphore.h