mirror of
https://github.com/apache/nuttx.git
synced 2026-05-26 18:56:10 +08:00
sched/timedwait: Ensure critical section for nxsig_timeout
nxsig_timeout calls nxsched_add_readytorun and up_switch_context, so must be in critical section. nxsig_timeout is used as wdentry in nxsig_clockwait See wd_expiration CALL_FUNC is not in critical section. Signed-off-by: Serg Podtynnyi <serg@podtynnyi.com>
This commit is contained in:
committed by
Xiang Xiao
parent
57a7cb503a
commit
c5757ed71f
@@ -78,20 +78,14 @@
|
||||
static void nxsig_timeout(wdparm_t arg)
|
||||
{
|
||||
FAR struct tcb_s *wtcb = (FAR struct tcb_s *)(uintptr_t)arg;
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
irqstate_t flags;
|
||||
|
||||
/* We must be in a critical section in order to call up_switch_context()
|
||||
* below. If we are running on a single CPU architecture, then we know
|
||||
* interrupts a disabled an there is no need to explicitly call
|
||||
* enter_critical_section(). However, in the SMP case,
|
||||
* enter_critical_section() does much more than just disable interrupts on
|
||||
* the local CPU; it also manages spinlocks to assure the stability of the
|
||||
* TCB that we are manipulating.
|
||||
* below.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
#endif
|
||||
|
||||
/* There may be a race condition -- make sure the task is
|
||||
* still waiting for a signal
|
||||
@@ -127,9 +121,7 @@ static void nxsig_timeout(wdparm_t arg)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -252,8 +244,8 @@ int nxsig_clockwait(int clockid, int flags,
|
||||
FAR const struct timespec *rqtp,
|
||||
FAR struct timespec *rmtp)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
irqstate_t iflags;
|
||||
FAR struct tcb_s *rtcb;
|
||||
irqstate_t iflags;
|
||||
clock_t expect = 0;
|
||||
clock_t stop;
|
||||
|
||||
@@ -297,6 +289,7 @@ int nxsig_clockwait(int clockid, int flags,
|
||||
#endif
|
||||
|
||||
iflags = enter_critical_section();
|
||||
rtcb = this_task();
|
||||
|
||||
if (rqtp)
|
||||
{
|
||||
@@ -394,7 +387,7 @@ int nxsig_clockwait(int clockid, int flags,
|
||||
int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
||||
FAR const struct timespec *timeout)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
FAR struct tcb_s *rtcb;
|
||||
sigset_t intersection;
|
||||
FAR sigpendq_t *sigpend;
|
||||
irqstate_t flags;
|
||||
@@ -410,6 +403,7 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
rtcb = this_task();
|
||||
|
||||
/* Check if there is a pending signal corresponding to one of the
|
||||
* signals in the pending signal set argument.
|
||||
|
||||
Reference in New Issue
Block a user