1
0
Fork 0
forked from nuttx/nuttx-update

mqueue: simplify the mqueue reailize

1. remove descript management in mqueue, save code size
2. use i_ops instead of i_mqueue to remove the dup logic

Change-Id: Ie88960e50ddcae9c87977c9ad65a45297c663291
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2020-12-22 22:02:48 +08:00 committed by Xiang Xiao
parent c8784faf3c
commit 3bc33572e3
25 changed files with 291 additions and 842 deletions

View file

@ -40,65 +40,6 @@
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxmq_close_group
*
* Description:
* This function is used to indicate that all threads in the group are
* finished with the specified message queue mqdes. The nxmq_close_group()
* deallocates any system resources allocated by the system for use by
* this task for its message queue.
*
* Input Parameters:
* mqdes - Message queue descriptor.
* group - Group that has the open descriptor.
*
* Returned Value:
* Zero (OK) if the message queue is closed successfully. Otherwise, a
* negated errno value is returned.
*
****************************************************************************/
int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
{
FAR struct mqueue_inode_s *msgq;
FAR struct inode *inode;
int ret = OK;
DEBUGASSERT(mqdes != NULL && group != NULL);
/* Verify the inputs */
if (mqdes)
{
sched_lock();
/* Find the message queue associated with the message descriptor */
msgq = mqdes->msgq;
DEBUGASSERT(msgq && msgq->inode);
/* Close/free the message descriptor */
ret = nxmq_desclose_group(mqdes, group);
if (ret >= 0)
{
/* Get the inode from the message queue structure */
inode = msgq->inode;
DEBUGASSERT(inode->u.i_mqueue == msgq);
/* Decrement the reference count on the inode, possibly free it */
mq_inode_release(inode);
}
sched_unlock();
}
return ret;
}
/****************************************************************************
* Name: nxmq_close
*
@ -124,23 +65,7 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
int nxmq_close(mqd_t mqdes)
{
FAR struct tcb_s *rtcb = (FAR struct tcb_s *)nxsched_self();
int ret;
/* Lock the scheduler to prevent any asynchronous task delete operation
* (unlikely).
*/
sched_lock();
DEBUGASSERT(mqdes != NULL && rtcb != NULL && rtcb->group != NULL);
/* Then perform the close operation */
ret = nxmq_close_group(mqdes, rtcb->group);
sched_unlock();
return ret;
return nx_close(mqdes);
}
/****************************************************************************
@ -173,80 +98,5 @@ int nxmq_close(mqd_t mqdes)
int mq_close(mqd_t mqdes)
{
int ret;
ret = nxmq_close(mqdes);
if (ret < 0)
{
set_errno(-ret);
ret = ERROR;
}
return ret;
}
/****************************************************************************
* Name: mq_inode_release
*
* Description:
* Release a reference count on a message queue inode.
*
* Input Parameters:
* inode - The message queue inode
*
* Returned Value:
* None
*
****************************************************************************/
void mq_inode_release(FAR struct inode *inode)
{
int ret;
/* Decrement the reference count on the inode */
do
{
ret = inode_semtake();
/* The only error that is expected is due to thread cancellation.
* At this point, we must continue to free the mqueue anyway.
*/
DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
while (ret < 0);
if (inode->i_crefs > 0)
{
inode->i_crefs--;
}
/* If the message queue was previously unlinked and the reference count
* has decremented to zero, then release the message queue and delete
* the inode now.
*/
if (inode->i_crefs <= 0 && (inode->i_flags & FSNODEFLAG_DELETED) != 0)
{
FAR struct mqueue_inode_s *msgq = inode->u.i_mqueue;
DEBUGASSERT(msgq);
/* Free the message queue (and any messages left in it) */
nxmq_free_msgq(msgq);
inode->u.i_mqueue = NULL;
/* Release and free the inode container. If it has been properly
* unlinked, then the peer pointer should be NULL.
*/
inode_semgive();
DEBUGASSERT(inode->i_peer == NULL);
inode_free(inode);
return;
}
inode_semgive();
return close(mqdes);
}

View file

@ -38,6 +38,52 @@
#include "inode/inode.h"
#include "mqueue/mqueue.h"
/****************************************************************************
* Private Functions Prototypes
****************************************************************************/
static int nxmq_file_close(FAR struct file *filep);
/****************************************************************************
* Private Data
****************************************************************************/
static const struct file_operations g_nxmq_fileops =
{
NULL, /* open */
nxmq_file_close, /* close */
NULL, /* read */
NULL, /* write */
NULL, /* seek */
NULL, /* ioctl */
NULL, /* poll */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
NULL, /* unlink */
#endif
};
/****************************************************************************
* Private Functions
****************************************************************************/
static int nxmq_file_close(FAR struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
if (inode->i_crefs <= 1 && (inode->i_flags & FSNODEFLAG_DELETED))
{
FAR struct mqueue_inode_s *msgq = inode->i_private;
if (msgq)
{
nxmq_free_msgq(msgq);
inode->i_private = NULL;
}
}
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -147,14 +193,13 @@ int nxmq_open(FAR const char *mq_name, int oflags, mode_t mode,
goto errout_with_inode;
}
/* Create a message queue descriptor for the current thread */
/* Associate the inode with a file structure */
msgq = inode->u.i_mqueue;
*mqdes = nxmq_create_des(NULL, msgq, oflags);
if (!*mqdes)
*mqdes = files_allocate(inode, oflags, 0, 0);
if (*mqdes < 0)
{
ret = -ENOMEM;
goto errout_with_inode;
ret = *mqdes;
goto errout_with_msgq;
}
}
else
@ -196,19 +241,18 @@ int nxmq_open(FAR const char *mq_name, int oflags, mode_t mode,
goto errout_with_inode;
}
/* Create a message queue descriptor for the TCB */
/* Associate the inode with a file structure */
*mqdes = nxmq_create_des(NULL, msgq, oflags);
if (!*mqdes)
*mqdes = files_allocate(inode, oflags, 0, 0);
if (*mqdes < 0)
{
ret = -ENOMEM;
ret = *mqdes;
goto errout_with_msgq;
}
/* Bind the message queue and the inode structure */
INODE_SET_MQUEUE(inode);
inode->u.i_mqueue = msgq;
inode->u.i_ops = &g_nxmq_fileops;
inode->i_private = msgq;
msgq->inode = inode;
/* Set the initial reference count on this inode to one */
@ -222,7 +266,6 @@ int nxmq_open(FAR const char *mq_name, int oflags, mode_t mode,
errout_with_msgq:
nxmq_free_msgq(msgq);
inode->u.i_mqueue = NULL;
errout_with_inode:
inode_release(inode);

View file

@ -35,6 +35,38 @@
#include "inode/inode.h"
#include "mqueue/mqueue.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: mq_inode_release
*
* Description:
* Release a reference count on a message queue inode.
*
* Input Parameters:
* inode - The message queue inode
*
* Returned Value:
* None
*
****************************************************************************/
static void mq_inode_release(FAR struct inode *inode)
{
if (inode->i_crefs <= 1)
{
FAR struct mqueue_inode_s *msgq = inode->i_private;
if (msgq)
{
nxmq_free_msgq(msgq);
inode->i_private = NULL;
}
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -182,8 +214,8 @@ int mq_unlink(FAR const char *mq_name)
if (ret < 0)
{
set_errno(-ret);
ret = ERROR;
return ERROR;
}
return ret;
return OK;
}

View file

@ -45,6 +45,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_FS_MQUEUE_MPATH
@ -55,41 +56,4 @@
#define MAX_MQUEUE_PATH 64
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: mq_inode_release
*
* Description:
* Release a reference count on a message queue inode.
*
* Input Parameters:
* inode - The message queue inode
*
* Returned Value:
* None
*
****************************************************************************/
void mq_inode_release(FAR struct inode *inode);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __FS_MQUEUE_MQUEUE_H */

View file

@ -42,7 +42,6 @@
#include <sys/types.h>
#include <signal.h>
#include "queue.h"
/********************************************************************************
* Pre-processor Definitions
@ -66,7 +65,7 @@ struct mq_attr
/* Message queue descriptor */
typedef FAR struct mq_des *mqd_t;
typedef int mqd_t;
/********************************************************************************
* Public Data

View file

@ -38,10 +38,6 @@
# include <nuttx/semaphore.h>
#endif
#ifndef CONFIG_DISABLE_MQUEUE
# include <nuttx/mqueue.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -372,9 +368,6 @@ union inode_ops_u
#ifdef CONFIG_FS_NAMED_SEMAPHORES
FAR struct nsem_inode_s *i_nsem; /* Named semaphore */
#endif
#ifndef CONFIG_DISABLE_MQUEUE
FAR struct mqueue_inode_s *i_mqueue; /* POSIX message queue */
#endif
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
FAR char *i_link; /* Full path to link target */
#endif

View file

@ -98,8 +98,6 @@
/* This structure defines a message queue */
struct mq_des; /* forward reference */
struct mqueue_inode_s
{
FAR struct inode *inode; /* Containing inode */
@ -113,23 +111,11 @@ struct mqueue_inode_s
#else
uint16_t maxmsgsize; /* Max size of message in message queue */
#endif
FAR struct mq_des *ntmqdes; /* Notification: Owning mqdes (NULL if none) */
pid_t ntpid; /* Notification: Receiving Task's PID */
struct sigevent ntevent; /* Notification description */
struct sigwork_s ntwork; /* Notification work */
};
/* This describes the message queue descriptor that is held in the
* task's TCB
*/
struct mq_des
{
FAR struct mq_des *flink; /* Forward link to next message descriptor */
FAR struct mqueue_inode_s *msgq; /* Pointer to associated message queue */
int oflags; /* Flags set when message queue was opened */
};
/****************************************************************************
* Public Data
****************************************************************************/
@ -424,69 +410,6 @@ void nxmq_free_msgq(FAR struct mqueue_inode_s *msgq);
FAR struct mqueue_inode_s *nxmq_alloc_msgq(mode_t mode,
FAR struct mq_attr *attr);
/****************************************************************************
* Name: nxmq_create_des
*
* Description:
* Create a message queue descriptor for the specified TCB
*
* Input Parameters:
* TCB - task that needs the descriptor.
* msgq - Named message queue containing the message
* oflags - access rights for the descriptor
*
* Returned Value:
* On success, the message queue descriptor is returned. NULL is returned
* on a failure to allocate.
*
****************************************************************************/
mqd_t nxmq_create_des(FAR struct tcb_s *mtcb,
FAR struct mqueue_inode_s *msgq, int oflags);
/****************************************************************************
* Name: nxmq_close_group
*
* Description:
* This function is used to indicate that all threads in the group are
* finished with the specified message queue mqdes. nxmq_close_group()
* deallocates any system resources allocated by the system for use by
* this task for its message queue.
*
* Input Parameters:
* mqdes - Message queue descriptor.
* group - Group that has the open descriptor.
*
* Returned Value:
* Zero (OK) if the message queue is closed successfully. Otherwise, a
* negated errno value is returned.
*
****************************************************************************/
int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group);
/****************************************************************************
* Name: nxmq_desclose_group
*
* Description:
* This function performs the portion of the mq_close operation related
* to freeing resource used by the message queue descriptor itself.
*
* Input Parameters:
* mqdes - Message queue descriptor.
* group - Group that has the open descriptor.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* and failure.
*
* Assumptions:
* - Called only from mq_close() with the scheduler locked.
*
****************************************************************************/
int nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group);
#undef EXTERN
#ifdef __cplusplus
}

