Receive side state machine This state machine is targeted towards packet based systems such as VIA. That is to say that it assumes that only complete packets are handed to the state machine. Some alterations (likely in the form of additional states) are required in order to support a the processing of partial packets received by stream based model like TCP. Tasks for this state machine: - recv control and data packets - potentially provide buffers to associated send CAR - track buffers provided by associated send CAR - notify associated send CAR of any progress made - provide buffer availability information for flow control This version of the state machine only handles receiving data into a user provided buffer. It needs to be expanded to include the forwarding cases. CP = control packet DP = data packet(s) State [Await CP],[label="Await Incoming\nControl Packet"] Event [Pkt] Invoke_Action[Determine CP Type],[label="got ctrl pkt"] Action [Determine CP Type] Get_Next_Packet_And_Process_Ring_Buffer() switch (packet type) case flow Invoke_Action[Proc Flow CP] case rndv-rts Invoke_Action[Proc Rndv-RTS CP] case rndv-cts Invoke_Action[Proc Rndv-CTS CP] case short Invoke_Action[Proc Short CP] case eager Invoke_Action[Proc Eager CP] case rndv-data Invoke_Action[Proc Rndv-Data CP] Action [Proc Flow CP] // TODO: We need to figure out what needs to happen when we receive an // explicit flow control packet. For that matter, we need to figure out // how to deal with flow control in general... Change_State([Await CP]) Action [Proc Rndv-RTS CP] Change_State([Await CP]) Action [Proc Rndv-CTS CP] Change_State([Await CP]) Action [Proc Short CP] Change_State([Await CP]) Action [Proc Eager CP] Invoke_Action([Check For Posted Request]) Action [Check For Posted Request] recv_incoming_foa(..., &found) if (found) Change_State([Recv Posted Data]) else Invoke_Action([Proc Unexp Eager CP Data]) Action [Proc Unexp Eager CP Data], [label="Process Unexpected\nEager CP Data"] decide whether to keep the data in the packets or make a temporary copy // this decision might be affected by the availability of buffers to // serve as replacements if we were to keep the ones we receive data in. if copy allocate temporary buffer big enough to hold all message data copy data from first packet return packet ??? // NEED AN INTERFACE FUNCTION HERE else keep handle to packet with car maybe allocate replacement buffers record in car how we decided to handle data (copy or keep in packets) if there are data pkts available locally Invoke_Action([Proc Unexp DP]) else Change_State([Await Unexp DP]) State [Await Unexp DP] Event [Pkt] Invoke_Action([Proc Unexp DP]) Action [Proc Unexp DP], [label="Process Unexpected\nData Packet(s)"] while there are data pkts available locally Get_Next_Packet_And_Process_Ring_Buffer() if we are copying data make copy return packet // NEED OUR INTERFACE AGAIN else keep handle to packet with car maybe allocate replacement buffers if all data pkts have been received if there are more packets // the first will be a ctrl pkt Invoke_Action([Determine CP Type],[label="more queued CPs"]) // also grabs pkt else Change_State([Await CP]) else Change_State([Await Unexp DP],[label="empty incoming queue"]) Action [Proc Rndv-Data CP] Change_State([Recv Posted Data]) State [Recv Posted Data],[shape=polygon,sides=5] Event [finished] Change_State([Await CP]) Function Get_Next_Packet_And_Process_Ring_Buffer() get reference to packet so we can move it around if we need some more buffers in the ring attempt to acquire buffers if we got buffers add to receive buffer ring for VC post flow control update to be sent return pointer to packet