On Mon, 26 Sep 2005 15:15:52 +0200 Udo A. Steinberg (UAS) wrote:
UAS> On Mon, 26 Sep 2005 14:32:32 +0200 Rene Wittmann (RW) wrote: UAS> UAS> RW> So a call to l4_thread_ex_regs is sufficient and I would cancel the UAS> RW> next_period-IPC UAS> RW> with: l4_thread_ex_regs(main_thread_id, 0xFFFFFFFF, 0xFFFFFFFF, &id1, UAS> RW> &id2, &w1, &w2, &w3)?? UAS> RW> (l4_thread_id id1=id2=L4_INVALID_ID, l4_umword_t w1,w2,w3). UAS> RW> UAS> RW> If it's that simple, it's fine! UAS> UAS> Right. Except that in the current Fiasco implementation an IPC will be UAS> cancelled only if you explicitly set EIP to something other than UAS> 0xffffffff.
Looks like we cannot change this restriction without breaking legacy L4 software. The original L4 behavior has always been:
read old EIP if (new_EIP != 0xffffffff) { set new_EIP cancel IPC }
Therefore, such a change would break existing software that sets EIP to 0xffffffff in order to only read the old EIP and expects IPC to continue.
UAS> This seems like an unneeded restriction to me and I'm currently discussing UAS> with our group if this restriction can be removed. I'll send you a patch UAS> and commit the change to CVS in that case. Meanwhile you can mimic the UAS> desired behavior by setting the EIP of ex_regs to the instruction UAS> following the int $0x30 of the l4_next_period call, which is of course UAS> quite suboptimal.
It also occurred to me that the ex_regs modification discussed above does not really prevent the race condition:
main thread: preempter thread:
deadline miss detected <--------- l4_ex_regs (abort IPC) l4_next_period();
The preempter can't tell whether the main thread is already blocking in its l4_next_period call. If the ex_regs happened too early (i.e., as shown above) it wouldn't have any effect.
So how about the following:
main thread: preempter thread:
going_to_wait_for_next_period = 1; if (going_to_wait_for_next_period) l4_next_period(); l4_ex_regs (main_thread, label); label: else going_to_wait_for_next_period = 0; main thread is obviously elsewhere do stuff for new period
The main thread flags via a shared variable to the preempter that it plans to go to sleep via next_period. If the preempter sees upon a deadline miss that the main thread is about to go to sleep, it l4_ex_regs'es it to a new EIP, namely the instruction following the l4_next_period call: if the main thread is already blocked in the IPC, then ex_regs will abort the IPC and set the new EIP to "label:". If not, new EIP will be set to "label:" as well and the whole block of code handling the wait until the next period will simply be skipped (make sure to keep your stack in shape).
-Udo.