View file

@ -33,7 +33,6 @@
#include <signal.h>
#include <semaphore.h>
#include <pthread.h>
#include <mqueue.h>
#include <time.h>
#include <nuttx/clock.h>
@ -601,12 +600,6 @@ struct task_group_s
struct socketlist tg_socketlist; /* Maps socket descriptor to socket */
#endif
#ifndef CONFIG_DISABLE_MQUEUE
/* POSIX Named Message Queue Fields *******************************************/
sq_queue_t tg_msgdesq; /* List of opened message queues */
#endif
#ifdef CONFIG_ARCH_ADDRENV
/* Address Environment ********************************************************/

View file

@ -31,6 +31,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <strings.h>
#include "queue.h"
#include <nuttx/sched.h>

View file

@ -169,12 +169,6 @@ static inline void group_release(FAR struct task_group_s *group)
env_release(group);
#endif
#ifndef CONFIG_DISABLE_MQUEUE
/* Close message queues opened by members of the group */
nxmq_release(group);
#endif
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_SHM)
/* Release any resource held by shared memory virtual page allocator */

View file

@ -22,9 +22,8 @@ ifneq ($(CONFIG_DISABLE_MQUEUE),y)
CSRCS += mq_send.c mq_timedsend.c mq_sndinternal.c mq_receive.c
CSRCS += mq_timedreceive.c mq_rcvinternal.c mq_initialize.c
CSRCS += mq_descreate.c mq_desclose.c mq_msgfree.c mq_msgqalloc.c
CSRCS += mq_msgqfree.c mq_release.c mq_recover.c mq_setattr.c
CSRCS += mq_waitirq.c mq_notify.c mq_getattr.c
CSRCS += mq_msgfree.c mq_msgqalloc.c mq_msgqfree.c mq_recover.c
CSRCS += mq_setattr.c mq_waitirq.c mq_notify.c mq_getattr.c
# Include mqueue build support

