On Wed, 21 Sep 2005 17:32:40 +0200 Rene Wittmann (RW) wrote:
RW> When I check for timeslice overruns with global variables (set by preempter RW> and read by rt thread) RW> everything seems fine. RW> Whereas when I check for deadline misses via global variables, it doesn't RW> work.
From the example code you posted it doesn't look like you made the variable that is shared between the two threads "volatile". Only when that variable is volatile will the compiler read it from memory every time. Otherwise it is free to cache the variable in a register and may not see the write from the other thread.
But that's not the real problem here.
RW> My "real" code looks like this: RW> RW> extern char deadline_miss; RW> l4_kernel_clock_t left; RW> RW> set_up_preempter_etc(); RW> do_reservation_and_set_up(); RW> deadline_miss = 0; RW> while(1){ RW> if (deadline_miss == 0){ RW> l4_rt_next_period(); RW> }
The above part in pseudo-code:
1) read deadline miss variable 2) compare deadline miss variable against 0 3) if equal, call next_period and go to sleep until next period begins
If the deadline miss occurs somewhere after 2) and before 3) is done, then you have the situation you describe:
RW> /* if I check here for deadline_miss != 0 it's true!! */ RW> dealine_miss = 0;
RW> Summary: when I check for deadline misses right before next_period-call, RW> I have none. So I call next_period. If I check _again_ after the call, RW> I have one! RW> RW> How could I prevent this? Waiting for the next period is not pretended as RW> Udo stated correctly!
What you want is an atomic way of checking for a deadline miss and acting upon the result of that check. But such functionality does not exist. There is currently no way you can prevent the above scenario where the deadline miss occurs after the check but before (or while) you go to sleep via next_period.
So what you have to do instead is: upon detecting a deadline miss, the preempter thread should ex_regs the thread with the deadline miss (thereby cancelling the l4_rt_next_period/IPC operation). When you return from next_period, you can check if you've been ex_regs'd out of it or whether the call returned regularly at the beginning of your new period, e.g, by checking the global variable that you already have.
RW> Maybe my kernel settings are also of note here: APIC with one shot mode
That's a good choice.
-Udo.