Files
TAIXIN/sdk/lib/posix/mqueue.c

183 lines
4.4 KiB
C
Raw Permalink Normal View History

#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