mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 03:45:50 +08:00
sched/event: Add nxevent_wait_irq() to handle the task cancel
If the thread is blocked waiting on a event, then the
thread must be unblocked from the evnet to handle
the task cancellation.
Signed-off-by: Chengdong Wang wangchengdong@lixiang.com
This commit is contained in:
committed by
Alan C. Assis
parent
735e489070
commit
39f54c1524
@@ -32,7 +32,8 @@ if(CONFIG_SCHED_EVENTS)
|
|||||||
event_destroy.c
|
event_destroy.c
|
||||||
event_wait.c
|
event_wait.c
|
||||||
event_clear.c
|
event_clear.c
|
||||||
event_getmask.c)
|
event_getmask.c
|
||||||
|
event_waitirq.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_sources(sched PRIVATE ${CSRCS})
|
target_sources(sched PRIVATE ${CSRCS})
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
ifeq ($(CONFIG_SCHED_EVENTS),y)
|
ifeq ($(CONFIG_SCHED_EVENTS),y)
|
||||||
CSRCS += event_init.c event_post.c event_reset.c event_destroy.c event_wait.c event_clear.c event_getmask.c
|
CSRCS += event_init.c event_post.c event_reset.c event_destroy.c event_wait.c event_clear.c event_getmask.c
|
||||||
|
CSRCS += event_waitirq.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Include event build support
|
# Include event build support
|
||||||
|
|||||||
+3
-2
@@ -31,12 +31,13 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/list.h>
|
#include <nuttx/list.h>
|
||||||
#include <nuttx/semaphore.h>
|
|
||||||
|
|
||||||
#include <nuttx/event.h>
|
#include <nuttx/event.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Definitions
|
* Public Function Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
void nxevent_wait_irq(FAR struct tcb_s *wtcb, int errcode);
|
||||||
|
|
||||||
#endif /* __SCHED_EVENT_EVENT_H */
|
#endif /* __SCHED_EVENT_EVENT_H */
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ int nxevent_post(FAR nxevent_t *event, nxevent_mask_t events,
|
|||||||
|
|
||||||
wtcb = wait->wtcb;
|
wtcb = wait->wtcb;
|
||||||
|
|
||||||
|
wtcb->waitobj = NULL;
|
||||||
|
|
||||||
/* Remove the task from waiting list */
|
/* Remove the task from waiting list */
|
||||||
|
|
||||||
dq_rem((FAR dq_entry_t *)wtcb, list_waitingforsignal());
|
dq_rem((FAR dq_entry_t *)wtcb, list_waitingforsignal());
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ static void nxevent_timeout(wdparm_t arg)
|
|||||||
|
|
||||||
/* Get waiting tcb from parameter */
|
/* Get waiting tcb from parameter */
|
||||||
|
|
||||||
wait = (FAR nxevent_wait_t *)(uintptr_t)arg;
|
wtcb = (FAR struct tcb_s *)(uintptr_t)arg;
|
||||||
wtcb = wait->wtcb;
|
wait = wtcb->waitobj;
|
||||||
|
|
||||||
/* We must be in a critical section in order to call up_switch_context()
|
/* We must be in a critical section in order to call up_switch_context()
|
||||||
* below.
|
* below.
|
||||||
@@ -82,6 +82,8 @@ static void nxevent_timeout(wdparm_t arg)
|
|||||||
list_delete(&(wait->node));
|
list_delete(&(wait->node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wtcb->waitobj = NULL;
|
||||||
|
|
||||||
/* Mark the errno value for the thread. */
|
/* Mark the errno value for the thread. */
|
||||||
|
|
||||||
wtcb->errcode = ETIMEDOUT;
|
wtcb->errcode = ETIMEDOUT;
|
||||||
@@ -199,13 +201,14 @@ nxevent_mask_t nxevent_tickwait_wait(FAR nxevent_t *event,
|
|||||||
/* Initialize event wait */
|
/* Initialize event wait */
|
||||||
|
|
||||||
wtcb = this_task();
|
wtcb = this_task();
|
||||||
|
wtcb->waitobj = (FAR void *)wait;
|
||||||
wait->expect = events;
|
wait->expect = events;
|
||||||
wait->eflags = eflags;
|
wait->eflags = eflags;
|
||||||
wait->wtcb = wtcb;
|
wait->wtcb = wtcb;
|
||||||
|
|
||||||
list_add_tail(&event->list, &(wait->node));
|
list_add_tail(&event->list, &(wait->node));
|
||||||
|
|
||||||
wd_start(&wtcb->waitdog, delay, nxevent_timeout, (uintptr_t)&wait);
|
wd_start(&wtcb->waitdog, delay, nxevent_timeout, (uintptr_t)wtcb);
|
||||||
|
|
||||||
/* Remove the tcb task from the ready-to-run list. */
|
/* Remove the tcb task from the ready-to-run list. */
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* sched/event/event_waitirq.c
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* 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 <sched.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
|
#include "sched/sched.h"
|
||||||
|
#include "event/event.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxevent_wait_irq
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* An error event has occurred and the event wait must be terminated with
|
||||||
|
* an error.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void nxevent_wait_irq(FAR struct tcb_s *wtcb, int errcode)
|
||||||
|
{
|
||||||
|
/* It is possible that an interrupt/context switch beat us to the punch
|
||||||
|
* and already changed the task's state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
DEBUGASSERT(wtcb != NULL);
|
||||||
|
|
||||||
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
|
FAR nxevent_wait_t *wait = wtcb->waitobj;
|
||||||
|
|
||||||
|
DEBUGASSERT(wait != NULL);
|
||||||
|
|
||||||
|
/* Remove the wait structure from the event's waiting list */
|
||||||
|
|
||||||
|
if (list_in_list(&(wait->node)))
|
||||||
|
{
|
||||||
|
list_delete(&(wait->node));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the task from the event waiting list */
|
||||||
|
|
||||||
|
dq_rem((FAR dq_entry_t *)wtcb, list_waitingforsignal());
|
||||||
|
|
||||||
|
/* Indicate that the wait is over */
|
||||||
|
|
||||||
|
wtcb->waitobj = NULL;
|
||||||
|
|
||||||
|
/* Store the error code for the thread */
|
||||||
|
|
||||||
|
wtcb->errcode = errcode;
|
||||||
|
|
||||||
|
/* Add the task to the ready-to-run list and perform a context
|
||||||
|
* switch if one is needed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (nxsched_add_readytorun(wtcb))
|
||||||
|
{
|
||||||
|
up_switch_context(this_task(), rtcb);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,6 +67,7 @@
|
|||||||
#include "signal/signal.h"
|
#include "signal/signal.h"
|
||||||
#include "mqueue/mqueue.h"
|
#include "mqueue/mqueue.h"
|
||||||
#include "task/task.h"
|
#include "task/task.h"
|
||||||
|
#include "event/event.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@@ -165,6 +166,17 @@ bool nxnotify_cancellation(FAR struct tcb_s *tcb)
|
|||||||
nxsig_wait_irq(tcb, SIG_CANCEL_TIMEOUT, SI_USER, ECANCELED);
|
nxsig_wait_irq(tcb, SIG_CANCEL_TIMEOUT, SI_USER, ECANCELED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_EVENTS
|
||||||
|
/* If the thread is blocked waiting on a event, then the
|
||||||
|
* thread must be unblocked to handle the cancellation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
else if (tcb->task_state == TSTATE_WAIT_EVENT)
|
||||||
|
{
|
||||||
|
nxevent_wait_irq(tcb, ECANCELED);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(CONFIG_DISABLE_MQUEUE) || !defined(CONFIG_DISABLE_MQUEUE_SYSV)
|
#if !defined(CONFIG_DISABLE_MQUEUE) || !defined(CONFIG_DISABLE_MQUEUE_SYSV)
|
||||||
/* If the thread is blocked waiting on a message queue, then
|
/* If the thread is blocked waiting on a message queue, then
|
||||||
* the thread must be unblocked to handle the cancellation.
|
* the thread must be unblocked to handle the cancellation.
|
||||||
|
|||||||
Reference in New Issue
Block a user