diff options
| author | [email protected] <[email protected]> | 2010-11-17 23:35:13 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2010-11-17 23:35:13 +0000 |
| commit | 32f65989126fbe1fb31013c577c11bbaa46a5e72 (patch) | |
| tree | c321bc5fca933c6d181d4d236873e481b0f56218 /components/pthreads | |
| parent | 5c148b670581c6b27b184ee28cd17a5b9deaf068 (diff) | |
add semaphore and sched implementation.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1056 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/pthreads')
| -rw-r--r-- | components/pthreads/pthread.c | 1 | ||||
| -rw-r--r-- | components/pthreads/pthread.h | 11 | ||||
| -rw-r--r-- | components/pthreads/pthread_attr.c | 1 | ||||
| -rw-r--r-- | components/pthreads/pthread_cond.c | 2 | ||||
| -rw-r--r-- | components/pthreads/pthread_test.c | 127 | ||||
| -rw-r--r-- | components/pthreads/sched.c | 28 | ||||
| -rw-r--r-- | components/pthreads/sched.h | 37 | ||||
| -rw-r--r-- | components/pthreads/sem.c | 98 | ||||
| -rw-r--r-- | components/pthreads/semaphore.c | 156 | ||||
| -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 |
