Re: l4_thread_ex_regs and suspending thread
"Valery V. Sedletski" <[email protected]>
| Newsgroups | gmane.comp.micro-kernel.l4.devel |
|---|---|
| Message-ID | <[email protected]> |
Adam Lackorzynski wrote: > Hi, > ... > but strange that it got a pagefault in case ~0 or L4_INVALID_ID is > specified, but does not change the registers or/and pager/preempter if I > specify 0 for eip/esp or l4_threadid_t initialized with zeros instead of > L4_INVALID_ID > I'm looking at > https://svn.tudos.org/repos/tudos/trunk/kernel/fiasco/src/kern/thread.cpp, > Thread::initialize, starting at line 850. There, sp and ip are only > changed when they're not ~0. Pager and preempter are only set if they're > valid (the lookup function is used to derive the pointer, which is 0 for > the invalid_id). Are we looking at the same code? > Yes, I see that in my Fiasco sources. And also I see that it changes pager/preempter only if they are not zero. (probably, it is converted from l4_threadid_t earlier). ip/sp are checked against ~0. And it seems that you're right. -- I changed something in the code, and now it doesn't cause the unhandled pagefault, so, probably, it was my proble,. It seems to suspend/resume without problems now, though I didn't saved/restored thread state yet (as you said later on this text) >>>> So, is it possible anyhow to suspend/resume the running thread from another >>>> thread? I know, that the thread can be suspended if entering unconditional >>>> l4_ipc_wait(), but this is from the inside that thread. How could it be done >>>> from an outside thread? >>> One way is to set the thread on such a loop via ex_regs (and paying >>> attention to the register contents which basically means there's some >>> assembly code involved). Another way is to do >>> ex_regs(id, ~0, ~0, L4_THREAD_EX_REGS_RAISE_EXCEPTION) which will >>> trigger an artificial exception in the thread and have it send an >>> exception IPC to its pager. The pager should then just not reply to have >>> the thread suspended, and then reply when you want to have the thread go >>> on later. What makes this a bit tricky is when L4 IPC is involves which >>> you will cancel with ex_regs, or not, if you use the >>> L4_THREAD_EX_REGS_NO_CANCEL flag. >>> >> I tried the 1st way -- set eip to the address of IPC wait loop, so it does >> suspend here, but resume doesn't work. -- You said that I'll need to set >> some registers via assember, but I wonder which ones -- the changed one is >> eip only. esp and eflags are only read, but didn't changed, others seems to >> be not altered with ex_regs... > What I meant is that the code must not change the thread's registers, or > it needs to ensure that the original values are restored when resuming > the thread. So when forcefully engaging the thread into an IPC, > registers might be changed when returning from that IPC, for example, > because it was cancelled. Thus the code which does the suspend should > save all CPU registers and just restore all of them when doing the > resume. That operation will take some assembly efforts. > With L4_THREAD_EX_REGS_RAISE_EXCEPTION this effort is taken by the > kernel and the pager just needs to memcpy the state away but requires > interaction with said pager so it depends on the setup what it easier to > do. > > Ah, so something can be changed when cancelling the IPC -- then I'll need to save/restore the thread state manually (or use the 2nd method with L4_THREAD_EX_REGS_RAISE_EXCEPTION). Thank you very much for clarification! > Adam