X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fdrv%2Ftimer.c;h=e8508e047f18d3f767632eaf3809cd3bf5786ec0;hb=1c11ac0ab0636d07db3899b02c5d89e2d0b020bc;hp=60494413276918af234d3a802dbb8177c6fd413d;hpb=05248535066bcff365b2aa6c9c3b7fa0e5a4f475;p=bertos.git diff --git a/bertos/drv/timer.c b/bertos/drv/timer.c index 60494413..e8508e04 100644 --- a/bertos/drv/timer.c +++ b/bertos/drv/timer.c @@ -52,6 +52,8 @@ #include #include // cpu_relax() +#include // proc_decQuantun() + /* * Include platform-specific binding code if we're hosted. * Try the CPU specific one for bare-metal environments. @@ -240,30 +242,34 @@ void synctimer_poll(List *queue) /** * Wait for the specified amount of timer ticks. + * + * \note Sleeping while preemption is disabled fallbacks to a busy wait sleep. */ void timer_delayTicks(ticks_t delay) { /* We shouldn't sleep with interrupts disabled */ IRQ_ASSERT_ENABLED(); -#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS +#if CONFIG_KERN_SIGNALS Timer t; - ASSERT(!sig_check(SIG_SINGLE)); - timer_setSignal(&t, proc_current(), SIG_SINGLE); - timer_setDelay(&t, delay); - timer_add(&t); - sig_wait(SIG_SINGLE); - -#else /* !CONFIG_KERN_SIGNALS */ - - ticks_t start = timer_clock(); - - /* Busy wait */ - while (timer_clock() - start < delay) - cpu_relax(); - + if (proc_preemptAllowed()) + { + ASSERT(!sig_check(SIG_SINGLE)); + timer_setSignal(&t, proc_current(), SIG_SINGLE); + timer_setDelay(&t, delay); + timer_add(&t); + sig_wait(SIG_SINGLE); + } + else #endif /* !CONFIG_KERN_SIGNALS */ + { + ticks_t start = timer_clock(); + + /* Busy wait */ + while (timer_clock() - start < delay) + cpu_relax(); + } } @@ -315,7 +321,6 @@ void timer_delayHp(hptime_t delay) } #endif /* CONFIG_TIMER_UDELAY */ - /** * Timer interrupt handler. Find soft timers expired and * trigger corresponding events. @@ -340,16 +345,19 @@ DEFINE_TIMER_ISR TIMER_STROBE_ON; - /* Perform hw IRQ handling */ - timer_hw_irq(); - /* Update the master ms counter */ ++_clock; + /* Update the current task's quantum (if enabled). */ + proc_decQuantum(); + #if CONFIG_TIMER_EVENTS timer_poll(&timers_queue); #endif + /* Perform hw IRQ handling */ + timer_hw_irq(); + TIMER_STROBE_OFF; }