Blame doc/notes/agent/send-sm.txt

Packit 0848f5
% Prototype Method Send State Machine
Packit 0848f5
% 
Packit 0848f5
% This state machine is targeted towards packet based systems such as VIA.
Packit 0848f5
% Some simplifications may be possible for stream based model like TCP.
Packit 0848f5
% 
Packit 0848f5
% Tasks for this state machine:
Packit 0848f5
% 
Packit 0848f5
% - send message at the head of the queue
Packit 0848f5
% 
Packit 0848f5
%   - message data source exists in two forms:
Packit 0848f5
% 
Packit 0848f5
%     - provided by user - potentially needing to be packed but guaranteed to be
Packit 0848f5
%       available when the CAR is enqueued
Packit 0848f5
% 
Packit 0848f5
%     - provided by associated recv CAR - may not be (completely) available
Packit 0848f5
%       until later (i.e., send could stall)
Packit 0848f5
% 
Packit 0848f5
% - track buffers provided by associated recv CAR
Packit 0848f5
% 
Packit 0848f5
% - provide buffers to associated recv CAR
Packit 0848f5
% 
Packit 0848f5
% - enforce flow control
Packit 0848f5
% 
Packit 0848f5
% 
Packit 0848f5
% This version of the state machine only handles sending from a user provided
Packit 0848f5
% buffer.  It needs to be expanded to include the forwarding cases.
Packit 0848f5
Packit 0848f5
\begin{verbatim}
Packit 0848f5
State [Awaiting CAR],[label="Awaiting\nCAR"]
Packit 0848f5
    Event [CAR Available]
Packit 0848f5
        Invoke_Action([Decide Msg Type],
Packit 0848f5
                      [label="got CAR"])
Packit 0848f5
Packit 0848f5
Action [Decide Msg Type]
Packit 0848f5
    // Note: An otherwise eager message may get converted to a
Packit 0848f5
    // rndv-RTS message if too many outstanding eager messages have already
Packit 0848f5
    // been sent to the receiving process.
Packit 0848f5
Packit 0848f5
    if the type is eager
Packit 0848f5
        // TODO: we may want to convert it to rndv (rts and eventually data)
Packit 0848f5
Packit 0848f5
    Invoke_Action([Check Buffers for Ctrl])
Packit 0848f5
Packit 0848f5
Action [Check Buffers for Ctrl],
Packit 0848f5
       [label="Check Buffers\nfor Ctrl Pkt"]
Packit 0848f5
    // get buffers if we don't already have some
Packit 0848f5
    // always need a buffer for control information
Packit 0848f5
    if buffers are not available
Packit 0848f5
        Change_State([Awaiting Buffers for Ctrl],
Packit 0848f5
                     [label="no bufs"])
Packit 0848f5
    else
Packit 0848f5
        Invoke_Action([Check Flow for Ctrl],
Packit 0848f5
	              [label="bufs ok"])
Packit 0848f5
Packit 0848f5
State [Awaiting Buffers for Ctrl],
Packit 0848f5
      [label="Awaiting Buffers\nfor Ctrl Pkt"]
Packit 0848f5
    Event [Buffers Available]
Packit 0848f5
        Invoke_Action([Check Flow for Ctrl],
Packit 0848f5
                      [label="bufs ok"])
Packit 0848f5
Packit 0848f5
Action [Check Flow for Ctrl],
Packit 0848f5
       [label="Check Flow Control\nfor Ctrl Pkt"]
Packit 0848f5
    if flow restricted // all tensed up
Packit 0848f5
        Change_State([Awaiting Flow for Ctrl],
Packit 0848f5
                     [label="flow\nrestricted"])
Packit 0848f5
    else
Packit 0848f5
        Invoke_Action([Post Send Ctrl],
Packit 0848f5
                      [label="flow ok"])
Packit 0848f5
Packit 0848f5
State [Awaiting Flow for Ctrl],
Packit 0848f5
      [label="Awaiting Flow\nfor Ctrl Pkt"]
Packit 0848f5
    Event [Flow Enabled]
Packit 0848f5
        Invoke_Action([Post Send Ctrl],
Packit 0848f5
                      [label="flow ok"])
Packit 0848f5
Packit 0848f5
Action [Post Send Ctrl],
Packit 0848f5
       [label="Post Send\nfor Ctrl Pkt"]
Packit 0848f5
    type = OD.type
Packit 0848f5
    // pack meta-data into the packet buffer
Packit 0848f5
    // meta-data may include the envelope information (context, src rank,
Packit 0848f5
    // and tag) as well as the ready send bit
Packit 0848f5
    put type in packet buffer
Packit 0848f5
    if type is short or eager
Packit 0848f5
        put the envelope info and rsend bit in the packet buffer
Packit 0848f5
    else if type is rndv-rts message
Packit 0848f5
        put the envelope and LIBA(OD) into the packet buffer
Packit 0848f5
	OD.type = rndv-data
Packit 0848f5
    else if type is rndv-cts
Packit 0848f5
        put the two LIBAs in the packet buffer
Packit 0848f5
    else if type is rndv-data
Packit 0848f5
        put the LIBA in the packet buffer
Packit 0848f5
    else if type is flow control
Packit 0848f5
        // TODO
Packit 0848f5
    
Packit 0848f5
    // pack data from DD into packet buffer (as much as will fit) if we have
Packit 0848f5
    // any data to send
Packit 0848f5
    if type is short, eager, or rndv-data and a DD exists
Packit 0848f5
        if direct access flag is set
