From a4bdf6cbff7b5fce39aef18765396cc0aab26bf0 Mon Sep 17 00:00:00 2001 From: batt Date: Fri, 29 Aug 2008 15:21:53 +0000 Subject: [PATCH] Restore preempt_forbid_cnt as private; supply an accessor macro. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1751 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/kern/preempt.c | 9 +++++---- bertos/kern/proc.h | 31 ++++++++++++++++++++++--------- bertos/kern/signal.c | 5 +---- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/bertos/kern/preempt.c b/bertos/kern/preempt.c index c3d212d4..2c44373b 100644 --- a/bertos/kern/preempt.c +++ b/bertos/kern/preempt.c @@ -65,7 +65,8 @@ CONFIG_DEPEND(CONFIG_KERN_PREEMPT, CONFIG_KERN_SCHED && CONFIG_TIMER_EVENTS & MOD_DEFINE(preempt) -int preempt_forbid_cnt; +/** Global preemption disabling nesting counter */ +int _preempt_forbid_cnt; static Timer preempt_timer; @@ -74,7 +75,7 @@ void proc_schedule(void) { IRQ_DISABLE; - ASSERT(preempt_forbid_cnt == 0); + ASSERT(proc_allowed()); LIST_ASSERT_VALID(&ProcReadyList); CurrentProcess = (struct Process *)list_remHead(&ProcReadyList); ASSERT2(CurrentProcess, "no idle proc?"); @@ -86,7 +87,7 @@ void proc_schedule(void) void proc_preempt(UNUSED_ARG(void *, param)) { - if (!preempt_forbid_cnt) + if (proc_allowed()) { IRQ_DISABLE; @@ -122,7 +123,7 @@ void proc_switch(void) /* Sleeping with IRQs disabled or preemption forbidden is illegal */ IRQ_ASSERT_ENABLED(); - ASSERT(preempt_forbid_cnt == 0); + ASSERT(proc_allowed()); // Will invoke proc_switch() in interrupt context kill(0, SIGUSR1); diff --git a/bertos/kern/proc.h b/bertos/kern/proc.h index f8de758f..1a358346 100644 --- a/bertos/kern/proc.h +++ b/bertos/kern/proc.h @@ -85,9 +85,6 @@ const char *proc_currentName(void); } #endif -/** Global preemption disable nesting counter. */ -extern int preempt_forbid_cnt; - /** * Disable preemptive task switching. * @@ -108,11 +105,12 @@ extern int preempt_forbid_cnt; INLINE void proc_forbid(void) { #if CONFIG_KERN_PREEMPT + extern int _preempt_forbid_cnt; // No need to protect against interrupts here. - ++preempt_forbid_cnt; + ++_preempt_forbid_cnt; /* - * Make sure preempt_forbid_cnt is flushed to memory so the + * Make sure _preempt_forbid_cnt is flushed to memory so the * preemption softirq will see the correct value from now on. */ MEMORY_BARRIER; @@ -133,13 +131,13 @@ INLINE void proc_permit(void) * flushed to memory before task switching is re-enabled. */ MEMORY_BARRIER; - + extern int _preempt_forbid_cnt; /* No need to protect against interrupts here. */ - --preempt_forbid_cnt; - ASSERT(preempt_forbid_cnt >= 0); + --_preempt_forbid_cnt; + ASSERT(_preempt_forbid_cnt >= 0); /* - * This ensures preempt_forbid_cnt is flushed to memory immediately + * This ensures _preempt_forbid_cnt is flushed to memory immediately * so the preemption interrupt sees the correct value. */ MEMORY_BARRIER; @@ -147,6 +145,21 @@ INLINE void proc_permit(void) #endif } +/** + * \return true if preemptive task switching is allowed. + * \note This accessor is needed because _preempt_forbid_cnt + * must be absoultely private. + */ +INLINE bool proc_allowed(void) +{ + #if CONFIG_KERN_PREEMPT + extern int _preempt_forbid_cnt; + return (_preempt_forbid_cnt == 0); + #else + return true; + #endif +} + /** * Execute a block of \a CODE atomically with respect to task scheduling. */ diff --git a/bertos/kern/signal.c b/bertos/kern/signal.c index 948d68f1..9785958d 100644 --- a/bertos/kern/signal.c +++ b/bertos/kern/signal.c @@ -139,10 +139,7 @@ sigmask_t sig_wait(sigmask_t sigs) /* Sleeping with IRQs disabled or preemption forbidden is illegal */ IRQ_ASSERT_ENABLED(); - - #if CONFIG_KERN_PREEMPT - ASSERT(preempt_forbid_cnt == 0); - #endif + ASSERT(proc_allowed()); /* * This is subtle: there's a race condition where a concurrent -- 2.25.1