L 5.2 Delivery part of k_ipc

(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