diff --git a/components/pthreads/SConscript b/components/pthreads/SConscript index 9fe796d22..5f017aea1 100644 --- a/components/pthreads/SConscript +++ b/components/pthreads/SConscript @@ -1,7 +1,20 @@ Import('RTT_ROOT') from building import * -src = Glob('*.c') +src = Split(''' +clock_time.c +pthread.c +pthread_attr.c +pthread_barrier.c +pthread_cond.c +pthread_internal.c +pthread_mutex.c +pthread_rwlock.c +pthread_spin.c +pthread_tls.c +sched.c +semaphore.c +''') CPPPATH = [RTT_ROOT + '/components/pthreads'] group = DefineGroup('pthreads', src, depend = ['RT_USING_PTHREADS'], CPPPATH = CPPPATH) diff --git a/components/pthreads/clock_time.c b/components/pthreads/clock_time.c new file mode 100644 index 000000000..4884d07fb --- /dev/null +++ b/components/pthreads/clock_time.c @@ -0,0 +1,27 @@ +#include +#include "pthread_internal.h" +#include + +int clock_getres(clockid_t clock_id, struct timespec *res) +{ + if ((clock_id != CLOCK_REALTIME) || (res == RT_NULL)) + { + rt_set_errno(EINVAL); + return -1; + } + + res->tv_sec = 0; + res->tv_nsec = NSEC_PER_TICK; + + return 0; +} + +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return 0; +} + +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return 0; +} diff --git a/components/pthreads/mqueue.c b/components/pthreads/mqueue.c new file mode 100644 index 000000000..849f5348e --- /dev/null +++ b/components/pthreads/mqueue.c @@ -0,0 +1,150 @@ +#include "mqueue.h" +#include +#include "pthread_internal.h" + +int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, + struct mq_attr *omqstat) +{ + rt_set_errno(-RT_ERROR); + return -1; +} + +int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat) +{ + if ((mqdes == RT_NULL) || mqstat == RT_NULL) + { + rt_set_errno(EBADF); + return -1; + } + + mqstat->mq_maxmsg = mqdes->max_msgs; + mqstat->mq_msgsize = mqdes->msg_size; + mqstat->mq_curmsgs = 0; + mqstat->mq_flags = 0; + + return 0; +} + +mqd_t mq_open(const char *name, int oflag, ...) +{ + rt_mq_t mq; + va_list arg; + mode_t mode; + struct mq_attr *attr = RT_NULL; + + if (oflag & O_CREAT) + { + va_start(arg, oflag); + mode = (mode_t) va_arg(arg, unsigned int); + attr = (struct mq_attr *) va_arg(arg, struct mq_attr *); + va_end(arg); + + mq = rt_mq_create(name, attr->mq_msgsize, attr->mq_maxmsg, RT_IPC_FLAG_FIFO); + if (mq == RT_NULL) /* create failed */ + { + rt_set_errno(ENFILE); + return RT_NULL; + } + } + + if (oflag & O_EXCL) + { + mq = (rt_mq_t)rt_object_find(name, RT_Object_Class_MessageQueue); + if (mq == RT_NULL) rt_set_errno(ENOSPC); + } + + return mq; +} + +ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio) +{ + rt_err_t result; + + if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL)) + { + rt_set_errno(EINVAL); + return -1; + } + + result = rt_mq_recv(mqdes, msg_ptr, msg_len, RT_WAITING_FOREVER); + if (result == RT_EOK) + return msg_len; + + rt_set_errno(EBADF); + return -1; +} + +int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio) +{ + rt_err_t result; + + if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL)) + { + rt_set_errno(EINVAL); + return -1; + } + + result = rt_mq_send(mqdes, msg_ptr, msg_len); + if (result == RT_EOK) + return 0; + + rt_set_errno(EBADF); + return -1; +} + +ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, + unsigned *msg_prio, const struct timespec *abs_timeout) +{ + int tick; + rt_err_t result; + + if ((mqdes == RT_NULL) || (msg_ptr == RT_NULL)) + { + rt_set_errno(EINVAL); + return -1; + } + tick = time_to_tick(abs_timeout); + + result = rt_mq_recv(mqdes, msg_ptr, msg_len, tick); + if (result == RT_EOK) return msg_len; + + if (result == -RT_ETIMEOUT) + rt_set_errno(ETIMEOUT); + else + rt_set_errno(EBADMSG); + + return -1; +} + +int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, + const struct timespec *abs_timeout) +{ + /* RT-Thread does not support timed send */ + return mq_send(mqdes, msg_ptr, msg_len, msg_prio); +} + +int mq_notify(mqd_t mqdes, const struct sigevent *notification) +{ + rt_set_errno(-RT_ERROT); + return -1; +} + +int mq_close(mqd_t mqdes) +{ + return 0; +} + +int mq_unlink(const char *name) +{ + rt_mq_t mq; + + mq = (rt_mq_t)rt_object_find(name, RT_Object_Class_MessageQueue); + if (mq == RT_NULL) + { + rt_set_errno(ENOENT); + return -1; + } + + rt_mq_delete(mq); + return 0; +} diff --git a/components/pthreads/mqueue.h b/components/pthreads/mqueue.h new file mode 100644 index 000000000..901b1bed5 --- /dev/null +++ b/components/pthreads/mqueue.h @@ -0,0 +1,33 @@ +#ifndef __MQUEUE_H__ +#define __MQUEUE_H__ + +#include +#include +#include +#include + +typedef rt_mq_t mqd_t; +struct mq_attr +{ + long mq_flags; /* Message queue flags. */ + long mq_maxmsg; /* Maximum number of messages. */ + long mq_msgsize; /* Maximum message size. */ + long mq_curmsgs; /* Number of messages currently queued. */ +}; + +int mq_close(mqd_t mqdes); +int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat); +int mq_notify(mqd_t mqdes, const struct sigevent *notification); +mqd_t mq_open(const char *name, int oflag, ...); +ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio); +int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio); +int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, + struct mq_attr *omqstat); +ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, + unsigned *msg_prio, const struct timespec *abs_timeout); +int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, + const struct timespec *abs_timeout); + +int mq_unlink(const char *name); + +#endif diff --git a/components/pthreads/pthread_internal.h b/components/pthreads/pthread_internal.h index 9f3210569..47c745e69 100644 --- a/components/pthreads/pthread_internal.h +++ b/components/pthreads/pthread_internal.h @@ -53,4 +53,6 @@ rt_inline _pthread_data_t* _pthread_get_data(pthread_t thread) return (_pthread_data_t*)thread->user_data; } +#define NSEC_PER_TICK (1000000000UL/RT_TICK_PER_SECOND) + #endif diff --git a/components/pthreads/semaphore.c b/components/pthreads/semaphore.c index 8fbf243c7..f80e0f8ec 100644 --- a/components/pthreads/semaphore.c +++ b/components/pthreads/semaphore.c @@ -58,16 +58,12 @@ int sem_init(sem_t *sem, int pshared, unsigned int value) 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) + if (oflag & O_CREAT) { sem = rt_sem_create(name, 1, RT_IPC_FLAG_FIFO); if (sem == RT_NULL) @@ -75,35 +71,10 @@ sem_t *sem_open(const char *name, int oflag, ...) } /* find semaphore */ - if (oflag == O_EXCL) + 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; + sem = (rt_sem_t)rt_object_find(name, RT_Object_Class_Semaphore); + if (sem == RT_NULL) rt_set_errno(ENOSPC); } return sem;