mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +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)
|
static void nxsig_timeout(wdparm_t arg)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *wtcb = (FAR struct tcb_s *)(uintptr_t)arg;
|
FAR struct tcb_s *wtcb = (FAR struct tcb_s *)(uintptr_t)arg;
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
/* 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. If we are running on a single CPU architecture, then we know
|
* below.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
#endif
|
|
||||||
|
|
||||||
/* There may be a race condition -- make sure the task is
|
/* There may be a race condition -- make sure the task is
|
||||||
* still waiting for a signal
|
* still waiting for a signal
|
||||||
@@ -127,9 +121,7 @@ static void nxsig_timeout(wdparm_t arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -252,8 +244,8 @@ int nxsig_clockwait(int clockid, int flags,
|
|||||||
FAR const struct timespec *rqtp,
|
FAR const struct timespec *rqtp,
|
||||||
FAR struct timespec *rmtp)
|
FAR struct timespec *rmtp)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb;
|
||||||
irqstate_t iflags;
|
irqstate_t iflags;
|
||||||
clock_t expect = 0;
|
clock_t expect = 0;
|
||||||
clock_t stop;
|
clock_t stop;
|
||||||
|
|
||||||
@@ -297,6 +289,7 @@ int nxsig_clockwait(int clockid, int flags,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
iflags = enter_critical_section();
|
iflags = enter_critical_section();
|
||||||
|
rtcb = this_task();
|
||||||
|
|
||||||
if (rqtp)
|
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,
|
int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
||||||
FAR const struct timespec *timeout)
|
FAR const struct timespec *timeout)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb;
|
||||||
sigset_t intersection;
|
sigset_t intersection;
|
||||||
FAR sigpendq_t *sigpend;
|
FAR sigpendq_t *sigpend;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
@@ -410,6 +403,7 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
|
rtcb = this_task();
|
||||||
|
|
||||||
/* Check if there is a pending signal corresponding to one of the
|
/* Check if there is a pending signal corresponding to one of the
|
||||||
* signals in the pending signal set argument.
|
* signals in the pending signal set argument.
|
||||||
|
|||||||
Reference in New Issue
Block a user