{ Desc: Master (Global) include file for AMIRTR File: [22,310]AMIRTR.INC Author: Jim Bostwick Last Edit: 20-DEC-1989 23:23:17 History: 26-OCT-1989 - JMB - add proper debug code 9-OCT-1989 - JMB - major happy munging... 27-JAN-1989 - JMB - Rework Link array for simplicity. Note: A slight departure from past practice - this is something like a package file in that it includes top-level stuff (e.g., General.typ) and defines global data. The goal is to reduce the number of include files which must be opened by the compiler. Theoretically, this file may be turned into a true package (by pre-expanding all includes) as it nears completion. Including external definitions which aren't referenced does no harm, even in an overlay situation, because the compiler doesn't generate the .GLOBL reference until a call to the routine is actually built. } {$Nolist} {*USER* Global data for AMIRTR is organized around an array of 'link records', which contain all necessary information to manage a decnet link. The array is (obviously) fixed in size, which governs the maximum number of open links available to the program. Constant 'Max_Links' sets this size. .note This does not limit the number of possible nodes in the 'message net', but does potentially impact performance due to excessive link creation and destruction. In general, specify enough links for the expected number of 'active' connections - certainly enough to handle all concurrently active ones. At the same time, be aware of limits in decnet (NCP MAX LINKS parameter). Also, links take resources inside DECNET - comexec, pool, etc. .end note .hl 2 LUNS are assigned in a block, starting with Lo_Net_LUN and proceeding until one LUN per link plus one for the network mailbox (Max_Links + 1 LUNS) have been assigned. User program MUST stay away from these LUNS! This means either assigning them with 'high' numbers, or using 'low' numbers, and forcing Pascal Opens to use higher ones. Link 0 (Link[0]) is used with the net mailbox lun. Not all fields of Link 0 are used. However, the statistics record in particular shows activity on the mailbox. The link record also contains a couple of fields for convenience - notably the 'active' boolean, and node name. These duplicate information available elsewhere in the record, but eliminate the need to dig it out each time. .hl 2 EFNs Two global EFNs are defined. Net_EFN is the generic network activity EFN (also used for SRDA ast notification and other things). Aux_EFN is just a random flag which is used for 'throw-away' things - a scratch EFN if you will... } {*WIZARD* .hl 2 Statistics Link Statistics are kept for each link in the Link_Statistics_rec, and may be reported using router control messages. Link statistics are kept for two reasons. The important one is to enable the program to determine which link to drop if more are requested than are available. Note that this shouldn't happen too often; if it does, rebuild with more links available. The second reason is for debugging and system tuning. .hl 3 Last Activity The Last Activity timer shows roughly how long it has been since a link passed a message (either in- or outbound). This is a high-granularity timer (Activity_Units, Activity_Time; initial default =10sec.) to avoid overloading the program with timer service. Each time a link is used, the Last_Activity field is zeroed. A single, program-wide, timer increments the field for all active links each time it is serviced. Timer service occurs in the main loop, after all net and message traffic has been dealt with. Thus on a buisy system (or program), the timer will tend to 'slow down'. In any case, the (active) link with the largest value in Last_Activity is the 'least-recently-used' link. .note A better algorithm would account for volume of usage as well as time. For example, a link which sends a wad of messages at regular but relatively long intervals, will get blown away if a bunch of sporadic links come active at one time. Eventually, the low-volume guys will fade away, but we'd like the heavy hitter to hand around. One approach would be to give each new link a 'budget' at creation. The activity timer would decrement the budget, while any activity would increment it. By balancing the timer cost (decrement) against the use-reward (increment), we could keep those heavy hitters in there, while getting rid of the 'one-shot' links that much sooner. .end note .hl 3 Reads, Writes These real values contain the count of inbound and outbound network traffic. Retries (if ever defined) are NOT counted. These are reals only to allow large values - the increment is always 1.0. .hl 3 Connects This is an integer counter of the number of times this link has been opened since program startup. Big numbers here are generally bad - indicating either a weak link (dropping all the time) or too few links (forcing the program to kill off and re-incarnate constantly). &&&&& } {[a+,b+,l-,k+,r+] Pasmat } {$List} CONST Max_Links = 4; { maximum number of concurrently open net links } Lo_Net_LUN = 7; { will allocate LUNS 7 and up NS: } Mbx_LUN = Lo_Net_LUN; { a handy synonym } Net_EFN = f15; { make group global to be nice, global for easy debug } Aux_EFN = f16; { generic EFN } Activity_Units = seconds; { time units for activity timer } Activity_Count = 10; { e.g, 10 sec. activity timer } Activity_EFN = f14; { flag set when timer expires } Null_Task_String = CH6('0','0','0','0','0','0'); { Don't care parameter for some calls } TYPE { Define link control and status flags } Link_Flag_typ = (Link_Active, Link_Shutdown); { Define some pointer types } Connect_Block_Ptr = ^Net_Connect_Block; Request_Block_Ptr = ^Net_Request_Block; { Define Link Statistics Record } Link_Statistics_rec = RECORD; Last_Activity: integer; { time units since active } Reads,Writes: Real; { count of traffic in, out } Connects: Integer; { count of network opens } END; { Link_Statistics_rec } { Define master link database record } Link_Record = RECORD { the master link record } LUN : Integer; { LUN used by this link } Read_IOSB: IO_Status_Block; { network read IOSB for this link } Node: CH6; { Copy of remote node name } Task: CH16; { copy of remote task name } Read_Dat: CH16; { net (mbx) message inbound } Msg: Message_rec; { the net message } Stats: Link_Statistics_rec; { link activity numbers } Link_Flags: Set of Link_Flag_typ; { link status flags } Active: Boolean; { TRUE if link in use } END; { Link_Record } VAR I: Integer; { every program needs a generic integer!} Status: Integer; L: 0..Max_Links; { global link index } Crash_Request: Boolean; { TRUE if we're dead but don't know it } Exit_Request: Boolean; { TRUE if we've been asked to quit } Log_file: Text; { log file } Null_IOSB: IO_Status_Block; { dummy for use in SIGNAL calls } IOSB: IO_Status_Block; { generic status block } MyName: Rad56; { "AMIRTR" in RAD-50 } MyNode: CH6; { node name currently executing on } Trademark: str40; { node::name> for logging } Loc_Msg: Message_rec; { message buffer for GETMSG } Conb: Net_Connect_Block; { for use with inbound requests } ReqB: Net_Request_Block; { for use in outbound link requests } Link: Array [0..Max_Links] of Link_Record; { the master link database } { link[0] is net mailbox } { Debugging stuff. We can debug at various levels. Output can be to a file or tt:, via messages, or both. } Debugging: Boolean; { TRUE if DEBUG enabled at some level } Debug_to_file: Boolean; { TRUE if debug output to file or tt: } Debug_to_msg: Boolean; { TRUE if debug output via messages } Debug_level: Integer; { Level we're debugging at, meaningless if DEBUG is FALSE } Debug_flags: Message_packet_sub_set; { Experiment: are enough of these useful? } Debug_Msg: Message_rec; { Message for debug out put via message } Debug_width:Integer; { Width of debug output } Debug_file: Text; { File for debug output to file or tt: } Debug_file_name: CH40; { Filespec for debug output } Debug_task:Ch6; { Task name for debug output via msg } Debug_node:Ch6; { Node debug sink task lives on }