/*
 * Copyright (c) 1996 by Satish Chandra, Brad Richards, Mark D. Hill, 
 * James R. Larus, and David A. Wood.
 *
 * Teapot is distributed under the following conditions:
 * 
 *     You may make copies of Teapot for your own use and modify those copies.
 * 
 *     All copies of Teapot must retain our names and copyright notice.
 * 
 *     You may not sell Teapot or distributed Teapot in conjunction with a
 *     commercial product or service without the expressed written consent of
 *     the copyright holders.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * 
 */
#line 1 "nw.m"
Procedure NW_SendData(				Dest: 	NODE;
						MType: 	MSG;
						Addr: 	ID;
						Frm:	NODE;
						Data:	Value;
						info:	INFO);
Var
	Msg: Message;
Begin
	Alias Net : Network[Frm][Dest] Do
		Assert (Net.Count != ChanMax) "Network is full";
		Msg.MType := MType;
		Msg.Addr := Addr;
		Msg.Value := Data;
		Msg.RdBit := info.RdBit;
		Msg.WrBit := info.WrBit;
		Net.Messages[Net.Count] := Msg;
		Net.Ages[Net.Count] := 0;
		Net.Count := Net.Count + 1;
	End; -- alias net
End;

Procedure NW_Send(			Dest: 	NODE;
					MType: 	MSG;
					Addr: 	ID;
					Frm:	NODE);
Var
	Msg: Message;
Begin
	Alias Net : Network[Frm][Dest] Do
		Assert (Net.Count != ChanMax) "Network is full";
		Msg.MType := MType;
		Msg.Addr := Addr;
		Undefine Msg.Value;
		Net.Messages[Net.Count] := Msg;
		Net.Ages[Net.Count] := 0;
		Net.Count := Net.Count + 1;
	End; -- alias net
End;

Procedure NW_Send_w_Bits(		Dest: 	NODE;
					MType: 	MSG;
					Addr: 	ID;
					Frm:	NODE;
					info: 	INFO);
Var
	Msg: Message;
Begin
	Alias Net : Network[Frm][Dest] Do
		Assert (Net.Count != ChanMax) "Network is full";
		Msg.MType := MType;
		Msg.Addr := Addr;
		Msg.RdBit := info.RdBit;
		Msg.WrBit := info.WrBit;
		Undefine Msg.Value;
		Net.Messages[Net.Count] := Msg;
		Net.Ages[Net.Count] := 0;
		Net.Count := Net.Count + 1;
	End; -- alias net
End;

Procedure NW_RecvData(Addr: ID; msg : Message; Us: NODE);
Begin
	Nodes[Us].Dram[Addr].Data := msg.Value;
End;

Procedure NW_ConsumeMsg(Var Net: NetSlotType; M_Index: 0..ChanMax-1);
Begin
	Assert (M_Index < Net.Count) "Invalid Message Index";
	For i := M_Index To Net.Count - 2 Do
		Net.Messages[i] := Net.Messages[i+1];
		Net.Ages[i] := Net.Ages[i+1];
	Endfor;
	Undefine Net.Messages[Net.Count-1];
	Undefine Net.Ages[Net.Count-1];
	Net.Count := Net.Count - 1;
End;


-- Look through all of the messages pending on this channel to see if any
-- of them have been overlooked ReorderMax times.  Returns true if one of 
-- them has "expired" in this manner.

Function Msg_Too_Old(Src: NODE; Dst: NODE): boolean;
Var
	flag : boolean;
	
Begin
	flag := false;
	For j := 1 to Network[Src][Dst].Count Do
		If (Network[Src][Dst].Ages[j-1] >= ReorderMax)
		Then
			flag := true;
		Endif;
	Endfor;
	return flag;
End;



Function Find_Old_Msg(Src: NODE; Dst: NODE): 0..ChanMax;
Begin
	For j := 1 to Network[Src][Dst].Count Do
		If (Network[Src][Dst].Ages[j-1] >= ReorderMax)
		Then
			return j-1;
		Endif;
	Endfor;
	Assert (false) "Didn't find old message!";
End;



Procedure Age_Messages(Src: NODE; Dst: NODE);
Begin
	For j := 1 to Network[Src][Dst].Count Do
	    Network[Src][Dst].Ages[j-1] := Network[Src][Dst].Ages[j-1] + 1;
	Endfor;
End;



-- Actually fails if there are less than TWO open slots on each channel,
-- otherwise we can die when handling queued msgs.

Function Space_in_Network(Src: NODE): boolean;
Var
	flag : boolean;
Begin
	-- if the channel from src to any other node is full,
	-- say that the network is full
	flag := true;
	For j : NODE Do
		If (Network[Src][j].Count >= ChanMax-1)
		Then
			flag := false;
		Endif;
	Endfor;
	return flag;
	-- return (Network[Src][Dst].Count < ChanMax);
End;



Function Network_Empty(): boolean;
Var
	flag : boolean;
Begin
	flag := true;
	For i : NODE Do
	    For j : NODE Do
		If (Network[i][j].Count > 0) Then
			flag := false;
		Endif;
	    Endfor;
	Endfor;
	return flag;
End;
