argon-rtos icon indicating copy to clipboard operation
argon-rtos copied to clipboard

Thread<->IRQ synchronization with semaphore breaks timing in tickless mode

Open diggit opened this issue 7 years ago • 6 comments
trafficstars

Hi, I noticed a problem with thread waking from sleep in tickless mode. When there is thread synced (infinite timeout) by semaphore from ISR, whole system timing breaks. All sleeps in other threads are much shorter.

~~Note: Now I am syncing using simple suspend and resume principle which works.~~ Not, it does not, same problem.

diggit avatar Nov 03 '18 14:11 diggit

Hi @diggit, sorry for the delay in replying, and thanks for the bug report. Can you provide more information about what you are seeing, I don't totally understand the issue. Specifically, what do you mean by "system timing breaks" and "all sleeps in other threads are much shorter"? Do you have an example? Thanks!

flit avatar Dec 12 '18 18:12 flit

Hi, it's been a while since found this problem. By "system timing breaks" and "all sleeps in other threads are much shorter" I meant, that 100ms sleeps did not take 100ms anymore, but they were shorter (eg simple LED blinking thread looped much faster). Even load monitoring started to return nonsense.

My case was one thread loop of: waiting for semaphore and then drawing on display FB. There was IRQ handler swapping FBs and incrementing semaphore when there was FB ready to be filled (drawn into). This caused LED blinking thread to loop much faster and breaking other timing dependent things.

diggit avatar Dec 13 '18 09:12 diggit

As far as I understood correctly then this rtos soft real time and decrease or increase the time when running can be normal. It is worth understanding that soft real-time rtos cannot guarantee accurate time intervals. Need more debugging information or code that is tied to the time that would understand what is bug and what is not correctly written.

ghost avatar Dec 24 '18 17:12 ghost

ok, back to this issue

Lets have one thread blinking with LED:

void blink_thread_fcn(void *arg)
{
	while(1)
	{
		gpio_set(PB13);
		Ar::Thread::sleep(10);
		gpio_clr(PB13);
		Ar::Thread::sleep(40);
	}
}

Timing, when there is no other interrupt source. 2019-10-05_12-47_Ar_timing_simple

Now, let's add some other interrupt source. Eg, timer which periodically fires interrupt and wakes thread that flips output.

void irq_trig_blink_thread_fcn(void *args) {
	static bool ledOn = false;

	while(1) {
		if(ledOn) {
			gpio_clr(PB14);
		}
		else {
			gpio_set(PB14);
		}
		ledOn = !ledOn;
		Ar::Thread::getCurrent()->suspend();
	}
}

extern "C" void TIM7_IRQHandler(void) {
	TIM7->SR = ~TIM_SR_UIF;
	irq_trig_blink_thread.resume();
}

diggit avatar Oct 05 '19 11:10 diggit

This part is biased by my WIP patches to #11, skip to next comment, sorry!

Out of nowhere, both sleeps got extended by another kSchedulerQuanta_ms (10ms) and notice those glitches. Like first blinking thread was called and 10ms sleep for on time was completely ignored. 2019-10-05_12-57_Ar_timing_interrupts

Here with 30Hz interrupt source 2019-10-05_13-14_Ar_timing_interrupts_33Hz

When irq_trig_blink_thread.resume(); is called, scheduler is executed afterwards. I am suspecting, that schedulers re-configures systick. Scheduler itself was not called at its' tick period

Here are highlighted time segments. Green (4) are segments 10ms long which corresponds to 4 * kSchedulerQuanta_ms (4 * 10ms) . Red are segments which got interrupted by second timer and scheduler reconfigured and reset systick. Because Argon measures time in ticks of kSchedulerQuanta_ms, shorter sleep times ceil to 0 passed ticks and Argon thinks, that no delay passed yet. 2019-10-05_13-28_Ar_timing_interrupts_33Hz_detail_hilighted

Problem seems to be pretty obvious. We could ignore sleeping threads and not reconfigure systick when the scheduler is not triggered from systick. Could this cause any problems?

diggit avatar Oct 05 '19 12:10 diggit

With 30Hz second timer interrupt:

2019-10-05_14-47_ar_timing_interrupts_vanilla

Thread priority has no noticeable effect.

diggit avatar Oct 05 '19 12:10 diggit