xiaoxiang781216 commented on code in PR #7088: URL: https://github.com/apache/incubator-nuttx/pull/7088#discussion_r999761431
########## sched/mqueue/msgctl.c: ########## @@ -0,0 +1,124 @@ +/**************************************************************************** + * sched/mqueue/msgctl.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 "mqueue/msg.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: msgctl + * + * Description: + * System V message control operations. + * msgctl() performs the control operation specified by cmd on the + * System V message queue with identifier msqid. + * + * Input Parameters: + * msqid - System V message queue identifier + * cmd - Command operations + * msqid_ds - Defines a message queue + * + * Returned Value: + * On success, IPC_STAT, IPC_SET, and IPC_RMID return 0. A + * successful IPC_INFO or MSG_INFO operation returns the index of + * the highest used entry in the kernel's internal array recording + * information about all message queues. (This information can be + * used with repeated MSG_STAT or MSG_STAT_ANY operations to obtain + * information about all queues on the system.) A successful + * MSG_STAT or MSG_STAT_ANY operation returns the identifier of the + * queue whose index was given in msqid. + * + * On failure, -1 is returned and errno is set to indicate the error. + * + ****************************************************************************/ + +int msgctl(int msqid, int cmd, struct msqid_ds *buf) +{ + FAR struct msgq_s *msgq; + irqstate_t flags; + int ret = OK; + + flags = enter_critical_section(); + + msgq = nxmsg_lookup((key_t)msqid); Review Comment: change the argument type of nxmsg_lookup to int instead cast ########## sched/mqueue/msg.h: ########## @@ -0,0 +1,98 @@ +/******************************************************************************** + * sched/mqueue/msg.h + * + * 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. + * + ********************************************************************************/ + +#ifndef __SCHED_MQUEUE_MSG_H +#define __SCHED_MQUEUE_MSG_H + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include <nuttx/config.h> +#include <nuttx/compiler.h> + +#include <nuttx/irq.h> +#include <nuttx/list.h> +#include <nuttx/mqueue.h> +#include <sys/msg.h> + +#include <errno.h> + +#if defined(CONFIG_MQ_MAXMSGSIZE) && CONFIG_MQ_MAXMSGSIZE > 0 + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +#define MSG_MAX_BYTES CONFIG_MQ_MAXMSGSIZE +#define MSG_MAX_MSGS 16 + +/******************************************************************************** + * Public Type Definitions + ********************************************************************************/ + +struct msgq_s +{ + struct mqueue_cmn_s cmn; + struct list_node msglist; /* Prioritized message list */ + key_t key; + int16_t maxmsgs; /* Maximum number of messages in the queue */ + int16_t nmsgs; /* Number of message in the queue */ + uint16_t maxmsgsize; /* Max size of message in message queue */ +}; + +struct msgbuf_s +{ + struct list_node node; + uint16_t msize; /* Message data length */ + long mtype; /* Message type, must be > 0 */ + char mtext[MSG_MAX_BYTES]; /* Message data */ +}; + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +EXTERN struct list_node g_msgfreelist; Review Comment: change to static ########## sched/mqueue/msg.h: ########## @@ -0,0 +1,98 @@ +/******************************************************************************** + * sched/mqueue/msg.h + * + * 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. + * + ********************************************************************************/ + +#ifndef __SCHED_MQUEUE_MSG_H +#define __SCHED_MQUEUE_MSG_H + +/******************************************************************************** + * Included Files + ********************************************************************************/ + +#include <nuttx/config.h> +#include <nuttx/compiler.h> + +#include <nuttx/irq.h> +#include <nuttx/list.h> Review Comment: remove ########## sched/mqueue/msginternal.c: ########## @@ -0,0 +1,198 @@ +/**************************************************************************** + * sched/mqueue/msginternal.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/kmalloc.h> +#include "mqueue/msg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MQ_PERBLOCK 10 + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +struct nxmsg_manager_s +{ + uint8_t nmsgq; /* The number of groups of msgs array */ + FAR struct msgq_s **msgqs; /* The pointer of two layer file descriptors array */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct nxmsg_manager_s g_msgmgrs; Review Comment: remove nxmsg_manager_s and use nmsgq/msgqs directly? ########## sched/mqueue/msginternal.c: ########## @@ -0,0 +1,198 @@ +/**************************************************************************** + * sched/mqueue/msginternal.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/kmalloc.h> +#include "mqueue/msg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MQ_PERBLOCK 10 + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +struct nxmsg_manager_s +{ + uint8_t nmsgq; /* The number of groups of msgs array */ + FAR struct msgq_s **msgqs; /* The pointer of two layer file descriptors array */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct nxmsg_manager_s g_msgmgrs; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +struct list_node g_msgfreelist = LIST_INITIAL_VALUE(g_msgfreelist); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmsg_alloc_internal + ****************************************************************************/ + +static FAR struct msgq_s *nxmsg_alloc_internal(void) +{ + FAR struct msgq_s *msgq; + FAR struct msgq_s **tmp; + int i; + + msgq = kmm_zalloc(sizeof(struct msgq_s)); + if (msgq == NULL) + { + return NULL; + } + + for (i = 0; i < g_msgmgrs.nmsgq; i++) + { + if (g_msgmgrs.msgqs[i] == NULL) + { + g_msgmgrs.msgqs[i] = msgq; + msgq->key = i + 1; + return msgq; + } + } + + tmp = kmm_realloc(g_msgmgrs.msgqs, sizeof(FAR void *) * + (g_msgmgrs.nmsgq + MQ_PERBLOCK)); + if (tmp == NULL) + { + kmm_free(msgq); + return NULL; + } + + g_msgmgrs.msgqs = tmp; + + memset(&g_msgmgrs.msgqs[g_msgmgrs.nmsgq], 0, + sizeof(FAR void *) * MQ_PERBLOCK); + + g_msgmgrs.msgqs[g_msgmgrs.nmsgq] = msgq; + + msgq->key = g_msgmgrs.nmsgq + 1; + + g_msgmgrs.nmsgq += MQ_PERBLOCK; + + return msgq; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmsg_initialize + ****************************************************************************/ + +void nxmsg_initialize(void) +{ + FAR struct msgbuf_s *msg; + + msg = (FAR struct msgbuf_s *)kmm_malloc(sizeof(*msg) * + CONFIG_PREALLOC_MQ_MSGS); + if (msg) + { + int i; + for (i = 0; i < CONFIG_PREALLOC_MQ_MSGS; i++) + { + list_add_tail(&g_msgfreelist, &msg->node); + msg++; + } + } +} + +/**************************************************************************** + * Name: nxmsg_alloc + ****************************************************************************/ + +int nxmsg_alloc(FAR struct msgq_s **pmsgq) +{ + FAR struct msgq_s *msgq; + + msgq = nxmsg_alloc_internal(); + if (msgq == NULL) + { + return -ENOMEM; + } + + /* Initialize the new named message queue */ + + list_initialize(&msgq->msglist); + + msgq->maxmsgs = MSG_MAX_MSGS; + msgq->maxmsgsize = MSG_MAX_BYTES; + + *pmsgq = msgq; + return OK; +} + +/**************************************************************************** + * Name: nxmsg_free + ****************************************************************************/ + +void nxmsg_free(FAR struct msgq_s *msgq) +{ + FAR struct msgbuf_s *entry; + FAR struct msgbuf_s *tmp; + int index; + + if (msgq == NULL || msgq->key <= 0 || msgq->key > g_msgmgrs.nmsgq) + { + return; + } + + index = msgq->key - 1; + + list_for_every_entry_safe(&msgq->msglist, entry, + tmp, struct msgbuf_s, node) + { + list_delete(&entry->node); + list_add_tail(&g_msgfreelist, &entry->node); + } + + kmm_free(g_msgmgrs.msgqs[index]); + g_msgmgrs.msgqs[index] = NULL; +} + +/**************************************************************************** + * Name: nxmsg_lookup + ****************************************************************************/ + +FAR struct msgq_s *nxmsg_lookup(key_t key) Review Comment: key_t to int ########## sched/mqueue/msgsnd.c: ########## @@ -0,0 +1,246 @@ +/**************************************************************************** + * sched/mqueue/msgsnd.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 <assert.h> + +#include <nuttx/cancelpt.h> + +#include "sched/sched.h" +#include "mqueue/msg.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: msgsnd_wait + ****************************************************************************/ + +static int msgsnd_wait(FAR struct msgq_s *msgq, int msgflg) +{ + FAR struct tcb_s *rtcb; + +#ifdef CONFIG_CANCELLATION_POINTS + /* msgsnd_wait() is not a cancellation point, but may be called via + * msgsnd() which are cancellation points. + */ + + if (check_cancellation_point()) + { + /* If there is a pending cancellation, then do not perform + * the wait. Exit now with ECANCELED. + */ + + return -ECANCELED; + } +#endif + + /* Verify that the queue is indeed full as the caller thinks + * Loop until there are fewer than max allowable messages in the + * receiving message queue + */ + + while (msgq->nmsgs >= msgq->maxmsgs) + { + /* Should we block until there is sufficient space in the + * message queue? + */ + + if ((msgflg & IPC_NOWAIT) != 0) + { + return -EAGAIN; + } + + /* Block until the message queue is no longer full. + * When we are unblocked, we will try again + */ + + rtcb = this_task(); + rtcb->waitobj = msgq; + msgq->cmn.nwaitnotfull++; + + /* Initialize the errcode used to communication wake-up error + * conditions. + */ + + rtcb->errcode = OK; + + /* Make sure this is not the idle task, descheduling that + * isn't going to end well. + */ + + DEBUGASSERT(NULL != rtcb->flink); + up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL); + + /* When we resume at this point, either (1) the message queue + * is no longer empty, or (2) the wait has been interrupted by + * a signal. We can detect the latter case be examining the + * per-task errno value (should be EINTR or ETIMEOUT). + */ + + if (rtcb->errcode != OK) + { + return -rtcb->errcode; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: msgsnd + * + * Description: + * The msgsnd() function is used to send a message to the queue + * associated with the message queue identifier specified by msqid. + * The msgp argument points to a user-defined buffer that must contain + * first a field of type long int that will specify the type of the + * message, and then a data portion that will hold the data bytes of + * the message. + * + * Input Parameters: + * msqid - Message queue identifier + * msgp - Pointer to a buffer with the message to be sent + * msgsz - Length of the data part of the message to be sent + * msgflg - Operations flags + * + * Returned Value: + * On success, mq_send() returns 0 (OK); on error, -1 (ERROR) + * is returned, with errno set to indicate the error: + * + * EAGAIN The queue was full and the O_NONBLOCK flag was set for the + * message queue description referred to by mqdes. + * EINVAL Either msg or mqdes 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. + * EINTR The call was interrupted by a signal handler. + * + ****************************************************************************/ + +int msgsnd(int msqid, FAR const void *msgp, size_t msgsz, int msgflg) +{ + FAR const struct mymsg *buf = msgp; + FAR struct msgbuf_s *msg; + FAR struct msgq_s *msgq; + FAR struct tcb_s *btcb; + irqstate_t flags; + int ret = OK; + + if (msgp == NULL) + { + ret = -EFAULT; + goto errout; + } + + flags = enter_critical_section(); + + msgq = nxmsg_lookup(msqid); + if (msgq == NULL) + { + ret = -EINVAL; + goto errout_with_critical; + } + + if (msgsz > msgq->maxmsgsize) + { + ret = -EMSGSIZE; + goto errout_with_critical; + } + + if (!up_interrupt_context()) /* In an interrupt handler? */ + { + /* No.. Not in an interrupt handler. Is the message queue FULL? */ + + if (msgq->nmsgs >= msgq->maxmsgs) + { + /* Yes.. the message queue is full. Wait for space to become + * available in the message queue. + */ + + ret = msgsnd_wait(msgq, msgflg); + } Review Comment: should we return error in else branch -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org