View file

@ -1,140 +0,0 @@
/****************************************************************************
* sched/mqueue/mq_desclose.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <mqueue.h>
#include <sched.h>
#include <string.h>
#include <assert.h>
#include <queue.h>
#include <nuttx/sched.h>
#include <nuttx/mqueue.h>
#include "mqueue/mqueue.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: mq_desfree
*
* Description:
* Deallocate a message queue descriptor but returning it to the free list
*
* Input Parameters:
* mqdes - message queue descriptor to free
*
****************************************************************************/
#define mq_desfree(mqdes) sq_addlast((FAR sq_entry_t*)mqdes, &g_desfree)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxmq_desclose_group
*
* Description:
* This function performs the portion of the mq_close operation related
* to freeing resource used by the message queue descriptor itself.
*
* Input Parameters:
* mqdes - Message queue descriptor.
* group - Group that has the open descriptor.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* and failure.
*
* Assumptions:
* - Called only from mq_close() with the scheduler locked.
*
****************************************************************************/
int nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
{
FAR struct mqueue_inode_s *msgq;
#ifdef CONFIG_DEBUG_FEATURES
mqd_t mq_ptr;
#endif
DEBUGASSERT(mqdes != NULL && group != NULL);
#ifdef CONFIG_DEBUG_FEATURES
/* Check that msgq is valid for closing. It must be owned by the current
* group. NOTE the call to sq_rem() below would corrupt the descriptor
* list if mqdes did not lie in the list.
*/
mq_ptr = (mqd_t)sq_peek(&group->tg_msgdesq);
while (mq_ptr)
{
if (mq_ptr == mqdes)
{
break;
}
mq_ptr = (mqd_t)sq_next(mq_ptr);
}
DEBUGASSERT(mq_ptr != NULL);
if (mq_ptr == NULL)
{
/* 'mqdes' does not lie in the group's list of message descriptors. */
return -EPERM;
}
#endif
/* Remove the message descriptor from the current group's list of message
* descriptors.
*/
sq_rem((FAR sq_entry_t *)mqdes, &group->tg_msgdesq);
/* Find the message queue associated with the message descriptor */
msgq = mqdes->msgq;
/* Check if the calling task has a notification attached to the message
* queue via this mqdes.
*/
if (msgq->ntmqdes == mqdes)
{
memset(&msgq->ntevent, 0, sizeof(struct sigevent));
msgq->ntpid = INVALID_PROCESS_ID;
msgq->ntmqdes = NULL;
nxsig_cancel_notification(&msgq->ntwork);
}
/* Deallocate the message descriptor */
mq_desfree(mqdes);
return OK;
}

View file

