.MB +5 .MT -3 .LL 65 .PN 53 .HE MP/M User's Guide .FT (All Information Herein is Proprietary to Digital Research.) .sp .pp 2.3 Queue and Process Descriptor Data Structures .pp This section contains a description of the queue and process descriptor data structures used by the MP/M Extended Disk Operating System (XDOS). .sp .ce QUEUE DATA STRUCTURES .pp A queue is a first in first out (FIFO) mechanism which has been implemented in MP/M to provide several essential functions in a multi-tasking environment. Queues can be used for the communication of messages between processes, to synchronize processes, and to provide mutual exclusion. .pp MP/M has been designed to simplify queue management for both user and system processes. In fact, queues are treated in a manner similar to disk files. Queues can be created, opened, written to, read from, and deleted. .pp A few illustrations should suffice to describe applications for queues: .pp COMMUNICATION: .pp A queue can be used for communication to provide a FIFO list of messages produced by a producer for consumption by a consumer. For example, consider a data logging application where data is continuously received via a serial communication link and is to be written to a disk file. This would be a difficult application for a sequential operating system such as CP/M because arriving serial data would be lost while buffers were being written to disk. Under MP/M a queue could be used by the producer to send blocks of received serial data (or simply buffer pointers) to a consumer which would write the blocks on disk. MP/M supports concurrency of these operations, allowing the producer to quickly write a buffer to the queue and then resume monitoring the serial input. .pp SYNCHRONIZATION: .pp When a process attempts to read a message at a queue and there are no messages posted at the queue, the process is placed in a priority ordered list of processes waiting for messages at the queue. The process will remain in that state until a message arrives. Thus synchronization of processes can be achieved, allowing the waiting (DQing) process to continue execution when a message is sent to the queue. .cp 20 .pp MUTUAL EXCLUSION: .pp A queue can also be used for mutual exclusion. Mutual exclusion messages generally have a length of zero. A good example of mutual exclusion is that which is used by MP/M to control access to the printer. A queue is created (MXList) and sent one message. When the printer is to be used by the spooler or by entering a control-P (^P) at the console an attempt is made to read the message from the list mutual exclusion queue. This attempt is made using the MP/M conditional read queue function. If the message is available, that is it has not been consumed by some other process, it is read and the printer is used. When finished with the printer, the message is written back to the list mutual exclusion queue. If the message is not available the user who entered the ^P receives a message indicating that the printer is busy. In the case of the spooler, it waits until the printer is available before continuing. .sp .ce QUEUE DATA STRUCTURES .SP .pp The queue data structures include the queue control block and the user queue control block. There are two types of queue control blocks, circular or linked. The type of queue control block used depends upon the message size. Message sizes of 0 to 2 bytes use circular queues while message sizes of 3 or more bytes use linked queues. .sp .ce CIRCULAR QUEUES .pp The following example illustrates how to setup a queue control block for a circular queue with 80 messages of a one byte length. Each example in this section will be shown both in PL/M and assembly language. .cp 17 .LI PL/M: DECLARE CIRCULAR$QUEUE STRUCTURE ( QL ADDRESS, NAME(8) BYTE, MSGLEN ADDRESS, NMBMSGS ADDRESS, DQPH ADDRESS, NQPH ADDRESS, MSG$IN ADDRESS, MSG$OUT ADDRESS, MSG$CNT ADDRESS, BUFFER (80) BYTE ) INITIAL (0,'CIRCQUE ',1,80); .ad .cp 14 .li Assembly Language: CRCQUE: DS 2 ; QL DB 'CIRCQUE ' ; NAME DW 1 ; MSGLEN DW 80 ; NMBMSGS DS 2 ; DQPH DS 2 ; NQPH DS 2 ; MSGIN DS 2 ; MSGOUT DS 2 ; MSGCNT BUFFER: DS 80 ; BUFFER .AD The elements of the circular queue shown above are defined as follows: .LI QL = 2 byte link, set by system NAME = 8 ASCII character queue name, set by user MSGLEN = 2 bytes, length of message, set by user NMBMSGS = 2 bytes, number of messages, set by user DQPH = 2 bytes, DQ process head, set by system NQPH = 2 bytes, NQ process head, set by system MSG$IN = 2 bytes, pointer to next message in, set by system MSG$OUT = 2 bytes, pointer to next message out, set by system MSG$CNT = 2 bytes, number of messages in the queue, set by system BUFFER = n bytes, where n is equal to the message length times the number of messages, space allocated by user, set by system Note: Mutual exclusion queues require a two byte buffer for the owner process descriptor address. Queue Overhead = 24 bytes .AD .sp .ce LINKED QUEUES .pp The following example illustrates how to setup a queue control block for a linked queue containing 4 messages, each 33 bytes in length: .cp 16 .LI PL/M: DECLARE LINKED$QUEUE STRUCTURE ( QL ADDRESS, NAME (8) BYTE, MSGLEN ADDRESS, NMBMSGS ADDRESS, DQPH ADDRESS, NQPH ADDRESS, MH ADDRESS, MT ADDRESS, BH ADDRESS, BUFFER (140) BYTE ) INITIAL (0,'LNKQUE ',33,4); .ad .cp 21 .li Assembly Language: LNKQUE: DS 2 ; QL DB 'LNKQUE ' ; NAME DW 33 ; MSGLEN DW 4 ; NMBMSGS DS 2 ; DQPH DS 2 ; NQPH DS 2 ; MH DS 2 ; MT DS 2 ; BH BUFFER: DS 2 ; MSG #1 LINK DS 33 ; MSG #1 DATA DS 2 ; MSG #2 LINK DS 33 ; MSG #2 DATA DS 2 ; MSG #3 LINK DS 33 ; MSG #3 DATA DS 2 ; MSG #4 LINK DS 33 ; MSG #4 DATA .AD The elements of the linked queue shown above are defined as follows: .LI QL = 2 byte link, set by system NAME = 8 ASCII character queue name, set by user MSGLEN = 2 bytes, length of message, set by user NMBMSGS = 2 bytes, number of messages, set by user DQPH = 2 bytes, DQ process head, set by system NQPH = 2 bytes, NQ process head, set by system MH = 2 bytes, message head, set by system MT = 2 bytes, message tail, set by system BH = 2 bytes, buffer head, set by system BUFFER = n bytes where n is equal to the message length plus two, times the number of messages, space allocated by the user, set by the system .AD .sp .ce USER QUEUE CONTROL BLOCK .pp The user queue control block data structure is used to provide read/write access to queues in much the same manner that a file control block provides access to a disk file. Queues are "opened", an operation which fills in the actual queue control block address, and then can be read from or written to. .pp If the actual queue address is known it can be filled in the pointer field of the user queue control block, the 8 byte name field can be omitted, and an open operation is not required in order to access the queue. .pp The following example illustrates a user queue control block: .cp 9 .LI PL/M: DECLARE USER$QUEUE$CONTROL$BLOCK STRUCTURE ( POINTER ADDRESS, MSGADR ADDRESS, NAME (8) BYTE ) INITIAL (0,.BUFFER,'SPOOL '); DECLARE BUFFER (33) BYTE; .ad .cp 11 .li Assembly Language: UQCB: DS 2 ; POINTER DW BUFFER ; MSGADR DB 'SPOOL ' ; NAME BUFFER: DS 33 ; BUFFER .AD .cp 14 .pp The elements of the user queue control block shown above are defined as follows: .LI POINTER = 2 bytes, set by system to address of actual queue during an open queue operation, or set by the user if the actual queue address is known MSGADR = 2 bytes, address of user buffer, set by user NAME = 8 bytes, ASCII queue name, set by user, may be omitted if the pointer field is set by the user .AD .sp .ce QUEUE NAMING CONVENTIONS .pp The following conventions should be used in the naming of queues. Queues which are to be directly written to by the Terminal Message Process (TMP) via the Command Line Interpreter (CLI) must have an upper case ASCII name. Thus when an operator enters the queue name followed by a command tail at a console, the command tail is written to the queue. .pp In order to make a queue inaccessible by a user at a console it must contain at least one lower case character. Mutual exclusion queues should be named upper case 'MX' followed by 1 to 6 additional ASCII characters. These queues are treated specially in that they must have a two byte buffer in which MP/M places the address of the process descriptor owning the mutual exclusion message. .cp 35 .sp .ce PROCESS DESCRIPTOR .pp Each process in the MP/M system has a process descriptor which defines all the characteristics of the process. The following example illustrates the process descriptor: .cp 28 .LI PL/M: DECLARE CNS$HNDLR STRUCTURE ( PL ADDRESS, STATUS BYTE, PRIORITY BYTE, STKPTR ADDRESS, NAME (8) BYTE, CONSOLE BYTE, MEMSEG BYTE, B ADDRESS, THREAD ADDRESS, DISK$SET$DMA ADDRESS, DISK$SLCT BYTE, DCNT ADDRESS, SEARCHL BYTE, SEARCHA ADDRESS, DRVACT ADDRESS, REGISTERS (20) BYTE, SCRATCH (2) BYTE ) INITIAL (0,0,200,.CNS$STK(19), 'CNS ',1,0FFH); DECLARE CNS$STK (20) ADDRESS INITIAL ( 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H, 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H, 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H, 0C7C7H,STRT$CNS); .ad .cp 28 .li Assembly Language: CNSHND: DW 0 ; PL DB 0 ; STATUS DB 200 ; PRIORITY DW CNSTK+38 ;STKPTR DB 'CNS ' ; NAME DB 0 ; CONSOLE DB 0FFH ; MEMSEG (FF = resident) DS 2 ; B DS 2 ; THREAD DS 2 ; DISK SET DMA DS 1 ; DISK SLCT DS 2 ; DCNT DS 1 ; SEARCHL DS 2 ; SEARCHA DS 2 ; DRVACT DS 20 ; REGISTERS DS 2 ; SCRATCH CNSTK: DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H DW 0C7C7H,0C7C7H,0C7C7H DW CNSPR ; CNSTK+38 = PROCEDURE ADR .AD .pp The elements of the process descriptor shown above are defined as follows: .LI PL = 2 byte link field, initially set by user to address of next process descriptor, or zero if no more STATUS = 1 byte, process status, set by system PRIORITY = 1 byte, process priority, set by user STKPTR = 2 bytes, stack pointer, initially set by user NAME = 8 bytes, ASCII process name, set by user The high order bit of each byte of the process name is reserved for use by the system. The high order bit of the first byte (identified as NAME(0)') "on" indicates that the process is performing direct console BIOS calls and that MP/M is to ignore all control characters. It is also used to suppress the normal console status check done when BDOS disk functions are invoked. This bit may be set by the user. CONSOLE = 1 byte, console to be used by process, set by user MEMSEG = 1 byte, memory segment table index B = 2 bytes, system scatch area THREAD = 2 bytes, process list thread, set by system DISK$SET$DMA = 2 bytes, default DMA address, set by user DISK$SLCT = 1 byte, default disk/user code DCNT = 2 bytes, system scratch byte SEARCHL = 1 byte, system scratch byte SEARCHA = 2 bytes, system scratch bytes DRVACT = 2 bytes, 16 bit vector of drives being accessed by the process REGISTERS =20 bytes, 8080 / Z80 register save area SCRATCH = 2 bytes, system scratch bytes .AD .sp .ce PROCESS NAMING CONVENTIONS .pp The following conventions should be used in the naming of processes. Processes which wait on queues that are to be sent command tails from the TMPs are given the console resource if their name matches that of the queue which they are reading. Processes which are to be protected from abortion by an operator using the ABORT command must have at least one lower case character in the process name. .br