VSDRV VERSION 2 -- VARIABLE SEND-DATA DRIVER FOR RSX-11M by: John Osudar Science Applications, Inc. 1211 W. 22nd Street, Suite 901 Oak Brook, IL 60521 (This document corresponds to VSDRV V2.04, dated 30-Oct-81) This work was supported by the Light Water Breeder Reactor Proof-of-Breeding Analytical Support Project at Argonne National Laboratory. Introduction ------------ RSX-11M V3.2 provides several means for communication between tasks. Among these are global event flags, common memory, and the send/receive data directives. The latter provide for data transfer from one task to another, but restrict the amount of data to 13 words per transfer. RSX-11M-Plus allows variable-length data blocks of up to 256 words in length; this feature is not provided with RSX-11M, because it requires support for secondary executive pool, which RSX-11M does not have. Because a "variable length send/receive" function can be useful in a number of applications, a simple driver has been written to provide some of the same functionality. The RSX-11M device name chosen for this driver is VS: (for Variable Send-data), and its features are as follows: The driver is actually a queue manager, which has its own private pool of dynamic memory. Functions provided include: create a queue, put a message in a queue, get a message from a queue, and delete a queue. Each queue has a six-character name. When a task accesses a queue, it specifies the queue name. By default, each task can access a queue whose name is the same as the task's name. If selected when the driver is assembled, a protection feature prevents non-privileged tasks from operating on queues other than their default queue, except for writing. (Any task can write a message to any queue). Queues are created explicitly through driver QIO calls, and are always accessed in FIFO (first-in, first-out) order. With VS: Version 2, a number of additional features have been added to the driver. The ability to request a "read with wait" has been retained. (This feature causes a read request on an empty queue to wait until a message is available). However, "read with wait" has the negative effect of causing the requesting task to be fixed in memory while the request is pending. To alleviate this problem, an AST (Asynchronous System Trap) mechanism has been added in Version 2. A task can specify an AST routine to be called each time a message is received in a particular queue. Unlike "read with wait", specifying AST's does not cause the task to become fixed in memory, since RSX-11M will reload a task that has been checkpointed out to disk when an AST occurs for that task. Another new feature of VS: Version 2 is the "create or flush" function, which creates a new empty queue if not already present, but flushes the queue of all messages (and aborts a waiting read request) if the queue already exists. Version 1 required a "delete queue" followed by a "create queue" to achieve the same effect. VS: Version 2 is compatible with Version 1, with one exception: the function code for the "dump driver pool" function, which is not intended for general use, has been changed from octal 3400 to octal 4000, because octal 3400 is the code for a standard DEC I/O function that VS: now uses. This function is only used for debugging, and by the VS: utility program VSUTIL, which has been modified for Version 2. Function, Parameters, Status Codes ---------------------------------- Here is a list of the QIO function codes recognized by the VS: driver. All function codes are in octal. IO.KIL (0012) Cancel all waiting read requests for this task. IO.WLB (0400) Put a message into any existing queue. IO.RLB (1000) Get a message from a queue. IO.RLB ! SF.WAI (1200) Wait for a message to be put into a queue, and get it. IO.ATT (1400) Device attach -- ignored. IO.DET (2000) Device detach -- ignored. IO.CRQ (2400) Create a new message queue. IO.CRQ ! SF.FLU (2500) Create a new message queue, or flush an existing one. IO.DLQ (3000) Delete a message queue and all queued messages. IO.CLN (3400) Clear all AST's set by this task. IO.DMP (4000) For utilities or debugging, dump a snapshot of the driver's pool. IO.AST (4400) Set or clear an AST for an existing queue. IO.EXM (5000) Examine a selected message in a queue, without dequeuing it. IO.DLM (5400) Delete a selected message from a queue. The six-word QIO parameter list is used by VS: as follows: Word 1 -- Buffer address (with IO.WLB, IO.RLB, IO.DMP, IO.EXM) Word 2 -- Buffer length in bytes (with IO.WLB, IO.RLB, IO.DMP, IO.EXM) Word 3 -- First word of RAD50 queue name (with IO.WLB; for privileged tasks, also with IO.RLB, IO.CRQ, IO.DLQ, IO.AST, IO.EXM, IO.DLM) Word 4 -- Second word of RAD50 queue name (same functions as word 3) Word 5 -- Message ID (with IO.EXM, IO.DLM) Word 6 -- Address of AST routine, or 0 to clear AST (with IO.AST) Notes: (*) Buffers used with VS: must be aligned on word boundaries. (*) The "read" function returns the name of the sending task (in RAD50 representation) in the first two words of the buffer. Thus, if you are expecting messages of up to N bytes in length, you must provide at least N+4 bytes of buffer space for a "read" operation. (*) Under no circumstances can any task clear an AST other than the task that set the AST. Also, setting an AST for a queue prohibits read-and-wait, flush, or delete queue operations, but does not prohibit a simple read operation. (*) The AST routine receives control with three parameter words on its stack: the first two words are the queue name in RAD50 representation, and the third word is the length of the message in bytes, including four extra bytes for the sender task name. See the Executive Reference Manual for details about AST processing. (*) The "examine message" and "delete message" operations utilize a "message- ID", which is actually the virtual address of the message in VSDRV space. Message-ID 0 corresponds to the first message in a queue. (*) The "examine message" function can be called with a buffer of any length; as much of the message as will fit into the buffer will be copied. The buffer will contain four words of information preceding the message. The first word is the message-ID of the NEXT message in the queue, or 0 if this is the last one. The second word contains the length of the message text in bytes. The third and fourth words contain the sender task name in RAD50. Status codes that can be returned by VS: in the first word of the I/O status block include: IS.SUC (+1.) Successful completion; second word of IOSB is a byte count. IE.ABO (-15.) Operation aborted due to IO.KIL, SF.FLU, IO.DLQ, or I/O rundown at task exit. IE.PRI (-16.) Privilege violation--unprivileged task attempted to create, delete, set an AST in, or read a queue other than its default, or attempted to do an IO.DMP function (only if protection enabled). IE.QNF (-101.) Queue not found. IE.QEX (-102.) Queue already exists (on attempt to create a queue). IE.NMS (-103.) No more space in VS: private pool. IE.RAW (-104.) Read already waiting on queue (for IO.RLB ! SF.WAI, or IO.AST) IE.NOM (-105.) No message available in queue (for IO.RLB without SF.WAI, IO.EXM, or IO.DLM). IE.UBS (-106.) User buffer is too small to hold entire message (or to hold entire driver pool snapshot, for IO.DMP). IE.ATS (-107.) AST is already set (for IO.RLB ! SF.WAI, IO.AST specifying an AST address, IO.AST clearing another task's AST, IO.CRQ!SF.FLU or IO.DLM to a queue whose AST was set by another task) IE.ATC (-108.) No AST is set for queue (for IO.AST clearing an AST). Disadvantages and advantages of VS: Version 2 --------------------------------------------- Disadvantages (compared to true variable send/receive on RSX-11M-Plus): 1. At least one LUN must be set aside for use with VS:--this LUN is the one you use for setting AST's. If you use "read and wait", then one LUN must be set aside for each simultaneous outstanding wait. True variable send/receive does not require any LUN's. 2. The VS: driver and its private pool occupy additional memory space, which cannot be used for other purposes when not in use by VS:. True variable send/receive code is part of the exec, and its pool space is part of the exec's secondary pool, which is usable by other system components. 3. VS: requires that queues be created, flushed, and deleted explicitly. True variable send/receive automatically has a queue for each task, which is created when the task is installed, flushed when the task exits, and deleted when the task is removed. Advantages (compared to true variable send/receive on RSX-11M-Plus): 1. VS: can be used under RSX-11M, which does not support variable send/receive or secondary exec pool; the only cost in terms of exec resources is the I/O packet and AST block usage. 2. VS: queues exist independent of tasks in the system. When a task exits, no messages are deleted (not even from a task's "default" queue); queues can still be "flushed" using the "create or flush" function. 3. VS: allows a task to manipulate several queues of messages, while variable send/receive provides only one queue per task. With VS:, tasks can share queues, under some protocol established among them, if the application requires. (For example, you can create a spooling system with several despoolers taking requests from the same queue.) 4. VS: allows selective examination and deletion of messages in any queue. Use of VS: from FORTRAN ----------------------- Here are some notes on using VS: Version 2 from a FORTRAN program. Most of this information can be found in the RSX-11M/M-PLUS Executive Reference Manual. (1) Setting up the QIO parameter list The QIO parameter list is an array of six integers. The VS: driver uses these six words as described previously. To create the parameter list, use a statement like this: INTEGER IPARM(6) To put a buffer address into the first word, use the library subroutine GETADR, like this: CALL GETADR(IPARM(1),IBUFER) (Here, IBUFER is the name of the buffer array that is used to transfer messages between the driver and the task). To put a buffer size into the second word, use a simple assignment statement: IPARM(2)=124 (This tells the driver that 124. bytes of storage are available in the buffer on a read request, or that the message being sent is 124. bytes long on a write request. This would require that the buffer array be declared to contain at least 124/2 = 62 words, e.g. INTEGER IBUFER(62) or the equivalent). To put a RAD50 queue name into the third and fourth words, you must create a two-word integer array containing the queue name, and set the name into the array with a DATA statement, like this: INTEGER QNAME(2) DATA QNAME/3RMYQ,3RUE5/ (The constant form 3Rxxx is like 3Hxxx or 'xxx' but creates a RAD50 representation of the character string. In this case, QNAME(1) will contain the string 'MYQ', and QNAME(2) will contain 'UE5', which together form the name of the queue 'MYQUE5'). Then, you put the queue name into the parameter list with two simple assignments: IPARM(3)=QNAME(1) IPARM(4)=QNAME(2) (There are other ways to do this, especially for cases where the queue name is not a constant determined at compilation time, but may be determined when the program is run. Consult the FORTRAN User's Guide for subroutines that convert ASCII character strings to RAD50, if you need them). Note that you do not need to set up the first two words of the parameter list unless you are doing a "read" or "write" function, and that the third and fourth words can be set to zeroes if you want to use your task's default queue name (same as the task name). Setting up parameter word six with the AST subroutine address is not discussed here, as a special interface routine is generally used to allow FORTRAN to process AST's. This routine is described in detail later. (2) Assigning a unit to the VS: driver In order to access the VS: driver, you must have a logical unit assigned to it. This can be done when you build your task, with an option like this: ASG=VS:3 (which assigns LUN 3 to the VS: driver). Also, you can do this with a subroutine call within your program: CALL ASNLUN(3,'VS',0) Here, you specify the LUN as the first parameter; the other parameters must be 'VS' and 0 as shown. You can assign as many LUN's to the VS: driver as you need. In particular, if your program will be using "read and wait" with more than one queue at the same time, then you must have as many LUN's assigned as there will be simultaneous waits. (3) Doing the actual operation To do the operation, you call one of the library routines QIO or WTQIO. In both cases, the calls are identical: CALL QIO (fnc,lun,[efn],,[isb],[prl][,ids]) CALL WTQIO(fnc,lun,[efn],,[isb],[prl][,ids]) The parameters enclosed in [ ] are optional, but commas must be included as shown, even if some parameters are left out. The parameters are: fnc One of the octal function codes, specified in FORTRAN with a leading '"' to signify "octal"; e.g. "1200 lun The logical unit number on which to perform this operation. The LUN must already be assigned to VS: efn An event flag number. Event flags are single-bit flags that can be used to signal the occurrence of certain events, in this case the completion of the requested operation. You should probably use "local" event flags here (event flags used only by your task); these flags are numbered from 1 to 32. It is through the event flag that you determine when the operation has been completed. isb The name of a two-word array, the I/O status block, which receives a status code in the low byte of the first word, and a byte count in the second word. The status code should be +1 for successful operations. The byte count tells you how long the message is when you do a read, and should equal your message length when you do a write. prl The name of the six-word parameter list array. ids An integer variable into which the system places a "directive status"; if you have made any mistakes in setting up the call, or if some condition has occurred that has prevented your request from being passed to the VS: driver, this word will contain an error code. Normal completion should produce a +1 status. The difference between using the QIO and WTQIO calls is this: WTQIO will not return control to your program until the operation has been completed, while QIO will return as soon as the operation has been set up and sent to the VS: driver. Look at the Executive Reference Manual for subroutines that test event flag status, or stop/wait for event flags to be set, if you are planning on using the QIO call instead of the WTQIO call. Use of VS: AST's from FORTRAN ----------------------------- The Executive Reference Manual states that FORTRAN does not support AST routines. This does not mean that you can't process AST's in a FORTRAN routine; it only means that FORTRAN doesn't provide the necessary interface between the RSX-11M AST mechanism and itself. When an AST occurs, RSX-11M saves part of the current status of the program, and transfers control to the specified AST routine. Depending upon the type of AST that has occurred, several parameters may be passed by the system to the AST routine. The method used for passing these parameters is not compatible with the way FORTRAN calls subroutines; this is one of the reasons why FORTRAN doesn't directly support AST routines. A second reason is that the system does not save the program's register contents before entering the AST routine; since FORTRAN subroutines freely modify all registers, this is also an incompatibility. Finally, when an AST routine completes its processing, it must return control to the system (for restoring of the program's status and clearing of the "AST state" indicator); FORTRAN subroutines simply perform a "RETURN" operation, which is not enough. Therefore, in order to process AST's within a FORTRAN routine, some additional interfacing code must be supplied, written in MACRO-11. Many different types of AST interface modules for FORTRAN can be written; you should have a special one written for you if your needs aren't met by those described here. Each such module will have the following components: an initialization routine, a "set AST for queue" routine, a "clear AST for queue" or "clear all AST's" routine, and an internal AST routine that gains control when an AST occurs, saves the program's registers, sets up the parameter list for the FORTRAN AST routine, calls the FORTRAN AST routine, and finally cleans up the stack, restores the registers, and does an "AST exit" after the FORTRAN routine returns. AST setup module IVSAST IVSAST consists of FORTRAN-callable function IVSAST, and an internal AST interface routine. IVSAST allows a list of queues to be specified, and either a single FORTRAN routine, or a list of FORTRAN routines, to be associated with the AST's for those queues. The internal AST routine calls the appropriate FORTRAN routine when an AST occurs, passing it the queue name and message length. Individual clearing of AST's for queues is not provided, but all AST's set by the program may be cleared by calling IVSAST a second time, with no queue name list. For further details, look at documentation in the source code for IVSAST. AST setup module BCTVSAST1 BCTVSAST1 consists of FORTRAN-callable subroutines VSAST1, ASTSET, and ASTCLR, and an internal AST interface routine. VSAST1 is called once, to specify the VS: logical unit number, an event flag for internal use, and the single FORTRAN AST routine. Then, ASTSET is called to set an AST for a single queue, and ASTCLR is called to clear the AST for a single queue. The internal AST routine calls the FORTRAN routine when an AST for any queue occurs, passing it the queue name and message length. To clear all AST's at once, a call to the Executive subroutine WTQIO must be made. For further details, look at documentation in the source code for BCTVSAST1. VSUTIL Utility Program ---------------------- (This corresponds to version V02.02 of VSUTIL, dated 31-Jul-81.) VSUTIL provides some utility functions related to the VS: Variable Send-data driver, Version 2. The following commands are recognized (each command keyword can be abbreviated to just the first letter): QUEUES ["queue"] Displays summary of queues on the terminal, or display all messages in a single queue. SHOW ['filename'] Produces a snapshot of VS: private pool, queues, messages. CREATE "queue" Creates a queue with the specified name. DELETE "queue" Deletes the specified queue, and all messages in it. FLUSH "queue" Flushes the specified queue of all messages REMOVE msg-id,"queue" Removes the specified message from the specified queue " ... " are required delimiters for queue names, because queue names are allowed to have embedded (but not leading) blanks; if VSUTIL is run through CCL, the delimiters must be doubled up ("" ... "") on the MCR command line in order to be passed through to VSUTIL by CCL. [ ... ] indicates optional parameters. "Message-ID" is the virtual address of the message. If this program is passed an MCR command line, the line must be one of the valid commands listed above, or the form "@FILENAME". The latter form is particularly useful if VSUTIL is run from your STARTUP.CMD file to set up permanent queues.