A late addition to an old question.
RW> 2.) Consider we have a deadline miss. And we say RW> l4_rt_next_period(): would it wait for the beginning of the next RW> (which means: RW> period 1: deadline miss RW> period 2: call next period (because we think we're RW> still in period 1)+ wait to end of period RW> period 3: normal work) RW> Or do I have to care that we do not call RW> l4_rt_next_period() in case of a deadline miss?
If your thread misses its deadline right before it wanted to call l4_rt_next_period, then l4_rt_next_period blocks the thread until the end of the new period started due to the deadline miss. Since this is likely not what the thread intended to do, it's the preempter's job to handle that situation, e.g. by ex_regs'ing the thread out of it's l4_rt_next_period call.
You're right, it is not intended to wait for the next period. So I introduced some additional checking.
Unfortunatelly I can not recognize deadline misses early enough. This is my configuration: My preempter thread runs at a priority of 255, my rt thread is a periodic thread with period length 40ms. The latter has three timeslices: 1. 10ms, prio=60 2. 18ms, prio=50 3. 10ms, prio=60
All other threads in the system should have a lower priority by default (dm_phys, log, names, simple_ts). I have no logging output or else inside my rt execution.
When I check for timeslice overruns with global variables (set by preempter and read by rt thread) everything seems fine. Whereas when I check for deadline misses via global variables, it doesn't work.
My "real" code looks like this:
extern char deadline_miss; l4_kernel_clock_t left;
set_up_preempter_etc(); do_reservation_and_set_up(); deadline_miss = 0; while(1){ if (deadline_miss == 0){ l4_rt_next_period(); } /* if I check here for deadline_miss != 0 it's true!! */ dealine_miss = 0; work1(); l4_rt_next_reservation(1,&left); work2(); l4_rt_next_reservation(2,&left); work3(); l4_rt_next_reservation(3,&left); }
THE PREEMPTER: extern char deadline_miss; extern char overrun; l4_rt_preemption_t _dw; l4_msgdope_t _result; while(1){ if (l4_ipc_receive(l4_preemption_id(main_thread_id), L4_IPC_SHORT_MSG, &_dw.lh.low, &dw.lh.high, L4_IPC_NEVER, &result) == 0){ if (_dw.p.type == L4_RT_PREEMPT_TIMESLICE){ overrun=1; /* in reality distinguished by id */ } else if (_dw.p.type == L4_RT_PREEMPT_DEADLINE){ deadline_miss = 1; } else{ exit(-1); } }
Summary: when I check for deadline misses right before next_period-call, I have none. So I call next_period. If I check _again_ after the call, I have one!
How could I prevent this? Waiting for the next period is not pretended as Udo stated correctly! Maybe global variables aren't so suitable for this task, but what should I do different? "Ex_regs'ing" would reduce the critical time, I guess, but not totally prevent it?
Maybe my kernel settings are also of note here: APIC with one shot mode
Regards, Rene