CTimer delays busy-spin the processor
Blackaddr opened this issue · comments
When using the CTimer delay functions, the processor sits in a busy loop tying up the processor core.
E.g.
Line 611 in 3b6c4a1
It would be nice if we had the option to Yield() instead. Busy-waiting improves the precising timing of the delay (I assume this was the intent), but is not great for multi-threaded applications. I found this while porting other baremetal libraries to Circle that expect a delay() call to be yielding.
void CTimer::SimpleusDelay (unsigned nMicroSeconds, bool yield = false); // same optional param for all delays needed
void CTimer::SimpleusDelay (unsigned nMicroSeconds, bool yield )
{
if (nMicroSeconds > 0)
{
unsigned nTicks = nMicroSeconds * (CLOCKHZ / 1000000) + 1;
#ifndef USE_PHYSICAL_COUNTER
PeripheralEntry ();
unsigned nStartTicks = read32 (ARM_SYSTIMER_CLO);
while (read32 (ARM_SYSTIMER_CLO) - nStartTicks < nTicks)
{
// do nothing,
if (yield && CScheduler::Get()) { CScheduler::Get()->Yield(); } // add optional yield
}
PeripheralExit ();
#else
unsigned nStartTicks = GetClockTicks ();
while (GetClockTicks () - nStartTicks < nTicks)
{
// do nothing
if (yield && CScheduler::Get()) { CScheduler::Get()->Yield(); } // add optional yield
}
#endif
}
}
The CScheduler::Sleep()
, CScheduler::MsSleep()
and CScheduler::usSleep()
methods put the current task to sleep for the given amount of time and let other tasks run. See this.
@rsta2 Great! I was not aware of these functions, thank you for bringing them to my attention and for your help.