(Revision 0 - 10 October 2000)
Overview: does send part of fast ipc message delivery - it's the "magic" of L4 ipc
On entry: sdesc/rdesc/timeout/dthrd/wfor/vsend/stcb/dtcb/s0-s7/v0,v1 are set up - see Table 5.1 p. 48.
Called from: ipc prologue (which is called from geh)
ipc_long for fast part of ipc
pending_restart when sender becomes unblocked
This subset of the ipc code handles the send part for calls (rpc) and reply and wait (typical server operation) except long ipc and cases where message can't be delivered now (see prologue).
Basic idea of the "magic" of L4 ipc:
When there's an ipc involving 2 parties - if there's a receiver waiting:
1. never leave the kernel (until user-level receiver code is
invoked)
do the send
processing
change to
receiving thread's context and do the kernel part of the receiving processing
2. for servers with someone waiting, set up the sender to
receive later before transferring control to the receiver
| 23 | no receive part - goto code optimized for sends |
| 24,25 | set receiver BUSY, i.e., set him READY |
| 26,27 | if it's a call - goto 40 |
| 28,29 | if it's a reply and wait (open wait) but no-one is in
sender's receive Q, i.e., no-one is requesting anything of this sending
server , goto 40 - the code here and in 30-35 has to do with who we are
expecting a reply from if there isn't anyone - we won't need to save resume state for this server (see point 2 above) |
| 30-35 | if it's a reply and wait AND someone is in server's request
Q, set stack up for this thread to resume after context has switched to
receiver of this reply, i.e., set up a stack context for this thread to
resume as receiver after the process it's replying to has done his receive
- this server will want to respond to next request The data to save includes: code to run (sender_restart_receiving) this process's receive descriptor who this process will be waiting for (anyone in this case) timeout (irrelevant in this case since someone already has a request for this server - his 'send Q' is not empty |
| 36-39,50 | insert thread in READY (BUSY) scheduling list, mark its tcb as READY and goto 50 to end this thread's current processing |
| 40-46 | get here if it's a call (rpc) or a reply and wait with
no-one requesting anything of this server (no-one is requesting anything
of this server or sending anything to it)- so by definition, partner is
not ready to send (couldn't possibly be for rpc (since it hasn't got first
part of rpc yet) and server's 'send Q' is empty this means this thread's receive can time out - so need to do timeout processing if timeout = infinity, goto 47 else if timeout > 0 , add thread to wakeup Q so it can become unblocked after timeout if there's no receive |
| 47-49 | get here if infinite timeout or finite timeout and thread
put in wakeup Q need to save stuff in tcb because caller won't resume right now - save info in caller's tcb |
| 50 | store WAIT (infinite timeout) or WAIT + WAKEUP (finite timeout) as appropriate in caller's tcb |
| 51,52 | switch to receiver thread and then return to user level code that receives and processes calling sender's message |