@ -1,141 +0,0 @@
/****************************************************************************
* sched/mqueue/mq_descreate.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <mqueue.h>
#include <sched.h>
#include <queue.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/sched.h>
#include <nuttx/mqueue.h>
#include "mqueue/mqueue.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nxmq_alloc_des
*
* Description:
* Allocate a message queue descriptor.
*
* Input Parameters:
* None
*
* Returned Value:
* Reference to the allocated mq descriptor.
*
****************************************************************************/
static mqd_t nxmq_alloc_des(void)
{
mqd_t mqdes;
/* Try to get the message descriptorfrom the free list */
mqdes = (mqd_t)sq_remfirst(&g_desfree);
/* Check if we got one. */
if (!mqdes)
{
/* Add another block of message descriptors to the list */
nxmq_alloc_desblock();
/* And try again */
mqdes = (mqd_t)sq_remfirst(&g_desfree);
}
return mqdes;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxmq_create_des
*
* Description:
* Create a message queue descriptor for the specified TCB
*
* Input Parameters:
* mtcb - task that needs the descriptor.
* msgq - Named message queue containing the message
* oflags - access rights for the descriptor
*
* Returned Value:
* On success, the message queue descriptor is returned. NULL is returned
* on a failure to allocate.
*
****************************************************************************/
mqd_t nxmq_create_des(FAR struct tcb_s *mtcb,
FAR struct mqueue_inode_s *msgq, int oflags)
{
FAR struct task_group_s *group;
mqd_t mqdes;
/* A NULL TCB pointer means to use the TCB of the currently executing
* task/thread.
*/
if (!mtcb)
{
mtcb = nxsched_self();
}
group = mtcb->group;
DEBUGASSERT(group);
/* Create a message queue descriptor for the TCB */
mqdes = nxmq_alloc_des();
if (mqdes)
{
/* Initialize the message queue descriptor */
memset(mqdes, 0, sizeof(struct mq_des));
mqdes->msgq = msgq;
mqdes->oflags = oflags;
/* And add it to the specified task's TCB */
sq_addlast((FAR sq_entry_t *)mqdes, &group->tg_msgdesq);
}
return mqdes;
}

View file

@ -25,6 +25,8 @@
#include <nuttx/config.h>
#include <mqueue.h>
#include <nuttx/fs/fs.h>
#include <nuttx/mqueue.h>
/****************************************************************************
@ -51,19 +53,31 @@
int mq_getattr(mqd_t mqdes, struct mq_attr *mq_stat)
{
int ret = ERROR;
FAR struct mqueue_inode_s *msgq;
FAR struct file *filep;
FAR struct inode *inode;
int ret;
if (mqdes && mq_stat)
if (!mq_stat)
{
/* Return the attributes */
mq_stat->mq_maxmsg = mqdes->msgq->maxmsgs;
mq_stat->mq_msgsize = mqdes->msgq->maxmsgsize;
mq_stat->mq_flags = mqdes->oflags;
mq_stat->mq_curmsgs = mqdes->msgq->nmsgs;
ret = OK;
set_errno(EINVAL);
return ERROR;
}
return ret;
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
{
set_errno(-ret);
return ERROR;
}
inode = filep->f_inode;
msgq = inode->i_private;
mq_stat->mq_maxmsg = msgq->maxmsgs;
mq_stat->mq_msgsize = msgq->maxmsgsize;
mq_stat->mq_flags = filep->f_oflags;
mq_stat->mq_curmsgs = msgq->nmsgs;
return OK;
}

View file

@ -30,18 +30,6 @@
#include "mqueue/mqueue.h"
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/* This is a container for a list of message queue descriptors. */
struct mq_des_block_s
{
sq_entry_t queue;
struct mq_des mqdes[NUM_MSG_DESCRIPTORS];
};
/****************************************************************************
* Public Data
****************************************************************************/
@ -59,13 +47,6 @@ sq_queue_t g_msgfree;
sq_queue_t g_msgfreeirq;
/* The g_desfree data structure is a list of message descriptors available
* to the operating system for general use. The number of messages in the
* pool is a constant.
*/
sq_queue_t g_desfree;
/****************************************************************************
* Private Data
****************************************************************************/
@ -82,10 +63,6 @@ static struct mqueue_msg_s *g_msgalloc;
static struct mqueue_msg_s *g_msgfreeirqalloc;
/* g_desalloc is a list of allocated block of message queue descriptors. */
static sq_queue_t g_desalloc;
/****************************************************************************
* Private Functions
****************************************************************************/
@ -155,7 +132,6 @@ void nxmq_initialize(void)
sq_init(&g_msgfree);
sq_init(&g_msgfreeirq);
sq_init(&g_desalloc);
/* Allocate a block of messages for general use */
@ -170,50 +146,4 @@ void nxmq_initialize(void)
g_msgfreeirqalloc =
mq_msgblockalloc(&g_msgfreeirq, CONFIG_PREALLOC_MQ_IRQ_MSGS,
MQ_ALLOC_IRQ);
/* Allocate a block of message queue descriptors */
nxmq_alloc_desblock();
}
/****************************************************************************
* Name: nxmq_alloc_desblock
*
* Description:
* Allocate a block of message descriptors and place them on the free
* list.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void nxmq_alloc_desblock(void)
{
FAR struct mq_des_block_s *mqdesblock;
/* Allocate a block of message descriptors */
mqdesblock = (FAR struct mq_des_block_s *)
kmm_malloc(sizeof(struct mq_des_block_s));
if (mqdesblock)
{
int i;
/* Add the block to the list of allocated blocks (in case
* we ever need to reclaim the memory).
*/
sq_addlast((FAR sq_entry_t *)&mqdesblock->queue, &g_desalloc);
/* Then add each message queue descriptor to the free list */
for (i = 0; i < NUM_MSG_DESCRIPTORS; i++)
{
sq_addlast((FAR sq_entry_t *)&mqdesblock->mqdes[i], &g_desfree);
}
}
}

View file

