Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources
This commit is contained in:
182
sdk/lib/posix/mqueue.c
Normal file
182
sdk/lib/posix/mqueue.c
Normal file
@@ -0,0 +1,182 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "osal/msgqueue.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
struct pthread_mq {
|
||||
char name[32];
|
||||
uint32 unlink: 1, rev: 31;
|
||||
struct pthread_mq *next;
|
||||
os_msgqueue_t msgq;
|
||||
};
|
||||
|
||||
struct pthread_mq_data {
|
||||
void *data;
|
||||
uint32 len;
|
||||
};
|
||||
|
||||
static struct pthread_mq *mq_list = NULL;
|
||||
|
||||
static struct pthread_mq *mq_list_find(const char *name, uint8 unlink)
|
||||
{
|
||||
struct pthread_mq *prev = NULL;
|
||||
struct pthread_mq *next = NULL;
|
||||
uint32 flag = disable_irq();
|
||||
next = mq_list;
|
||||
while (next) {
|
||||
if (os_strcmp(next->name, name) == 0) {
|
||||
if (unlink) {
|
||||
if (prev == NULL) {
|
||||
mq_list = next->next;
|
||||
} else {
|
||||
prev->next = next->next;
|
||||
}
|
||||
next->unlink = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
enable_irq(flag);
|
||||
return next;
|
||||
}
|
||||
|
||||
static void mq_list_add(struct pthread_mq *mq)
|
||||
{
|
||||
uint32 flag = disable_irq();
|
||||
mq->next = mq_list;
|
||||
mq_list = mq;
|
||||
enable_irq(flag);
|
||||
}
|
||||
|
||||
int mq_close(mqd_t mqdes)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
mqd_t mq_open(const char *name, int oflag, int mode, struct mq_attr *attr)
|
||||
{
|
||||
struct pthread_mq *mq = mq_list_find(name, 0);
|
||||
if (mq) {
|
||||
return (mqd_t)mq;
|
||||
} else {
|
||||
mq = (struct pthread_mq *)os_zalloc(sizeof(struct pthread_mq));
|
||||
if (mq == NULL) {
|
||||
pthread_err("alloc fail\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
os_strncpy(mq->name, name, 31);
|
||||
os_msgq_init(&mq->msgq, attr ? attr->mq_msgsize : 32);
|
||||
mq_list_add(mq);
|
||||
return (mqd_t)mq;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 _mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int tmo)
|
||||
{
|
||||
struct pthread_mq_data *val;
|
||||
struct pthread_mq *mq = (struct pthread_mq *)mqdes;
|
||||
|
||||
if (mq->unlink) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
val = (struct pthread_mq_data *)os_msgq_get(&mq->msgq, tmo);
|
||||
if (val) {
|
||||
if (msg_len >= val->len) {
|
||||
os_memcpy(msg_ptr, val->data, val->len);
|
||||
} else {
|
||||
pthread_err("msg_len(%d) < val_len(%d)\r\n", msg_len, val->len);
|
||||
}
|
||||
os_free(val->data);
|
||||
os_free(val);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int tmo)
|
||||
{
|
||||
int ret;
|
||||
struct pthread_mq *mq = (struct pthread_mq *)mqdes;
|
||||
struct pthread_mq_data *val;
|
||||
|
||||
if (mq->unlink) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
val = os_malloc(sizeof(struct pthread_mq_data));
|
||||
if (val) {
|
||||
val->data = os_memdup(msg_ptr, msg_len);
|
||||
if (val->data) {
|
||||
ret = os_msgq_put(&mq->msgq, (uint32)val, tmo);
|
||||
if (ret == 0) {
|
||||
return RET_OK;
|
||||
}
|
||||
os_free(val->data);
|
||||
} else {
|
||||
pthread_err("alloc fail\r\n");
|
||||
}
|
||||
os_free(val);
|
||||
} else {
|
||||
pthread_err("alloc fail\r\n");
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio)
|
||||
{
|
||||
return _mq_receive(mqdes, msg_ptr, msg_len, osWaitForever);
|
||||
}
|
||||
|
||||
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
|
||||
{
|
||||
return _mq_send(mqdes, msg_ptr, msg_len, osWaitForever);
|
||||
}
|
||||
|
||||
int mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abstime)
|
||||
{
|
||||
return _mq_receive(mqdes, msg_ptr, msg_len, pthread_timespec_delta(abstime));
|
||||
}
|
||||
|
||||
int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abstime)
|
||||
{
|
||||
return _mq_send(mqdes, msg_ptr, msg_len, pthread_timespec_delta(abstime));
|
||||
}
|
||||
|
||||
int mq_unlink(const char *name)
|
||||
{
|
||||
struct pthread_mq_data *val;
|
||||
struct pthread_mq *mq = mq_list_find(name, 1);
|
||||
if (mq) {
|
||||
while (os_msgq_cnt(&mq->msgq) > 0) {
|
||||
val = (struct pthread_mq_data *)os_msgq_get(&mq->msgq, 0);
|
||||
if (val) {
|
||||
os_free(val->data);
|
||||
os_free(val);
|
||||
}
|
||||
}
|
||||
os_msgq_del(&mq->msgq);
|
||||
os_free(mq);
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#endif
|
||||
77
sdk/lib/posix/posix_test.c
Normal file
77
sdk/lib/posix/posix_test.c
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "osal/msgqueue.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
#include "osal/sleep.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
pthread_cond_t c;
|
||||
void posix_mutex_test(void)
|
||||
{
|
||||
pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_t m2;
|
||||
pthread_mutex_init(&m2, NULL);
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
os_printf("posix_mutex_test %d\n", i);
|
||||
pthread_mutex_lock(&m1);
|
||||
pthread_mutex_unlock(&m1);
|
||||
|
||||
pthread_mutex_lock(&m2);
|
||||
pthread_mutex_unlock(&m2);
|
||||
}
|
||||
}
|
||||
|
||||
void posix_cond_test(void)
|
||||
{
|
||||
pthread_mutex_t m;
|
||||
pthread_mutex_init(&m, NULL);
|
||||
|
||||
pthread_cond_init(&c, NULL);
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
os_printf("posix_mutex_test %d\n", i);
|
||||
pthread_mutex_lock(&m);
|
||||
pthread_cond_wait(&c, &m);
|
||||
pthread_mutex_unlock(&m);
|
||||
}
|
||||
}
|
||||
|
||||
static void *pthread_test_task(void *arg)
|
||||
{
|
||||
os_printf(KERN_NOTICE"pthread_test_task running ...\r\n");
|
||||
if (arg) {
|
||||
os_sleep(10);
|
||||
os_printf(KERN_NOTICE"pthread_test_task join!\r\n");
|
||||
pthread_join((pthread_t)arg, NULL);
|
||||
} else {
|
||||
os_sleep(20);
|
||||
}
|
||||
os_printf(KERN_NOTICE"pthread_test_task exit!\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void posix_pthread_test(void)
|
||||
{
|
||||
pthread_t pthd1, pthd2;
|
||||
pthread_attr_t attr1, attr2;
|
||||
pthread_attr_init(&attr1);
|
||||
pthread_attr_init(&attr2);
|
||||
pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
|
||||
pthread_attr_setdetachstate(&attr2, PTHREAD_CREATE_JOINABLE);
|
||||
os_printf("posix test start!\r\n");
|
||||
pthread_create(&pthd2, &attr2, pthread_test_task, 0);
|
||||
pthread_create(&pthd1, &attr1, pthread_test_task, (void *)pthd2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
269
sdk/lib/posix/pthread.c
Normal file
269
sdk/lib/posix/pthread.c
Normal file
@@ -0,0 +1,269 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
#include "osal/sleep.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
#define PTHREAD_MAX (32)
|
||||
|
||||
struct pthread_task {
|
||||
char name[11];
|
||||
uint8 inited;
|
||||
void *task_hdl;
|
||||
os_semaphore_t join_sema;
|
||||
pthread_attr_t attr;
|
||||
void *arg;
|
||||
void *(*start)(void *);
|
||||
void *tls;
|
||||
} ;
|
||||
|
||||
static pthread_t pthreads[PTHREAD_MAX];
|
||||
|
||||
static int32 pthread_set(pthread_t thread)
|
||||
{
|
||||
int32 i = 0;
|
||||
uint32 flag = disable_irq();
|
||||
for (i = 0; thread && i < PTHREAD_MAX; i++) {
|
||||
if (0 == pthreads[i]) {
|
||||
pthreads[i] = thread;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enable_irq(flag);
|
||||
return (thread && i < PTHREAD_MAX);
|
||||
}
|
||||
|
||||
static struct pthread_task *pthread_get(void *thread)
|
||||
{
|
||||
int32 i = 0;
|
||||
struct pthread_task *thd = NULL;
|
||||
uint32 flag = disable_irq();
|
||||
for (i = 0; thread && i < PTHREAD_MAX; i++) {
|
||||
if (thread == pthreads[i]) {
|
||||
thd = (struct pthread_task *)thread;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enable_irq(flag);
|
||||
return thd;
|
||||
}
|
||||
|
||||
static void pthread_del(pthread_t thread)
|
||||
{
|
||||
int32 i = 0;
|
||||
uint32 flag = disable_irq();
|
||||
for (i = 0; i < PTHREAD_MAX; i++) {
|
||||
if (thread == pthreads[i]) {
|
||||
pthreads[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enable_irq(flag);
|
||||
}
|
||||
|
||||
static void pthread_free(struct pthread_task *thd)
|
||||
{
|
||||
pthread_del((pthread_t)thd);
|
||||
os_sema_del(&thd->join_sema);
|
||||
pthread_key_destroy(thd->tls);
|
||||
os_free(thd->tls);
|
||||
os_free(thd);
|
||||
}
|
||||
|
||||
static void pthread_task_entry(void *args)
|
||||
{
|
||||
struct pthread_task *thd = (struct pthread_task *)args;
|
||||
thd->start(thd->arg);
|
||||
while(!thd->inited) os_sleep_ms(5);
|
||||
if (thd->attr.detachstate == PTHREAD_CREATE_JOINABLE) {
|
||||
pthread_dbg("pthread %s exit: JOINABLE!\r\n", thd->name);
|
||||
os_sema_up(&thd->join_sema);
|
||||
} else {
|
||||
pthread_dbg("pthread %s exit: DETACHED!\r\n", thd->name);
|
||||
pthread_free(thd);
|
||||
}
|
||||
}
|
||||
|
||||
static int pthread_priority(pthread_attr_t *attr)
|
||||
{
|
||||
if (attr) {
|
||||
if (attr->schedparam.sched_priority == 0) {
|
||||
return OS_TASK_PRIORITY_NORMAL;
|
||||
} else if (attr->schedparam.sched_priority <= 20) {
|
||||
return OS_TASK_PRIORITY_LOW + attr->schedparam.sched_priority / 2;
|
||||
} else if (attr->schedparam.sched_priority <= 40) {
|
||||
return OS_TASK_PRIORITY_BELOW_NORMAL + (attr->schedparam.sched_priority - 20) / 2;
|
||||
} else if (attr->schedparam.sched_priority <= 60) {
|
||||
return OS_TASK_PRIORITY_NORMAL + (attr->schedparam.sched_priority - 40) / 2;
|
||||
} else {
|
||||
return OS_TASK_PRIORITY_ABOVE_NORMAL + (attr->schedparam.sched_priority - 60) / 4;
|
||||
}
|
||||
}
|
||||
return OS_TASK_PRIORITY_NORMAL;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start)(void *), void *arg)
|
||||
{
|
||||
struct pthread_task *thd = os_zalloc(sizeof(struct pthread_task));
|
||||
if (thd == NULL) {
|
||||
pthread_err("alloc fail\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!pthread_set((pthread_t)thd)) {
|
||||
pthread_err("no free pthread, max %d\r\n", PTHREAD_MAX);
|
||||
os_free(thd);
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
if (attr) {
|
||||
thd->attr = *attr;
|
||||
if (attr->schedparam.sched_priority > 99) {
|
||||
thd->attr.schedparam.sched_priority = 99;
|
||||
}
|
||||
} else {
|
||||
pthread_attr_init(&thd->attr);
|
||||
}
|
||||
|
||||
os_sema_init(&thd->join_sema, 0);
|
||||
thd->arg = arg;
|
||||
thd->start = start;
|
||||
os_sprintf(thd->name, "p_%x", (uint32)start);
|
||||
thd->task_hdl = os_task_create(thd->name, pthread_task_entry, thd, pthread_priority(&thd->attr), 0, NULL, thd->attr.stacksize);
|
||||
*thread = (pthread_t)thd;
|
||||
thd->inited = 1;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
pthread_t pthread_self(void)
|
||||
{
|
||||
pthread_t thd = (pthread_t)os_task_data(os_task_current());
|
||||
return (pthread_t)pthread_get(thd);
|
||||
}
|
||||
|
||||
int pthread_join(pthread_t thread, void **value_ptr)
|
||||
{
|
||||
struct pthread_task *thd = pthread_get(thread);
|
||||
if (thd) {
|
||||
if (thread == pthread_self()) {
|
||||
pthread_err("pthread_join self!\r\n");
|
||||
return -EDEADLK;
|
||||
}
|
||||
if (thd->attr.detachstate == PTHREAD_CREATE_DETACHED) {
|
||||
pthread_err("pthread_join DETACHED thread!\r\n");
|
||||
return -EINVAL; /* join on a detached pthread */
|
||||
}
|
||||
|
||||
os_sema_down(&thd->join_sema, osWaitForever);
|
||||
pthread_free(thd);
|
||||
pthread_dbg("pthread_join DONE!\r\n");
|
||||
} else {
|
||||
pthread_dbg("pthread is not exist!\r\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pthread_exit(void *value_ptr)
|
||||
{
|
||||
struct pthread_task *thd = pthread_get(pthread_self());
|
||||
if (thd) {
|
||||
os_task_destroy(thd->task_hdl);
|
||||
pthread_free(thd);
|
||||
} else {
|
||||
pthread_err("pthread is not exist!\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_detach(pthread_t thread)
|
||||
{
|
||||
struct pthread_task *thd = pthread_get(thread);
|
||||
if (thd) {
|
||||
thd->attr.detachstate = PTHREAD_CREATE_DETACHED;
|
||||
} else {
|
||||
pthread_dbg("pthread is not exist!\r\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int pthread_timespec_delta(const struct timespec *abstime)
|
||||
{
|
||||
uint64 ticks;
|
||||
uint32 tmo = osWaitForever;
|
||||
struct timespec cur;
|
||||
|
||||
if (abstime) {
|
||||
os_systime(&cur);
|
||||
if (timespec_detal_ticks(abstime, &cur, &ticks) == RET_OK) {
|
||||
tmo = os_jiffies_to_msecs(ticks);
|
||||
}
|
||||
}
|
||||
|
||||
return tmo;
|
||||
}
|
||||
|
||||
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
|
||||
{
|
||||
uint8 init = 0;
|
||||
uint32 flag = disable_irq();
|
||||
|
||||
if (once_control == NULL || init_routine == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef __NEWLIB__
|
||||
if (!once_control->is_initialized) {
|
||||
once_control->is_initialized = 1;
|
||||
init = 1;
|
||||
}
|
||||
#else
|
||||
if (!(*once_control)) {
|
||||
*once_control = 1;
|
||||
init = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
enable_irq(flag);
|
||||
if (init) {
|
||||
init_routine();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *pthread_tls(pthread_t thread, int create, int size)
|
||||
{
|
||||
void *ptr;
|
||||
uint32 flag;
|
||||
struct pthread_task *thd = pthread_get(thread);
|
||||
if (thd) {
|
||||
if (!create) {
|
||||
flag = disable_irq();
|
||||
ptr = thd->tls;
|
||||
thd->tls = NULL;
|
||||
enable_irq(flag);
|
||||
os_free(ptr);
|
||||
} else {
|
||||
flag = disable_irq();
|
||||
ptr = thd->tls;
|
||||
if (size && ptr == NULL) {
|
||||
ptr = os_malloc(size);
|
||||
if (ptr) {
|
||||
thd->tls = ptr;
|
||||
}
|
||||
}
|
||||
enable_irq(flag);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
131
sdk/lib/posix/pthread_attr.c
Normal file
131
sdk/lib/posix/pthread_attr.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
int pthread_attr_init(pthread_attr_t *attr)
|
||||
{
|
||||
if (attr) {
|
||||
os_memset(attr, 0, sizeof(pthread_attr_t));
|
||||
attr->stacksize = 1024;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_destroy(pthread_attr_t *attr)
|
||||
{
|
||||
if (attr) {
|
||||
os_memset(attr, 0, sizeof(pthread_attr_t));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setdetachstate(pthread_attr_t *attr, int state)
|
||||
{
|
||||
if (state != PTHREAD_CREATE_JOINABLE && state != PTHREAD_CREATE_DETACHED) {
|
||||
return -EINVAL;
|
||||
}
|
||||
attr->detachstate = state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_getdetachstate(pthread_attr_t const *attr, int *state)
|
||||
{
|
||||
*state = (int)attr->detachstate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
|
||||
{
|
||||
//attr->schedpolicy = policy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_getschedpolicy(pthread_attr_t const *attr, int *policy)
|
||||
{
|
||||
//*policy = (int)attr->schedpolicy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param const *param)
|
||||
{
|
||||
attr->schedparam.sched_priority = param->sched_priority;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_getschedparam(pthread_attr_t const *attr, struct sched_param *param)
|
||||
{
|
||||
param->sched_priority = attr->schedparam.sched_priority;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size)
|
||||
{
|
||||
if (attr) {
|
||||
attr->stacksize = stack_size;
|
||||
if (stack_size >= 4096) {
|
||||
pthread_dbg("set stack size %d, maybe too large!\r\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_getstacksize(pthread_attr_t const *attr, size_t *stack_size)
|
||||
{
|
||||
*stack_size = attr->stacksize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack_addr)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int pthread_attr_getstackaddr(pthread_attr_t const *attr, void **stack_addr)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int pthread_attr_setstack(pthread_attr_t *attr, void *stack_base, size_t stack_size)
|
||||
{
|
||||
//attr->stackaddr = stack_base;
|
||||
attr->stacksize = ALIGN(stack_size, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_getstack(pthread_attr_t const *attr, void **stack_base, size_t *stack_size)
|
||||
{
|
||||
*stack_base = 0;//attr->stackaddr;
|
||||
*stack_size = attr->stacksize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guard_size)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int pthread_attr_getguardsize(pthread_attr_t const *attr, size_t *guard_size)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int pthread_attr_setscope(pthread_attr_t *attr, int scope)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int pthread_attr_getscope(pthread_attr_t const *attr, int *scope)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif
|
||||
106
sdk/lib/posix/pthread_barrier.c
Normal file
106
sdk/lib/posix/pthread_barrier.c
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
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)
|
||||
{
|
||||
int32 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, int count)
|
||||
{
|
||||
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)
|
||||
{
|
||||
int32 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;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
206
sdk/lib/posix/pthread_cond.c
Normal file
206
sdk/lib/posix/pthread_cond.c
Normal file
@@ -0,0 +1,206 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "osal/condv.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
||||
{
|
||||
os_condv_t *condv;
|
||||
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == cond) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
os_memset(cond, 0, sizeof(pthread_cond_t));
|
||||
|
||||
condv = os_zalloc(sizeof(os_condv_t));
|
||||
if (NULL == condv) {
|
||||
pthread_err("alloc fail\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (os_condv_init(condv)) {
|
||||
os_free(condv);
|
||||
pthread_err("os_condv_init fail\r\n");
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
cond->lock = condv;
|
||||
#else
|
||||
if (*cond == 0) {
|
||||
condv = os_zalloc(sizeof(os_condv_t));
|
||||
if (condv) {
|
||||
if (os_condv_init(condv)) {
|
||||
os_free(condv);
|
||||
pthread_err("os_condv_init fail\r\n");
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
*cond = (pthread_cond_t)condv;
|
||||
return RET_OK;
|
||||
} else {
|
||||
pthread_err("alloc fail\r\n");
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == cond) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NULL == cond->lock) {
|
||||
pthread_cond_init(cond, NULL);
|
||||
}
|
||||
|
||||
return os_condv_broadcast((os_condv_t *)(cond->lock));
|
||||
#else
|
||||
pthread_cond_init(cond, NULL);
|
||||
return os_condv_broadcast((os_condv_t *)(*cond));
|
||||
#endif
|
||||
}
|
||||
|
||||
int pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == cond) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cond->lock) {
|
||||
os_condv_del((os_condv_t *)(cond->lock));
|
||||
os_free(cond->lock);
|
||||
}
|
||||
#else
|
||||
os_condv_del((os_condv_t *)(*cond));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == cond) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NULL == cond->lock) {
|
||||
pthread_cond_init(cond, NULL);
|
||||
}
|
||||
|
||||
return os_condv_signal((os_condv_t *)(cond->lock));
|
||||
#else
|
||||
pthread_cond_init(cond, NULL);
|
||||
return os_condv_signal((os_condv_t *)(*cond));
|
||||
#endif
|
||||
}
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == cond) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NULL == cond->lock) {
|
||||
pthread_cond_init(cond, NULL);
|
||||
}
|
||||
|
||||
return os_condv_wait((os_condv_t *)(cond->lock), (os_mutex_t *)(mutex->mutex), pthread_timespec_delta(abstime));
|
||||
#else
|
||||
pthread_cond_init(cond, NULL);
|
||||
return os_condv_wait((os_condv_t *)(*cond), (os_mutex_t *)(*mutex), pthread_timespec_delta(abstime));
|
||||
#endif
|
||||
}
|
||||
|
||||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == cond) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NULL == cond->lock) {
|
||||
pthread_cond_init(cond, NULL);
|
||||
}
|
||||
|
||||
return os_condv_wait((os_condv_t *)(cond->lock), (os_mutex_t *)(mutex->mutex), osWaitForever);
|
||||
#else
|
||||
pthread_cond_init(cond, NULL);
|
||||
return os_condv_wait((os_condv_t *)(*cond), (os_mutex_t *)(*mutex), osWaitForever);
|
||||
#endif
|
||||
}
|
||||
|
||||
int pthread_condattr_destroy(pthread_condattr_t *attr)
|
||||
{
|
||||
if (!attr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_condattr_init(pthread_condattr_t *attr)
|
||||
{
|
||||
if (!attr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifdef LIB_PTHREAD_DEF
|
||||
#if defined(_POSIX_THREAD_PROCESS_SHARED) || defined(__MINILIBC__)
|
||||
attr->pshared = PTHREAD_PROCESS_PRIVATE;
|
||||
#endif
|
||||
#else
|
||||
*attr = PTHREAD_PROCESS_PRIVATE;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clock_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared)
|
||||
{
|
||||
if (!attr || !pshared) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*pshared = PTHREAD_PROCESS_PRIVATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)
|
||||
{
|
||||
if ((pshared != PTHREAD_PROCESS_PRIVATE) && (pshared != PTHREAD_PROCESS_SHARED)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (pshared != PTHREAD_PROCESS_PRIVATE) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
198
sdk/lib/posix/pthread_mutex.c
Normal file
198
sdk/lib/posix/pthread_mutex.c
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
os_mutex_t *m = (os_mutex_t *)(mutex->mutex);
|
||||
if (m) {
|
||||
os_mutex_del(m);
|
||||
os_free(m);
|
||||
}
|
||||
|
||||
mutex->initted = 0;
|
||||
mutex->mutex = NULL;
|
||||
mutex->attr = NULL;
|
||||
#else
|
||||
os_mutex_t *m = (os_mutex_t *)(*mutex);
|
||||
if (m) {
|
||||
os_mutex_del(m);
|
||||
os_free(m);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
|
||||
{
|
||||
os_mutex_t *m;
|
||||
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == mutex) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
os_memset(mutex, 0, sizeof(pthread_mutex_t));
|
||||
m = os_zalloc(sizeof(os_mutex_t));
|
||||
if (m == NULL) {
|
||||
pthread_err("alloc fail\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
os_mutex_init(m);
|
||||
mutex->initted = 1;
|
||||
mutex->mutex = m;
|
||||
mutex->attr = (pthread_mutexattr_t *)attr;
|
||||
#else
|
||||
if (mutex == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
m = os_zalloc(sizeof(os_mutex_t));
|
||||
if (m == NULL) {
|
||||
pthread_err("alloc fail\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
os_mutex_init(m);
|
||||
*mutex = (pthread_mutex_t)m;
|
||||
#endif
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == mutex) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NULL == mutex->mutex) {
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
|
||||
return os_mutex_lock((os_mutex_t *)(mutex->mutex), osWaitForever);
|
||||
#else
|
||||
os_mutex_t *m;
|
||||
|
||||
if (*mutex == 0) {
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
m = (os_mutex_t *)(*mutex);
|
||||
if (m) {
|
||||
return os_mutex_lock(m, osWaitForever);
|
||||
}
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == mutex) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NULL == mutex->mutex) {
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
|
||||
return os_mutex_lock((os_mutex_t *)(mutex->mutex), pthread_timespec_delta(abstime));
|
||||
#else
|
||||
os_mutex_t *m;
|
||||
|
||||
if (*mutex == 0) {
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
m = (os_mutex_t *)(*mutex);
|
||||
if (m) {
|
||||
return os_mutex_lock(m, pthread_timespec_delta(abstime));
|
||||
}
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int pthread_mutex_trylock(pthread_mutex_t *mutex)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == mutex) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NULL == mutex->mutex) {
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
|
||||
return os_mutex_lock((os_mutex_t *)(mutex->mutex), 0);
|
||||
#else
|
||||
os_mutex_t *m;
|
||||
|
||||
if (*mutex == 0) {
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
m = (os_mutex_t *)(*mutex);
|
||||
if (m) {
|
||||
return os_mutex_lock(m, 0);
|
||||
}
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||
{
|
||||
#ifdef __MINILIBC__
|
||||
if (NULL == mutex) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (NULL == mutex->mutex) {
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
|
||||
return os_mutex_unlock((os_mutex_t *)(mutex->mutex));
|
||||
#else
|
||||
os_mutex_t *m;
|
||||
|
||||
if (*mutex == 0) {
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
m = (os_mutex_t *)(*mutex);
|
||||
if (m) {
|
||||
return os_mutex_unlock(m);
|
||||
}
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
343
sdk/lib/posix/pthread_rwlock.c
Normal file
343
sdk/lib/posix/pthread_rwlock.c
Normal file
@@ -0,0 +1,343 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
|
||||
{
|
||||
if (!attr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*attr = PTHREAD_PROCESS_PRIVATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
|
||||
{
|
||||
if (!attr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr,
|
||||
int *pshared)
|
||||
{
|
||||
if (!attr || !pshared) {
|
||||
return -EINVAL;
|
||||
}
|
||||
*pshared = PTHREAD_PROCESS_PRIVATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)
|
||||
{
|
||||
if (!attr || pshared != PTHREAD_PROCESS_PRIVATE) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 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) {
|
||||
return -EBUSY;
|
||||
} else {
|
||||
pthread_cond_destroy(&rwlock->rw_condreaders);
|
||||
pthread_cond_destroy(&rwlock->rw_condwriters);
|
||||
}
|
||||
|
||||
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 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++;
|
||||
/* rw_mutex will be released when waiting for rw_condreaders */
|
||||
result = pthread_cond_wait(&rwlock->rw_condreaders, &rwlock->rw_mutex);
|
||||
/* rw_mutex should have been taken again when returned from waiting */
|
||||
rwlock->rw_nwaitreaders--;
|
||||
if (result != 0) { /* wait error */
|
||||
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 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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++;
|
||||
/* rw_mutex will be released when waiting for rw_condreaders */
|
||||
result = pthread_cond_timedwait(&rwlock->rw_condreaders, &rwlock->rw_mutex, abstime);
|
||||
/* rw_mutex should have been taken again when returned from waiting */
|
||||
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 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++;
|
||||
/* rw_mutex will be released when waiting for rw_condwriters */
|
||||
result = pthread_cond_timedwait(&rwlock->rw_condwriters, &rwlock->rw_mutex, abstime);
|
||||
/* rw_mutex should have been taken again when returned from waiting */
|
||||
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 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);
|
||||
}
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
if (rwlock->rw_refcount > 0) {
|
||||
rwlock->rw_refcount--; /* releasing a reader */
|
||||
} else if (rwlock->rw_refcount == -1) {
|
||||
rwlock->rw_refcount = 0; /* releasing a writer */
|
||||
}
|
||||
|
||||
/* 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 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++;
|
||||
/* rw_mutex will be released when waiting for rw_condwriters */
|
||||
result = pthread_cond_wait(&rwlock->rw_condwriters, &rwlock->rw_mutex);
|
||||
/* rw_mutex should have been taken again when returned from waiting */
|
||||
rwlock->rw_nwaitwriters--;
|
||||
|
||||
if (result != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
rwlock->rw_refcount = -1;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&rwlock->rw_mutex);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
87
sdk/lib/posix/pthread_tls.c
Normal file
87
sdk/lib/posix/pthread_tls.c
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "osal/irq.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
struct pthread_key_data {
|
||||
int is_used;
|
||||
void (*destructor)(void *args);
|
||||
};
|
||||
static struct pthread_key_data thread_keys[PTHREAD_KEY_MAX];
|
||||
|
||||
void pthread_key_destroy(void *tls)
|
||||
{
|
||||
uint32 index;
|
||||
void **data = (void **)tls;
|
||||
|
||||
if (tls == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (index = 0; index < PTHREAD_KEY_MAX; index++) {
|
||||
if (thread_keys[index].is_used) {
|
||||
if (data[index]) {
|
||||
thread_keys[index].destructor(data[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *pthread_getspecific(pthread_key_t key)
|
||||
{
|
||||
void **tls = (void **)pthread_tls(pthread_self(), 0, 0);
|
||||
if (tls && key < PTHREAD_KEY_MAX && thread_keys[key].is_used) {
|
||||
return tls[key];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pthread_setspecific(pthread_key_t key, const void *value)
|
||||
{
|
||||
void **tls = (void **)pthread_tls(pthread_self(), 1, PTHREAD_KEY_MAX * sizeof(void *));
|
||||
if (tls && key < PTHREAD_KEY_MAX && thread_keys[key].is_used) {
|
||||
tls[key] = (void *)value;
|
||||
return RET_OK;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
|
||||
{
|
||||
uint32 index;
|
||||
uint32 flag = disable_irq();
|
||||
for (index = 0; index < PTHREAD_KEY_MAX; index ++) {
|
||||
if (thread_keys[index].is_used == 0) {
|
||||
thread_keys[index].is_used = 1;
|
||||
thread_keys[index].destructor = destructor;
|
||||
*key = index;
|
||||
enable_irq(flag);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
enable_irq(flag);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
int pthread_key_delete(pthread_key_t key)
|
||||
{
|
||||
if (key >= PTHREAD_KEY_MAX) {
|
||||
return -EINVAL;
|
||||
}
|
||||
uint32 flag = disable_irq();
|
||||
thread_keys[key].is_used = 0;
|
||||
thread_keys[key].destructor = 0;
|
||||
enable_irq(flag);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
35
sdk/lib/posix/sched.c
Normal file
35
sdk/lib/posix/sched.c
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
int sched_yield(void)
|
||||
{
|
||||
os_task_yield();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sched_get_priority_min(int policy)
|
||||
{
|
||||
return OS_TASK_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
int sched_get_priority_max(int policy)
|
||||
{
|
||||
return OS_TASK_PRIORITY_HIGH;
|
||||
}
|
||||
|
||||
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif
|
||||
68
sdk/lib/posix/semaphore.c
Normal file
68
sdk/lib/posix/semaphore.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
int sem_destroy(sem_t *sem)
|
||||
{
|
||||
os_semaphore_t *s = (os_semaphore_t *)(*sem);
|
||||
os_sema_del(s);
|
||||
os_free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_getvalue(sem_t *sem, int *sval)
|
||||
{
|
||||
*sval = os_sema_count((os_semaphore_t *)(*sem));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_init(sem_t *sem, int pshared, unsigned value)
|
||||
{
|
||||
os_semaphore_t *s;
|
||||
|
||||
if (sem == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s = (os_semaphore_t *)os_zalloc(sizeof(os_semaphore_t));
|
||||
if (s == NULL) {
|
||||
pthread_err("alloc fail\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
os_sema_init(s, 0);
|
||||
*sem = (sem_t)s;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int sem_post(sem_t *sem)
|
||||
{
|
||||
return os_sema_up((os_semaphore_t *)(*sem));
|
||||
}
|
||||
|
||||
int sem_timedwait(sem_t *sem, const struct timespec *abstime)
|
||||
{
|
||||
return os_sema_down((os_semaphore_t *)(*sem), pthread_timespec_delta(abstime));
|
||||
}
|
||||
|
||||
int sem_trywait(sem_t *sem)
|
||||
{
|
||||
return os_sema_down((os_semaphore_t *)(*sem), 0);
|
||||
}
|
||||
|
||||
int sem_wait(sem_t *sem)
|
||||
{
|
||||
return os_sema_down((os_semaphore_t *)(*sem), osWaitForever);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
165
sdk/lib/posix/sockets.c
Normal file
165
sdk/lib/posix/sockets.c
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/sleep.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/if_api.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
return lwip_accept(s, addr, addrlen);
|
||||
}
|
||||
|
||||
int bind(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
return lwip_bind(s, name, namelen);
|
||||
}
|
||||
|
||||
int shutdown(int s, int how)
|
||||
{
|
||||
return lwip_shutdown(s, how);
|
||||
}
|
||||
|
||||
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
return lwip_getpeername(s, name, namelen);
|
||||
}
|
||||
|
||||
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
return lwip_getsockname(s, name, namelen);
|
||||
}
|
||||
|
||||
int setsockopt(int s, int level, int optname, const void *opval, socklen_t optlen)
|
||||
{
|
||||
return lwip_setsockopt(s, level, optname, opval, optlen);
|
||||
}
|
||||
|
||||
int getsockopt(int s, int level, int optname, void *opval, socklen_t *optlen)
|
||||
{
|
||||
return lwip_getsockopt(s, level, optname, opval, optlen);
|
||||
}
|
||||
|
||||
int closesocket(int s)
|
||||
{
|
||||
return lwip_close(s);
|
||||
}
|
||||
|
||||
int connect(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
return lwip_connect(s, name, namelen);
|
||||
}
|
||||
|
||||
int listen(int s, int backlog)
|
||||
{
|
||||
return lwip_listen(s, backlog);
|
||||
}
|
||||
|
||||
ssize_t recv(int s, void *mem, size_t len, int flags)
|
||||
{
|
||||
return lwip_recv(s, mem, len, flags);
|
||||
}
|
||||
|
||||
ssize_t recvmsg(int s, struct msghdr *message, int flags)
|
||||
{
|
||||
return lwip_recvmsg(s, message, flags);
|
||||
}
|
||||
|
||||
ssize_t recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
return lwip_recvfrom(s, mem, len, flags, from, fromlen);
|
||||
}
|
||||
|
||||
ssize_t send(int s, const void *dataptr, size_t size, int flags)
|
||||
{
|
||||
return lwip_send(s, dataptr, size, flags);
|
||||
}
|
||||
|
||||
ssize_t sendmsg(int s, const struct msghdr *msg, int flags)
|
||||
{
|
||||
return lwip_sendmsg(s, msg, flags);
|
||||
}
|
||||
|
||||
ssize_t sendto(int s, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
return lwip_sendto(s, data, size, flags, to, tolen);
|
||||
}
|
||||
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
return lwip_socket(domain, type, protocol);
|
||||
}
|
||||
|
||||
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout)
|
||||
{
|
||||
return lwip_select(maxfdp1, readset, writeset, exceptset, timeout);
|
||||
}
|
||||
|
||||
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
{
|
||||
return lwip_poll(fds, nfds, timeout);
|
||||
}
|
||||
|
||||
int ioctlsocket(int s, long cmd, void *argp)
|
||||
{
|
||||
return lwip_ioctl(s, cmd, argp);
|
||||
}
|
||||
|
||||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
|
||||
{
|
||||
return lwip_inet_ntop(af, src, dst, size);
|
||||
}
|
||||
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
return lwip_inet_pton(af, src, dst);
|
||||
}
|
||||
|
||||
char *if_indextoname(unsigned int ifindex, char *ifname)
|
||||
{
|
||||
return lwip_if_indextoname(ifindex, ifname);
|
||||
}
|
||||
|
||||
unsigned int if_nametoindex(const char *ifname)
|
||||
{
|
||||
return lwip_if_nametoindex(ifname);
|
||||
}
|
||||
|
||||
struct hostent *gethostbyname(const char *name)
|
||||
{
|
||||
return lwip_gethostbyname(name, 1);
|
||||
}
|
||||
|
||||
int gethostbyname_r(const char *name, struct hostent *ret, char *buf,
|
||||
size_t buflen, struct hostent **result, int *h_errnop)
|
||||
{
|
||||
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop, 1);
|
||||
}
|
||||
|
||||
struct hostent *gethostbyname_async(const char *name)
|
||||
{
|
||||
return lwip_gethostbyname(name, 0);
|
||||
}
|
||||
|
||||
int gethostbyname_r_async(const char *name, struct hostent *ret, char *buf,
|
||||
size_t buflen, struct hostent **result, int *h_errnop)
|
||||
{
|
||||
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop, 0);
|
||||
}
|
||||
|
||||
void freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
lwip_freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
int getaddrinfo(const char *nodename, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res)
|
||||
{
|
||||
|
||||
return lwip_getaddrinfo(nodename, servname, hints, res);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
556
sdk/lib/posix/stdio.c
Normal file
556
sdk/lib/posix/stdio.c
Normal file
@@ -0,0 +1,556 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/sleep.h"
|
||||
#include "osal/string.h"
|
||||
#include "lib/posix/stdio.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
#if FS_EN
|
||||
#include "fatfs/osal_file.h"
|
||||
#include "fatfs/ff.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define FILE void
|
||||
|
||||
#define FS_PSRAM_BUFF 1
|
||||
|
||||
/* sram slice buffer size, usr for psram slice write to sd */
|
||||
#define STDIO_RWBUF_SIZE 10000
|
||||
|
||||
extern int osal_open(const char *filename, int oflags, int mode);
|
||||
int read(int fd, void *buf, size_t nbytes);
|
||||
int write(int fd, const void *buf, size_t nbytes);
|
||||
|
||||
|
||||
#define ENV_MAX_CNT (8)
|
||||
static const char *_env_list_[ENV_MAX_CNT][2];
|
||||
|
||||
char *getenv(const char *name)
|
||||
{
|
||||
int32 i = 0;
|
||||
for (i = 0; i < ENV_MAX_CNT; i++) {
|
||||
if (_env_list_[i][0] == name) {
|
||||
return (char *)_env_list_[i][1];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int setenv(const char *name, const char *value, int overwrite)
|
||||
{
|
||||
int32 i = 0;
|
||||
int32 j = -1;
|
||||
|
||||
for (i = 0; i < ENV_MAX_CNT; i++) {
|
||||
if (_env_list_[i][0] == name) {
|
||||
break;
|
||||
}
|
||||
if (j == -1 && _env_list_[i][0] == NULL) {
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < ENV_MAX_CNT && (overwrite || _env_list_[i][1] == NULL)) {
|
||||
_env_list_[i][1] = value;
|
||||
} else if (i >= ENV_MAX_CNT && j != -1) {
|
||||
_env_list_[j][0] = name;
|
||||
_env_list_[j][1] = value;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unsetenv(const char *name)
|
||||
{
|
||||
int32 i = 0;
|
||||
for (i = 0; i < ENV_MAX_CNT; i++) {
|
||||
if (_env_list_[i][0] == name) {
|
||||
_env_list_[i][0] = NULL;
|
||||
_env_list_[i][1] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usleep(unsigned long usec)
|
||||
{
|
||||
os_sleep_us(usec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int sleep(unsigned int seconds)
|
||||
{
|
||||
os_sleep(seconds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int access(const char *pathname, int mode)
|
||||
{
|
||||
#if FS_EN
|
||||
return osal_fexist(pathname);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int fclose(FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return osal_fclose((F_FILE *)stream);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int feof(FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return f_eof((F_FILE *)stream);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ferror(FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return f_error((F_FILE *)stream);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int fflush(FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return fsync((int)stream);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
FILE *fopen(const char *filename, const char *mode)
|
||||
{
|
||||
#if FS_EN
|
||||
return (FILE *)osal_fopen(filename, mode);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return read((int)stream, ptr, size * nmemb);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int fseek(FILE *stream, long int offset, int whence)
|
||||
{
|
||||
// TODO: not support whence now
|
||||
#if FS_EN
|
||||
return osal_fseek((F_FILE *)stream, offset);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// FIXME: 仅支持获取文件大小, 不支持从指针位置开始
|
||||
long ftell(FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return f_size((FIL *)stream);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return write((int)stream, ptr, size *nmemb);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ADD truncate
|
||||
int fileno(FILE *stream)
|
||||
{
|
||||
return (int)stream;
|
||||
}
|
||||
|
||||
int ftruncate(int fd, off_t length)
|
||||
{
|
||||
#if FS_EN
|
||||
return f_truncate((F_FILE *)fd);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int remove(char *filename)
|
||||
{
|
||||
#if FS_EN
|
||||
return osal_unlink(filename);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int rename(const char *old_filename, const char *new_filename)
|
||||
{
|
||||
#if FS_EN
|
||||
return osal_rename(old_filename, new_filename);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void rewind(FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
f_rewind((FIL*)stream);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
int vfprintf(FILE *stream, const char *format, va_list arg)
|
||||
{
|
||||
#if FS_EN
|
||||
int f_vprintf (FIL* fp,const TCHAR* fmt,va_list arp);
|
||||
return f_vprintf((FIL*)stream, format, arg);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
int fgetc(FILE *stream)
|
||||
{
|
||||
uint8 val = 0;
|
||||
osal_fread(val, 1, 1, stream);
|
||||
return val;
|
||||
}
|
||||
*/
|
||||
|
||||
char *fgets(char *str, int n, FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return f_gets(str, n, (FIL*)stream);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
int fputc(int c, FILE *stream)
|
||||
{
|
||||
return f_putc(c, stream);
|
||||
}
|
||||
|
||||
int fputs(const char *str, FILE *stream)
|
||||
{
|
||||
return f_puts(str, stream);
|
||||
}
|
||||
*/
|
||||
|
||||
int fsync(int fd)
|
||||
{
|
||||
#if FS_EN
|
||||
return f_sync((F_FILE *)fd) == FR_OK ? 0 : -1;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int getc(FILE *stream)
|
||||
{
|
||||
uint8 val = 0;
|
||||
#if FS_EN
|
||||
osal_fread(&val, 1, 1, (F_FILE *)stream);
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
int putc(int c, FILE *stream)
|
||||
{
|
||||
return f_putc(c, stream);
|
||||
}
|
||||
*/
|
||||
|
||||
int stat(const char *path, struct stat *buf)
|
||||
{
|
||||
#if FS_EN
|
||||
FILINFO *file_info = (FILINFO *)os_malloc(sizeof(FILINFO));
|
||||
f_stat(path, file_info);
|
||||
buf->st_size = file_info->fsize;
|
||||
buf->st_mtime = file_info->ftime;
|
||||
buf->fattrib = file_info->fattrib;
|
||||
buf->st_mode = (file_info->fattrib & AM_DIR) ? S_IFDIR : S_IFREG;
|
||||
buf->fname = NULL;
|
||||
os_free(file_info);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: just support file size for now
|
||||
int fstat(int fd, struct stat *statbuf)
|
||||
{
|
||||
#if FS_EN
|
||||
F_FILE *file = (F_FILE *)fd;
|
||||
statbuf->st_size = f_size(file);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if FS_EN && FS_PSRAM_BUFF
|
||||
int write_from_psram(int fd, const char *psram_buf, size_t nbytes)
|
||||
{
|
||||
int left_len = nbytes;
|
||||
int write_len = 0;
|
||||
int wlen = 0;
|
||||
int len = -1;
|
||||
char *sram_buf = os_malloc(STDIO_RWBUF_SIZE);
|
||||
if(sram_buf == NULL){
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
while (left_len) {
|
||||
wlen = left_len < STDIO_RWBUF_SIZE ? left_len : STDIO_RWBUF_SIZE;
|
||||
hw_memcpy(sram_buf, psram_buf + write_len, wlen);
|
||||
len = (int)osal_fwrite(sram_buf, wlen, 1, (F_FILE *)fd);
|
||||
if (len < wlen) {
|
||||
os_free(sram_buf);
|
||||
return write_len + len;
|
||||
}
|
||||
left_len -= wlen;
|
||||
write_len += wlen;
|
||||
}
|
||||
|
||||
os_free(sram_buf);
|
||||
return write_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
int write(int fd, const void *buf, size_t nbytes)
|
||||
{
|
||||
if (fd > 0 && fd < 256) {
|
||||
return lwip_write(fd, buf, nbytes);
|
||||
} else {
|
||||
#if FS_EN
|
||||
#if FS_PSRAM_BUFF
|
||||
return write_from_psram(fd, buf, nbytes);
|
||||
#else
|
||||
return osal_fwrite(buf, nbytes, 1, (F_FILE *)fd);
|
||||
#endif
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if FS_EN && FS_PSRAM_BUFF
|
||||
int read_to_psram(int fd, char *psram_buf, size_t nbytes)
|
||||
{
|
||||
int left_len = nbytes;
|
||||
int read_len = 0;
|
||||
int rlen = 0;
|
||||
int len = -1;
|
||||
char *sram_buff = os_malloc(STDIO_RWBUF_SIZE);
|
||||
if(sram_buff == NULL){
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
while (left_len) {
|
||||
rlen = left_len < STDIO_RWBUF_SIZE ? left_len : STDIO_RWBUF_SIZE;
|
||||
len = (int)osal_fread(sram_buff, rlen, 1, (F_FILE *)fd);
|
||||
hw_memcpy(psram_buf + read_len, sram_buff, len);
|
||||
|
||||
if (len < rlen) {
|
||||
os_free(sram_buff);
|
||||
return read_len + len;
|
||||
}
|
||||
|
||||
left_len -= rlen;
|
||||
read_len += rlen;
|
||||
}
|
||||
|
||||
os_free(sram_buff);
|
||||
return read_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
int read(int fd, void *buf, size_t nbytes)
|
||||
{
|
||||
if (fd > 0 && fd < 256) {
|
||||
return lwip_read(fd, buf, nbytes);
|
||||
} else {
|
||||
#if FS_EN
|
||||
#if FS_PSRAM_BUFF
|
||||
return read_to_psram(fd, buf, nbytes);
|
||||
#else
|
||||
return osal_fread(buf, nbytes, 1, (F_FILE *)fd);
|
||||
#endif
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
off_t lseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
// TODO: whence not support now
|
||||
#if FS_EN
|
||||
return osal_fseek((F_FILE *)fd, offset) == FR_OK ? offset : -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int open(const char *path, int oflags, ...)
|
||||
{
|
||||
int handler = 0;
|
||||
#if FS_EN
|
||||
int flags = 0;
|
||||
|
||||
#if 0
|
||||
/* mode is not use */
|
||||
int mode = 0;
|
||||
va_list arg;
|
||||
|
||||
va_start(arg, oflags);
|
||||
mode = va_arg(arg, int);
|
||||
va_end(arg);
|
||||
#endif
|
||||
|
||||
if (ACC_MODE(oflags) == O_RDWR) {
|
||||
flags = (FA_READ | FA_WRITE);
|
||||
} else if (ACC_MODE(oflags) == O_RDONLY) {
|
||||
flags = FA_READ;
|
||||
} else {
|
||||
flags = FA_WRITE;
|
||||
}
|
||||
|
||||
if (oflags & O_CREAT) {
|
||||
flags |= FA_CREATE_ALWAYS;
|
||||
}
|
||||
|
||||
handler = (int)osal_open(path, 0, flags);
|
||||
#endif
|
||||
return handler == 0 ? -1 : handler;
|
||||
}
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
if (fd > 0 && fd < 256) {
|
||||
return lwip_close(fd);
|
||||
} else {
|
||||
#if FS_EN
|
||||
return osal_fclose((F_FILE *)fd);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int unlink(const char *path)
|
||||
{
|
||||
#if FS_EN
|
||||
return osal_unlink(path);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int fcntl(int fd, int cmd, ...)
|
||||
{
|
||||
int arg = 0;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, cmd);
|
||||
arg = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
|
||||
if (fd > 0 && fd < 256) {
|
||||
return lwip_fcntl(fd, cmd, arg);
|
||||
} else {
|
||||
#if FS_EN
|
||||
return f_cntl((FIL *)fd, cmd, arg);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl(int fd, long cmd, void *argp)
|
||||
{
|
||||
if (fd > 0 && fd < 256) {
|
||||
return lwip_ioctl(fd, cmd, argp);
|
||||
} else {
|
||||
#if FS_EN
|
||||
return f_ioctl((FIL *)fd, cmd, argp);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
if (fd > 0 && fd < 256) {
|
||||
return lwip_readv(fd, iov, iovcnt);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
if (fd > 0 && fd < 256) {
|
||||
return lwip_writev(fd, iov, iovcnt);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int fputs(const char *str, FILE *stream)
|
||||
{
|
||||
#if FS_EN
|
||||
return fwrite(str, 1, os_strlen(str), stream);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int _fclose_r (void *rptr, FILE * fp)
|
||||
{
|
||||
return fclose(fp);
|
||||
}
|
||||
int _fflush_r (void *rptr, FILE *fp)
|
||||
{
|
||||
return fflush(fp);
|
||||
}
|
||||
#else
|
||||
int _fclose_r (void *rptr, void * fp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int _fflush_r (void *rptr, void *fp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
227
sdk/lib/posix/timer.c
Normal file
227
sdk/lib/posix/timer.c
Normal file
@@ -0,0 +1,227 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "lib/common/rbuffer.h"
|
||||
#include "lib/posix/pthread.h"
|
||||
#include "osal/sleep.h"
|
||||
|
||||
#ifdef TXWSDK_POSIX
|
||||
|
||||
#define TIMESPEC_IS_ZERO(tm) (tm.tv_sec == 0 && tm.tv_nsec == 0)
|
||||
#define TIMESPEC_IS_NOT_ZERO(tm) (!(TIMESPEC_IS_ZERO( tm)))
|
||||
|
||||
struct posix_timer {
|
||||
os_timer_t timer;
|
||||
struct sigevent event;
|
||||
uint64 period_time;
|
||||
uint64 expired_time;
|
||||
};
|
||||
|
||||
void posix_timer_cb(void *arg)
|
||||
{
|
||||
pthread_t pthd;
|
||||
struct posix_timer *ptimer = (struct posix_timer *)(arg);
|
||||
|
||||
/* Update the timer period, which may need to be set to an it_interval
|
||||
* argument. This call should not block. */
|
||||
if (ptimer->period_time > 0) {
|
||||
os_timer_start(&ptimer->timer, ptimer->period_time);
|
||||
}
|
||||
|
||||
/* Create the timer notification thread if requested. */
|
||||
if (ptimer->event.sigev_notify == SIGEV_THREAD) {
|
||||
/* if the user has provided thread attributes, create a thread
|
||||
* with the provided attributes. Otherwise dispatch callback directly */
|
||||
if (ptimer->event.sigev_notify_attributes == NULL) {
|
||||
(*ptimer->event.sigev_notify_function)(ptimer->event.sigev_value);
|
||||
} else {
|
||||
pthread_create(&pthd,
|
||||
ptimer->event.sigev_notify_attributes,
|
||||
(void *(*)(void *))ptimer->event.sigev_notify_function,
|
||||
ptimer->event.sigev_value.sival_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
|
||||
{
|
||||
int ret = 0;
|
||||
struct posix_timer *ptimer = NULL;
|
||||
|
||||
/* POSIX specifies that when evp is NULL, the behavior shall be as is
|
||||
* sigev_notify is SIGEV_SIGNAL. SIGEV_SIGNAL is currently not supported. */
|
||||
if ((evp == NULL) || (evp->sigev_notify == SIGEV_SIGNAL)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
ptimer = os_zalloc(sizeof(struct posix_timer));
|
||||
if (ptimer == NULL) {
|
||||
pthread_err("alloc fail\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ptimer->event = *evp;
|
||||
if (ptimer->event.sigev_notify_attributes && ptimer->event.sigev_notify_attributes->detachstate != PTHREAD_CREATE_DETACHED) {
|
||||
pthread_err("timer sigev_notify_attributes detachstate is NOT DETACHED\r\n");
|
||||
ptimer->event.sigev_notify_attributes->detachstate = PTHREAD_CREATE_DETACHED;
|
||||
}
|
||||
ret = os_timer_init(&ptimer->timer, posix_timer_cb, OS_TIMER_MODE_ONCE, ptimer);
|
||||
if (!ret) {
|
||||
*timerid = (timer_t)ptimer;
|
||||
} else {
|
||||
pthread_err("os_timer_init fail\r\n");
|
||||
os_free(ptimer);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int timer_delete(timer_t timerid)
|
||||
{
|
||||
struct posix_timer *ptimer = (struct posix_timer *)(timerid);
|
||||
os_timer_stop(&ptimer->timer);
|
||||
while (os_timer_stat(&ptimer->timer)) {
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
os_timer_del(&ptimer->timer);
|
||||
os_free(ptimer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_getoverrun(timer_t timerid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue)
|
||||
{
|
||||
int ret = 0;
|
||||
struct posix_timer *ptimer = (struct posix_timer *)(timerid);
|
||||
uint64 expired_jiff = 0;
|
||||
uint64 period_jiff = 0;
|
||||
|
||||
/* Validate the value argument, but only if the timer isn't being disarmed. */
|
||||
if (TIMESPEC_IS_NOT_ZERO(value->it_value)) {
|
||||
if (!timespec_validate(&value->it_interval) || !timespec_validate(&value->it_value)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set ovalue, if given. */
|
||||
if (ovalue != NULL) {
|
||||
timer_gettime(timerid, ovalue);
|
||||
}
|
||||
|
||||
/* Stop the timer if it's currently active. */
|
||||
if (os_timer_stat(&ptimer->timer)) {
|
||||
os_timer_stop(&ptimer->timer);
|
||||
}
|
||||
|
||||
/* Only restart the timer if it_value is not zero. */
|
||||
if (TIMESPEC_IS_NOT_ZERO(value->it_value)) {
|
||||
/* Convert it_interval to ticks, but only if it_interval is not 0. If
|
||||
* it_interval is 0, then the timer is not periodic. */
|
||||
if (TIMESPEC_IS_NOT_ZERO(value->it_interval)) {
|
||||
timespec_to_ticks(&value->it_interval, &period_jiff);
|
||||
}
|
||||
|
||||
/* Set the new timer period. A non-periodic timer will have its period set
|
||||
* to portMAX_DELAY. */
|
||||
ptimer->period_time = period_jiff;
|
||||
|
||||
/* Convert it_value to ticks, but only if it_value is not 0. If it_value
|
||||
* is 0, then the timer will remain disarmed. */
|
||||
if (TIMESPEC_IS_NOT_ZERO(value->it_value)) {
|
||||
/* Absolute timeout. */
|
||||
if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME) {
|
||||
struct timespec cur_tm = { 0 };
|
||||
|
||||
/* Get current time */
|
||||
if (clock_gettime(CLOCK_REALTIME, &cur_tm) != 0) {
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
ret = timespec_detal_ticks(&value->it_value, &cur_tm, &expired_jiff);
|
||||
}
|
||||
|
||||
/* Make sure expired_jiff is zero in case we got negative time difference */
|
||||
if (ret != 0) {
|
||||
expired_jiff = 0;
|
||||
if (ret == -ETIMEDOUT) {
|
||||
/* Set Status to 0 as absolute time is past is treated as expiry but not an error */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
} else {/* Relative timeout. */
|
||||
timespec_to_ticks(&value->it_value, &expired_jiff);
|
||||
}
|
||||
}
|
||||
|
||||
/* If expired_jiff is still 0, that means that it_value specified
|
||||
* an absolute timeout in the past. Per POSIX spec, a notification should be
|
||||
* triggered immediately. */
|
||||
if (expired_jiff == 0) {
|
||||
posix_timer_cb(ptimer);
|
||||
} else {
|
||||
ptimer->expired_time = os_jiffies() + expired_jiff;
|
||||
os_timer_start(&ptimer->timer, os_jiffies_to_msecs(expired_jiff));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int timer_gettime(timer_t timerid, struct itimerspec *value)
|
||||
{
|
||||
struct posix_timer *ptimer = (struct posix_timer *)(timerid);
|
||||
uint64 expired_time = ptimer->expired_time - os_jiffies();
|
||||
uint64 period_time = ptimer->period_time;
|
||||
|
||||
/* Set it_value only if the timer is armed. Otherwise, set it to 0. */
|
||||
if (os_timer_stat(&ptimer->timer)) {
|
||||
value->it_value.tv_sec = (time_t)(expired_time / OS_SYSTICK_HZ);
|
||||
value->it_value.tv_nsec = (long)((expired_time % OS_SYSTICK_HZ) * NANOSECONDS_PER_TICK);
|
||||
} else {
|
||||
value->it_value.tv_sec = 0;
|
||||
value->it_value.tv_nsec = 0;
|
||||
}
|
||||
|
||||
/* Set it_interval only if the timer is periodic. Otherwise, set it to 0. */
|
||||
if (period_time != osWaitForever) {
|
||||
value->it_interval.tv_sec = (time_t)(period_time / OS_SYSTICK_HZ);
|
||||
value->it_interval.tv_nsec = (long)((period_time % OS_SYSTICK_HZ) * NANOSECONDS_PER_TICK);
|
||||
} else {
|
||||
value->it_interval.tv_sec = 0;
|
||||
value->it_interval.tv_nsec = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 //see: include/osal/csky/time.h
|
||||
void timeradd(struct timeval *a, struct timeval *b, struct timeval *res)
|
||||
{
|
||||
res->tv_sec = a->tv_sec + b->tv_sec;
|
||||
res->tv_usec = a->tv_usec + b->tv_usec;
|
||||
if (res->tv_usec >= 1000000) {
|
||||
++res->tv_sec;
|
||||
res->tv_usec -= 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
void timersub(struct timeval *a, struct timeval *b, struct timeval *res)
|
||||
{
|
||||
res->tv_sec = a->tv_sec - b->tv_sec;
|
||||
res->tv_usec = a->tv_usec - b->tv_usec;
|
||||
if (res->tv_usec < 0) {
|
||||
--res->tv_sec;
|
||||
res->tv_usec += 1000000;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user