Packit 0848f5
            point network send descriptor at the user data (which is pinned)
Packit 0848f5
        else
Packit 0848f5
            pack data into the packet buffer (from the data descriptor)
Packit 0848f5
Packit 0848f5
    post the send to the network device
Packit 0848f5
    if there are no data packets to send (i.e., short)
Packit 0848f5
        Invoke_Action([Signal CAR Completion],
Packit 0848f5
	              [label="msg complete"])
Packit 0848f5
    else if direct access flag is set
Packit 0848f5
        Invoke_Action([Check Flow for Data],
Packit 0848f5
                      [label="more data,\ndirect send"])
Packit 0848f5
    else
Packit 0848f5
        Invoke_Action([Check Buffers for Data],
Packit 0848f5
                      [label="more data,\nbuffered send"])
Packit 0848f5
    
Packit 0848f5
Action [Check Buffers for Data],
Packit 0848f5
       [label="Check Buffers\nfor Data Pkts"]
Packit 0848f5
    // try to get buffers if we need them
Packit 0848f5
    if buffers aren't available
Packit 0848f5
        Change_State([Awaiting Buffers for Data],
Packit 0848f5
		     [label="no bufs"])
Packit 0848f5
    else
Packit 0848f5
        Invoke_Action([Check Flow for Data],
Packit 0848f5
		      [label="bufs ok"])
Packit 0848f5
Packit 0848f5
State [Awaiting Buffers for Data],
Packit 0848f5
      [label="Awaiting Buffers\nfor Data Pkts"]
Packit 0848f5
    Event [Buffers Available]
Packit 0848f5
        Invoke_Action([Check Flow for Data],
Packit 0848f5
                      [label="bufs ok"])
Packit 0848f5
Packit 0848f5
Action [Check Flow for Data],
Packit 0848f5
       [label="Check Flow Control\nfor Data Pkts"]
Packit 0848f5
    if flow restricted
Packit 0848f5
        Change_State([Awaiting Flow for Data],
Packit 0848f5
                     [label="flow\nrestricted"])
Packit 0848f5
    else
Packit 0848f5
        Invoke_Action([Post Send Data],
Packit 0848f5
		      [label="flow ok"])
Packit 0848f5
Packit 0848f5
State [Awaiting Flow for Data],
Packit 0848f5
      [label="Awaiting Flow Control\nfor Data Pkts"]
Packit 0848f5
    Event [Flow Enabled]
Packit 0848f5
        Invoke_Action([Post Send Data],
Packit 0848f5
                      [label="flow ok"])
Packit 0848f5
Packit 0848f5
// TODO: Add buffer packing into flow
Packit 0848f5
Packit 0848f5
Action [Post Send Data],
Packit 0848f5
       [label="Post Send\nfor Data Pkts"]
Packit 0848f5
    if direct access flag is set
Packit 0848f5
        point network send descriptor at the user data (which is pinned)
Packit 0848f5
    else
Packit 0848f5
        pack data into the packet buffer (from the data descriptor)
Packit 0848f5
    post the send to the network device
Packit 0848f5
    // Note: In the implementation, we may want to post multiple packets sends
Packit 0848f5
    // at one time, amortizing the cost of checking for buffers and checking
Packit 0848f5
    // flow control over a set of outgoing packets.  We are uncertain how
Packit 0848f5
    // packing multiple buffers then posting multiple sends will affect
Packit 0848f5
    // peformance, but clearly amortizing costs when sending straight out of
Packit 0848f5
    // the user buffer will be a win.
Packit 0848f5
Packit 0848f5
    if there are more data packets to send
Packit 0848f5
        if we are sending directly from the user buffer
Packit 0848f5
            Invoke_Action([Check Flow for Data],
Packit 0848f5
                          [label="more data,\ndirect send"])
Packit 0848f5
        else
Packit 0848f5
            Invoke_Action([Check Buffers for Data],
Packit 0848f5
                          [label="more data,\nbuffered send"])
Packit 0848f5
    else
Packit 0848f5
        Invoke_Action([Signal CAR Completion],
Packit 0848f5
	              [label="msg complete"])
Packit 0848f5
    
Packit 0848f5
Action [Signal CAR Completion], [label="Check/Signal\nCAR Completion"]
Packit 0848f5
    if we did not send all data directly from the user buffer
Packit 0848f5
        reset (local) completion flag
Packit 0848f5
        if we send some of the data directly from the user buffer
Packit 0848f5
            lock CAR.mutex
Packit 0848f5
	        decrement CAR outstanding activities counter
Packit 0848f5
		if outstanding activity counter reaches zero
Packit 0848f5
                    set completion flag
Packit 0848f5
            unlock CAR.mutex
Packit 0848f5
        else // all data sent using packet buffers
Packit 0848f5
            set completion flag
Packit 0848f5
        if completion flag is set
Packit 0848f5
	    decrement completion counter associated with CAR
Packit 0848f5
        
Packit 0848f5
    Invoke_Action([Check Ready CAR])
Packit 0848f5
Packit 0848f5
Action [Check Ready CAR],[label="Check for Ready\nSend CAR"]
Packit 0848f5
    if more CARs are on the send queue
Packit 0848f5
        Invoke_Action([Decide Msg Type],
Packit 0848f5
                      [label="ready CAR"])
Packit 0848f5
    else
Packit 0848f5
        Change_State([Awaiting CAR],
Packit 0848f5
                     [label="no more\nCARs"])
Packit 0848f5
   
Packit 0848f5
Packit 0848f5
\end{verbatim}