@ -93,24 +93,34 @@
int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
{
FAR struct tcb_s *rtcb;
FAR struct mqueue_inode_s *msgq;
FAR struct inode *inode;
FAR struct file *filep;
FAR struct tcb_s *rtcb;
int errval;
errval = fs_getfilep(mqdes, &filep);
if (errval < 0)
{
goto errout_without_lock;
}
inode = filep->f_inode;
msgq = inode->i_private;
/* Was a valid message queue descriptor provided? */
if (!mqdes)
if (!msgq)
{
/* No.. return EBADF */
errval = EBADF;
goto errout;
goto errout_without_lock;
}
/* Get a pointer to the message queue */
sched_lock();
msgq = mqdes->msgq;
/* Get the current process ID */
@ -118,7 +128,7 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
/* Is there already a notification attached */
if (!msgq->ntmqdes)
if (msgq->ntpid == INVALID_PROCESS_ID)
{
/* No... Have we been asked to establish one? */
@ -139,8 +149,7 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
memcpy(&msgq->ntevent, notification,
sizeof(struct sigevent));
msgq->ntpid = rtcb->pid;
msgq->ntmqdes = mqdes;
msgq->ntpid = rtcb->pid;
}
}
@ -164,8 +173,7 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
*/
memset(&msgq->ntevent, 0, sizeof(struct sigevent));
msgq->ntpid = INVALID_PROCESS_ID;
msgq->ntmqdes = NULL;
msgq->ntpid = INVALID_PROCESS_ID;
nxsig_cancel_notification(&msgq->ntwork);
}
@ -173,7 +181,9 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
return OK;
errout:
set_errno(errval);
sched_unlock();
errout_without_lock:
set_errno(errval);
return ERROR;
}

View file

