diff --git a/components/pthreads/pthread.c b/components/pthreads/pthread.c index b2544ab320cbd18be2c1ff427ca413c16afb40a4..e3958a5e2044530923d39bfd66f7999f23be4764 100644 --- a/components/pthreads/pthread.c +++ b/components/pthreads/pthread.c @@ -1,4 +1,5 @@ #include +#include #include "pthread_internal.h" int pthread_system_init(void) diff --git a/components/pthreads/pthread.h b/components/pthreads/pthread.h index 5dab979c4efc8d83686031f3ea4e8a0960a836b0..9eb6c828f89f515e1fbd36e75f217d0deed43c7b 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 02b9ec6cddd61fb6139ee831de5b32b549e7b127..706e4819c35b10e84ccbee45443f54c8d2d9e0f4 100644 --- a/components/pthreads/pthread_attr.c +++ b/components/pthreads/pthread_attr.c @@ -1,5 +1,6 @@ #include #include "pthread.h" +#include "sched.h" #include #define DEFAULT_STACK_SIZE 2048 diff --git a/components/pthreads/pthread_cond.c b/components/pthreads/pthread_cond.c index c4e876f49cd05e033716e55e79fc6444d4371018..d737955dbefe411ca4d99bc2d03aee3a9a3d964e 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 14c07e92491a6d310bd7942a5a2abba15034f5e0..0000000000000000000000000000000000000000 --- a/components/pthreads/pthread_test.c +++ /dev/null @@ -1,127 +0,0 @@ -#include -#include - -#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 0000000000000000000000000000000000000000..f0dcedbfb72fadf2572b92d79217dcb2a67dec52 --- /dev/null +++ b/components/pthreads/sched.c @@ -0,0 +1,28 @@ +#include + +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 0000000000000000000000000000000000000000..7d8e501cd68fc83f0ffed641a9ca419a8f35578d --- /dev/null +++ b/components/pthreads/sched.h @@ -0,0 +1,37 @@ +#ifndef __SCHED_H__ +#define __SCHED_H__ + +#include +#include +#include + +/* 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 e4cecab69a711a9fd915d6827ccc9b8e3cab5134..0000000000000000000000000000000000000000 --- a/components/pthreads/sem.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include - -#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 0000000000000000000000000000000000000000..8fbf243c70931f27626b523bdee8ca2bf0b5c1c6 --- /dev/null +++ b/components/pthreads/semaphore.c @@ -0,0 +1,156 @@ +#include +#include + +#include +#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 similarity index 100% rename from components/pthreads/sem.h rename to components/pthreads/semaphore.h