kernel: fix mailbox usage of SYS_DLIST_FOR_EACH_NODE()
SYS_DLIST_FOR_EACH_NODE() is marked as non-safe when an item is removed from the list while looping over it. This is not true per-se, since the item, when removed, keeps its next and prev pointers intact; however, it is true if the item is then put into a list, be it a different one or the same one. To prevent this, SYS_DLIST_FOR_EACH_NODE_SAFE() must be used. _mbox_message_put() can remove items from the rx queue and then put them in the ready queue: this would cause the loop to start processing other ready threads as item in the rx queue. k_mbox_get() also removes items, from the tx queue, but does not seem to add them to another list; however, it now uses the safe version as well, since that is the proper usage. Change-Id: Ieccbff238fc8a036c0d53d873eaaf55f4f5a14af Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com> Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
1e20e8dc04
commit
ade6dc937f
1 changed files with 8 additions and 4 deletions
|
@ -250,7 +250,7 @@ static int _mbox_message_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg,
|
|||
struct k_thread *sending_thread;
|
||||
struct k_thread *receiving_thread;
|
||||
struct k_mbox_msg *rx_msg;
|
||||
sys_dnode_t *wait_q_item;
|
||||
sys_dnode_t *wait_q_item, *next_wait_q_item;
|
||||
unsigned int key;
|
||||
|
||||
/* save sender id so it can be used during message matching */
|
||||
|
@ -263,7 +263,9 @@ static int _mbox_message_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg,
|
|||
/* search mailbox's rx queue for a compatible receiver */
|
||||
key = irq_lock();
|
||||
|
||||
SYS_DLIST_FOR_EACH_NODE(&mbox->rx_msg_queue, wait_q_item) {
|
||||
SYS_DLIST_FOR_EACH_NODE_SAFE(&mbox->rx_msg_queue, wait_q_item,
|
||||
next_wait_q_item) {
|
||||
|
||||
receiving_thread = (struct k_thread *)wait_q_item;
|
||||
rx_msg = (struct k_mbox_msg *)receiving_thread->base.swap_data;
|
||||
|
||||
|
@ -436,7 +438,7 @@ int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, void *buffer,
|
|||
{
|
||||
struct k_thread *sending_thread;
|
||||
struct k_mbox_msg *tx_msg;
|
||||
sys_dnode_t *wait_q_item;
|
||||
sys_dnode_t *wait_q_item, *next_wait_q_item;
|
||||
unsigned int key;
|
||||
int result;
|
||||
|
||||
|
@ -446,7 +448,9 @@ int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, void *buffer,
|
|||
/* search mailbox's tx queue for a compatible sender */
|
||||
key = irq_lock();
|
||||
|
||||
SYS_DLIST_FOR_EACH_NODE(&mbox->tx_msg_queue, wait_q_item) {
|
||||
SYS_DLIST_FOR_EACH_NODE_SAFE(&mbox->tx_msg_queue, wait_q_item,
|
||||
next_wait_q_item) {
|
||||
|
||||
sending_thread = (struct k_thread *)wait_q_item;
|
||||
tx_msg = (struct k_mbox_msg *)sending_thread->base.swap_data;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue