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