@ -53,8 +53,9 @@
* are common to both functions.
*
* Input Parameters:
* mqdes - Message Queue Descriptor
* msg - Buffer to receive the message
* msgq - Message queue descriptor
* oflags - flags from user set
* msg - Buffer to receive the message
* msglen - Size of the buffer in bytes
*
* Returned Value:
@ -64,25 +65,26 @@
* EPERM Message queue opened not opened for reading.
* EMSGSIZE 'msglen' was less than the maxmsgsize attribute of the message
* queue.
* EINVAL Invalid 'msg' or 'mqdes'
* EINVAL Invalid 'msg' or 'msgq'
*
****************************************************************************/
int nxmq_verify_receive(mqd_t mqdes, FAR char *msg, size_t msglen)
int nxmq_verify_receive(FAR struct mqueue_inode_s *msgq,
int oflags, FAR char *msg, size_t msglen)
{
/* Verify the input parameters */
if (!msg || !mqdes)
if (!msg || !msgq)
{
return -EINVAL;
}
if ((mqdes->oflags & O_RDOK) == 0)
if ((oflags & O_RDOK) == 0)
{
return -EPERM;
}
if (msglen < (size_t)mqdes->msgq->maxmsgsize)
if (msglen < (size_t)msgq->maxmsgsize)
{
return -EMSGSIZE;
}
@ -100,7 +102,8 @@ int nxmq_verify_receive(mqd_t mqdes, FAR char *msg, size_t msglen)
* returns it.
*
* Input Parameters:
* mqdes - Message queue descriptor
* msgq - Message queue descriptor
* oflags - flags from user set
* rcvmsg - The caller-provided location in which to return the newly
* received message.
*
@ -117,10 +120,10 @@ int nxmq_verify_receive(mqd_t mqdes, FAR char *msg, size_t msglen)
*
****************************************************************************/
int nxmq_wait_receive(mqd_t mqdes, FAR struct mqueue_msg_s **rcvmsg)
int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
int oflags, FAR struct mqueue_msg_s **rcvmsg)
{
FAR struct tcb_s *rtcb;
FAR struct mqueue_inode_s *msgq;
FAR struct mqueue_msg_s *newmsg;
int ret;
@ -142,10 +145,6 @@ int nxmq_wait_receive(mqd_t mqdes, FAR struct mqueue_msg_s **rcvmsg)
}
#endif
/* Get a pointer to the message queue */
msgq = mqdes->msgq;
/* Get the message from the head of the queue */
while ((newmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&msgq->msglist))
@ -155,7 +154,7 @@ int nxmq_wait_receive(mqd_t mqdes, FAR struct mqueue_msg_s **rcvmsg)
* has been satisfied?
*/
if ((mqdes->oflags & O_NONBLOCK) == 0)
if ((oflags & O_NONBLOCK) == 0)
{
/* Yes.. Block and try again */
@ -191,7 +190,7 @@ int nxmq_wait_receive(mqd_t mqdes, FAR struct mqueue_msg_s **rcvmsg)
else
{
/* The queue was empty, and the O_NONBLOCK flag was set for the
* message queue description referred to by 'mqdes'.
* message queue description.
*/
return -EAGAIN;
@ -222,7 +221,7 @@ int nxmq_wait_receive(mqd_t mqdes, FAR struct mqueue_msg_s **rcvmsg)
* and disposes of the message structure
*
* Input Parameters:
* mqdes - Message queue descriptor
* msgq - Message queue descriptor
* mqmsg - The message obtained by mq_waitmsg()
* ubuffer - The address of the user provided buffer to receive the message
* prio - The user-provided location to return the message priority.
@ -240,12 +239,12 @@ int nxmq_wait_receive(mqd_t mqdes, FAR struct mqueue_msg_s **rcvmsg)
*
****************************************************************************/
ssize_t nxmq_do_receive(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
ssize_t nxmq_do_receive(FAR struct mqueue_inode_s *msgq,
FAR struct mqueue_msg_s *mqmsg,
FAR char *ubuffer, unsigned int *prio)
{
FAR struct tcb_s *btcb;
irqstate_t flags;
FAR struct mqueue_inode_s *msgq;
ssize_t rcvmsglen;
/* Get the length of the message (also the return value) */
@ -269,7 +268,6 @@ ssize_t nxmq_do_receive(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
/* Check if any tasks are waiting for the MQ not full event. */
msgq = mqdes->msgq;
if (msgq->nwaitnotfull > 0)
{
/* Find the highest priority task that is waiting for

View file

@ -72,17 +72,31 @@
ssize_t nxmq_receive(mqd_t mqdes, FAR char *msg, size_t msglen,
FAR unsigned int *prio)
{
FAR struct mqueue_inode_s *msgq;
FAR struct mqueue_msg_s *mqmsg;
FAR struct file *filep;
FAR struct inode *inode;
irqstate_t flags;
ssize_t ret;
/* Convert fd to msgq */
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
{
return ret;
}
inode = filep->f_inode;
msgq = inode->i_private;
DEBUGASSERT(up_interrupt_context() == false);
/* Verify the input parameters and, in case of an error, set
* errno appropriately.
*/
ret = nxmq_verify_receive(mqdes, msg, msglen);
ret = nxmq_verify_receive(msgq, filep->f_oflags, msg, msglen);
if (ret < 0)
{
return ret;
@ -105,20 +119,20 @@ ssize_t nxmq_receive(mqd_t mqdes, FAR char *msg, size_t msglen,
/* Get the message from the message queue */
ret = nxmq_wait_receive(mqdes, &mqmsg);
ret = nxmq_wait_receive(msgq, filep->f_oflags, &mqmsg);
leave_critical_section(flags);
/* Check if we got a message from the message queue. We might
* not have a message if:
*
* - The message queue is empty and O_NONBLOCK is set in the mqdes
* - The message queue is empty and O_NONBLOCK is set in the filep
* - The wait was interrupted by a signal
*/
if (ret >= 0)
{
DEBUGASSERT(mqmsg != NULL);
ret = nxmq_do_receive(mqdes, mqmsg, msg, prio);
ret = nxmq_do_receive(msgq, mqmsg, msg, prio);
}
sched_unlock();

View file

@ -1,57 +0,0 @@
/****************************************************************************
* sched/mqueue/mq_release.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include "mqueue/mqueue.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxmq_release
*
* Description:
* This function is called when the final member of a task group exits.
* This function closes all of the message queues opened by members of
* the task group.
*
* Input Parameters:
* group - The task group that is terminating.
*
* Returned Value:
* None
*
****************************************************************************/
void nxmq_release(FAR struct task_group_s *group)
{
while (group->tg_msgdesq.head)
{
nxmq_close_group((mqd_t)group->tg_msgdesq.head, group);
}
}

View file

@ -70,16 +70,29 @@
int nxmq_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
unsigned int prio)
{
FAR struct mqueue_inode_s *msgq;
FAR struct mqueue_msg_s *mqmsg = NULL;
FAR struct mqueue_inode_s *msgq;
FAR struct file *filep;
FAR struct inode *inode;
irqstate_t flags;
int ret;
/* Convert fd to msgq */
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
{
return ret;
}
inode = filep->f_inode;
msgq = inode->i_private;
/* Verify the input parameters -- setting errno appropriately
* on any failures to verify.
*/
ret = nxmq_verify_send(mqdes, msg, msglen, prio);
ret = nxmq_verify_send(msgq, filep->f_oflags, msg, msglen, prio);
if (ret < 0)
{
return ret;
@ -88,7 +101,6 @@ int nxmq_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
/* Get a pointer to the message queue */
sched_lock();
msgq = mqdes->msgq;
/* Allocate a message structure:
* - Immediately if we are called from an interrupt handler.
@ -111,7 +123,7 @@ int nxmq_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
* available in the message queue.
*/
ret = nxmq_wait_send(mqdes);
ret = nxmq_wait_send(msgq, filep->f_oflags);
}
}
@ -145,7 +157,7 @@ int nxmq_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
* to be exceeded in that case.
*/
ret = nxmq_do_send(mqdes, mqmsg, msg, msglen, prio);
ret = nxmq_do_send(msgq, mqmsg, msg, msglen, prio);
}
sched_unlock();

View file

@ -27,6 +27,7 @@
#include <fcntl.h> /* O_NONBLOCK */
#include <mqueue.h>
#include <nuttx/fs/fs.h>
#include <nuttx/mqueue.h>
/****************************************************************************
@ -61,23 +62,33 @@
int mq_setattr(mqd_t mqdes, const struct mq_attr *mq_stat,
struct mq_attr *oldstat)
{
int ret = ERROR;
FAR struct file *filep;
int ret;
if (mqdes && mq_stat)
if (!mq_stat)
{
/* Return the attributes if so requested */
if (oldstat)
{
mq_getattr(mqdes, oldstat);
}
/* Set the new value of the O_NONBLOCK flag. */
mqdes->oflags = ((mq_stat->mq_flags & O_NONBLOCK) |
(mqdes->oflags & (~O_NONBLOCK)));
ret = OK;
set_errno(EINVAL);
return ERROR;
}
return ret;
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
{
set_errno(-ret);
return ERROR;
}
/* Return the attributes if so requested */
if (oldstat)
{
mq_getattr(mqdes, oldstat);
}
/* Set the new value of the O_NONBLOCK flag. */
filep->f_oflags = ((mq_stat->mq_flags & O_NONBLOCK) |
(filep->f_oflags & (~O_NONBLOCK)));
return OK;
}

View file

@ -55,38 +55,39 @@
* common to both functions.
*
* Input Parameters:
* mqdes - Message queue descriptor
* msg - Message to send
* msgq - Message queue descriptor
* oflags - flags from user set
* msg - Message to send
* msglen - The length of the message in bytes
* prio - The priority of the message
* prio - The priority of the message
*
* Returned Value:
* One success, 0 (OK) is returned. On failure, a negated errno value is
* returned.
*
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
* EINVAL Either msg or msgq is NULL or the value of prio is invalid.
* EPERM Message queue opened not opened for writing.
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
* message queue.
*
****************************************************************************/
int nxmq_verify_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
unsigned int prio)
int nxmq_verify_send(FAR struct mqueue_inode_s *msgq, int oflags,
FAR const char *msg, size_t msglen, unsigned int prio)
{
/* Verify the input parameters */
if (msg == NULL || mqdes == NULL || prio > MQ_PRIO_MAX)
if (msg == NULL || msgq == NULL || prio > MQ_PRIO_MAX)
{
return -EINVAL;
}
if ((mqdes->oflags & O_WROK) == 0)
if ((oflags & O_WROK) == 0)
{
return -EPERM;
}
if (msglen > (size_t)mqdes->msgq->maxmsgsize)
if (msglen > (size_t)msgq->maxmsgsize)
{
return -EMSGSIZE;
}
@ -190,14 +191,15 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
* full.
*
* Input Parameters:
* mqdes - Message queue descriptor
* msgq - Message queue descriptor
* oflags - flags from user set
*
* Returned Value:
* On success, nxmq_wait_send() returns 0 (OK); a negated errno value is
* returned on any failure:
*
* EAGAIN The queue was full and the O_NONBLOCK flag was set for the
* message queue description referred to by mqdes.
* message queue description referred to by msgq.
* EINTR The call was interrupted by a signal handler.
* ETIMEOUT A timeout expired before the message queue became non-full
* (mq_timedsend only).
@ -208,10 +210,9 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
*
****************************************************************************/
int nxmq_wait_send(mqd_t mqdes)
int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int oflags)
{
FAR struct tcb_s *rtcb;
FAR struct mqueue_inode_s *msgq;
int ret;
#ifdef CONFIG_CANCELLATION_POINTS
@ -229,10 +230,6 @@ int nxmq_wait_send(mqd_t mqdes)
}
#endif
/* Get a pointer to the message queue */
msgq = mqdes->msgq;
/* Verify that the queue is indeed full as the caller thinks */
if (msgq->nmsgs >= msgq->maxmsgs)
@ -241,7 +238,7 @@ int nxmq_wait_send(mqd_t mqdes)
* message queue?
*/
if ((mqdes->oflags & O_NONBLOCK) != 0)
if ((oflags & O_NONBLOCK) != 0)
{
/* No... We will return an error to the caller. */
@ -305,12 +302,12 @@ int nxmq_wait_send(mqd_t mqdes)
* Description:
* This is internal, common logic shared by both [nx]mq_send and
* [nx]mq_timesend. This function adds the specified message (msg) to the
* message queue (mqdes). Then it notifies any tasks that were waiting
* message queue (msgq). Then it notifies any tasks that were waiting
* for message queue notifications setup by mq_notify. And, finally, it
* awakens any tasks that were waiting for the message not empty event.
*
* Input Parameters:
* mqdes - Message queue descriptor
* msgq - Message queue descriptor
* msg - Message to send
* msglen - The length of the message in bytes
* prio - The priority of the message
@ -320,11 +317,11 @@ int nxmq_wait_send(mqd_t mqdes)
*
****************************************************************************/
int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
FAR struct mqueue_msg_s *mqmsg,
FAR const char *msg, size_t msglen, unsigned int prio)
{
FAR struct tcb_s *btcb;
FAR struct mqueue_inode_s *msgq;
FAR struct mqueue_msg_s *next;
FAR struct mqueue_msg_s *prev;
irqstate_t flags;
@ -332,7 +329,6 @@ int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
/* Get a pointer to the message queue */
sched_lock();
msgq = mqdes->msgq;
/* Construct the message header info */
@ -376,7 +372,7 @@ int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
* message queue
*/
if (msgq->ntmqdes)
if (msgq->ntpid != INVALID_PROCESS_ID)
{
struct sigevent event;
pid_t pid;
@ -389,8 +385,7 @@ int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
/* Detach the notification */
memset(&msgq->ntevent, 0, sizeof(struct sigevent));
msgq->ntpid = INVALID_PROCESS_ID;
msgq->ntmqdes = NULL;
msgq->ntpid = INVALID_PROCESS_ID;
/* Notification the client */

View file

@ -138,17 +138,31 @@ ssize_t nxmq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
FAR const struct timespec *abstime)
{
FAR struct tcb_s *rtcb = this_task();
FAR struct mqueue_inode_s *msgq;
FAR struct mqueue_msg_s *mqmsg;
FAR struct file *filep;
FAR struct inode *inode;
irqstate_t flags;
int ret;
/* Convert fd to msgq */
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
{
return ret;
}
inode = filep->f_inode;
msgq = inode->i_private;
DEBUGASSERT(up_interrupt_context() == false);
/* Verify the input parameters and, in case of an error, set
* errno appropriately.
*/
ret = nxmq_verify_receive(mqdes, msg, msglen);
ret = nxmq_verify_receive(msgq, filep->f_oflags, msg, msglen);
if (ret < 0)
{
return ret;
@ -178,7 +192,7 @@ ssize_t nxmq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
* will not need to start timer.
*/
if (mqdes->msgq->msglist.head == NULL)
if (msgq->msglist.head == NULL)
{
sclock_t ticks;
@ -213,7 +227,7 @@ ssize_t nxmq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
/* Get the message from the message queue */
ret = nxmq_wait_receive(mqdes, &mqmsg);
ret = nxmq_wait_receive(msgq, filep->f_oflags, &mqmsg);
/* Stop the watchdog timer (this is not harmful in the case where
* it was never started)
@ -236,7 +250,7 @@ ssize_t nxmq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
if (ret >= 0)
{
DEBUGASSERT(mqmsg != NULL);
ret = nxmq_do_receive(mqdes, mqmsg, msg, prio);
ret = nxmq_do_receive(msgq, mqmsg, msg, prio);
}
sched_unlock();

View file

@ -145,18 +145,31 @@ int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen,
unsigned int prio, FAR const struct timespec *abstime)
{
FAR struct tcb_s *rtcb = this_task();
FAR struct mqueue_inode_s *msgq;
FAR struct mqueue_msg_s *mqmsg = NULL;
FAR struct mqueue_inode_s *msgq;
FAR struct file *filep;
FAR struct inode *inode;
irqstate_t flags;
sclock_t ticks;
int result;
int ret;
/* Convert fd to msgq */
ret = fs_getfilep(mqdes, &filep);
if (ret < 0)
{
return ret;
}
inode = filep->f_inode;
msgq = inode->i_private;
DEBUGASSERT(up_interrupt_context() == false);
/* Verify the input parameters on any failures to verify. */
ret = nxmq_verify_send(mqdes, msg, msglen, prio);
ret = nxmq_verify_send(msgq, filep->f_oflags, msg, msglen, prio);
if (ret < 0)
{
return ret;
@ -177,7 +190,6 @@ int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen,
/* Get a pointer to the message queue */
sched_lock();
msgq = mqdes->msgq;
/* OpenGroup.org: "Under no circumstance shall the operation fail with a
* timeout if there is sufficient room in the queue to add the message
@ -199,7 +211,7 @@ int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen,
* Currently nxmq_do_send() always returns OK.
*/
ret = nxmq_do_send(mqdes, mqmsg, msg, msglen, prio);
ret = nxmq_do_send(msgq, mqmsg, msg, msglen, prio);
sched_unlock();
return ret;
}
@ -247,7 +259,7 @@ int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen,
/* And wait for the message queue to be non-empty */
ret = nxmq_wait_send(mqdes);
ret = nxmq_wait_send(msgq, filep->f_oflags);
/* This may return with an error and errno set to either EINTR
* or ETIMEOUT. Cancel the watchdog timer in any event.
@ -275,7 +287,7 @@ int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen,
* Currently nxmq_do_send() always returns OK.
*/
ret = nxmq_do_send(mqdes, mqmsg, msg, msglen, prio);
ret = nxmq_do_send(msgq, mqmsg, msg, msglen, prio);
sched_unlock();
leave_cancellation_point();

View file

@ -47,12 +47,6 @@
#define MQ_MAX_MSGS 16
#define MQ_PRIO_MAX _POSIX_MQ_PRIO_MAX
/* This defines the number of messages descriptors to allocate at each
* "gulp."
*/
#define NUM_MSG_DESCRIPTORS 4
/********************************************************************************
* Public Type Definitions
********************************************************************************/
@ -103,13 +97,6 @@ EXTERN sq_queue_t g_msgfree;
EXTERN sq_queue_t g_msgfreeirq;
/* The g_desfree data structure is a list of message descriptors available
* to the operating system for general use. The number of messages in the
* pool is a constant.
*/
EXTERN sq_queue_t g_desfree;
/********************************************************************************
* Public Function Prototypes
********************************************************************************/
@ -120,7 +107,6 @@ struct task_group_s; /* Forward reference */
/* Functions defined in mq_initialize.c *****************************************/
void weak_function nxmq_initialize(void);
void nxmq_alloc_desblock(void);
void nxmq_free_msg(FAR struct mqueue_msg_s *mqmsg);
/* mq_waitirq.c *****************************************************************/
@ -129,24 +115,24 @@ void nxmq_wait_irq(FAR struct tcb_s *wtcb, int errcode);
/* mq_rcvinternal.c *************************************************************/
int nxmq_verify_receive(mqd_t mqdes, FAR char *msg, size_t msglen);
int nxmq_wait_receive(mqd_t mqdes, FAR struct mqueue_msg_s **rcvmsg);
ssize_t nxmq_do_receive(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
FAR char *ubuffer, FAR unsigned int *prio);
int nxmq_verify_receive(FAR struct mqueue_inode_s *msgq,
int oflags, FAR char *msg, size_t msglen);
int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
int oflags, FAR struct mqueue_msg_s **rcvmsg);
ssize_t nxmq_do_receive(FAR struct mqueue_inode_s *msgq,
FAR struct mqueue_msg_s *mqmsg,
FAR char *ubuffer, unsigned int *prio);
/* mq_sndinternal.c *************************************************************/
int nxmq_verify_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
unsigned int prio);
int nxmq_verify_send(FAR struct mqueue_inode_s *msgq, int oflags,
FAR const char *msg, size_t msglen, unsigned int prio);
FAR struct mqueue_msg_s *nxmq_alloc_msg(void);
int nxmq_wait_send(mqd_t mqdes);
int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int oflags);
int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
FAR struct mqueue_msg_s *mqmsg,
FAR const char *msg, size_t msglen, unsigned int prio);
/* mq_release.c *****************************************************************/
void nxmq_release(FAR struct task_group_s *group);
/* mq_recover.c *****************************************************************/
void nxmq_recover(FAR struct tcb_s *tcb);