mm fflBGnSn BBBHHMBtnlKMl RiRiw MtMnlliffll ifillfifiSs HP HffiM^mlH? HNRn WSS& WHjSk MM SM _KflU H iH MB ■H HUH H iP>" Hi Hi HUffil iilHlilll m m HE Bswbk ■ I JswlnM LIBRARY OF THE UNIVERSITY OF ILLINOIS AT URBANA-CHAMPAIGN £>L0.%4 cop. 2. Digitized by the Internet Archive in 2013 http://archive.org/details/designimplementa520oxle cop. ^ UIUCDCS-R-T2-520 / f I^L^^ll THE DESIGN AND IMPLEMENTATION OF AN EDUCATIONAL TIMESHARING SYSTEM FOR THE PDP-11 "by Donald Wayne Oxley June, 1972 SrffcUftffdtfftSfi-WE The person charging this material is re- sponsible for its return on or before the Latest Date stamped below. Theff, mutilation, and underlining of books are reasons for disciplinary action and may result in dismissal from the University. UNIVERSITY OF ILLINOIS LIBRARY AT URBANA-CHAMPAIGN SEP 1 19- AUG 2 9 Re CD L161— O-1096 UIUCDCS-R-72-520 THE DESIGN AND IMPLEMENTATION OF AN EDUCATIONAL TIMESHARING SYSTEM FOR THE PDP-11* by Donald Wayne Oxley June, 1972 Department of Computer Science University of Illinois at Urbana-Champaign Urbana, Illinois 6l801 *This work was supported in part by the National Science Foundation under Grant No. US NSF GJ-812 and was submitted in partial fulfillment for the Master of Science degree in Computer Science, 1972. Ill ACKNOWLEDGEMENT The author would like to thank Professor Donald B. Gillies for his advice and support throughout the development of this project and the writing of this thesis. Special thanks also go to Dr. Thomas Chen who first realized the feasibility of this project and worked with the author during the early months of development. Al Davis, Stan Kerr, Jim Hart and Keith Phillips have invested an amount of time and effort toward the development of instructional software for the system that cannot be measured. Without them, ETS would have been a total failure; I am deeply indebted to them. Also, the author would like to thank Don Burn, Chuck Collins, Bob Feretich, Barry Finkel, Jim Lellman, David Pasta, Ian Stocks, and the students of Al Davis ' CS 201 quiz sections for their help in developing and testing the software. Additional thanks go to Harold Lopeman, Bob Miller, Jim Miller, and Gordy Peterson for their efforts in building and maintaining the hardware. I am very grateful to Mrs. June Wingler who has done an excellent job of typing both this thesis and the documentation for this project. And most especially, I am indebted to my wife, Pat, for her patience, understanding, and encouragement. IV TABLE OF CONTENTS Page I . INTRODUCTION 1 II . THE ETS MONITOR 5 A. System Resources 5 B. System Control Structures 7 C . System Modules , 11 D. System Synchronization 20 III. THE ETS FILING SYSTEM 33 A. File Organization 3^ B. File Processor k-5 C . File Requests ^8 D. Errors and Protection 51 IV. I/O SUBSYSTEM . User File Storage Active users may read their program files onto disk while operating on them. Handling of file storage is very important and is treated as a separate section of this manual. B. System Control Structures In order to function properly, a system must keep available a wealth of information on what is going on in the system at any given time. This information is a common pool of data which system routines may access and must update with any information they have which other routines may need to interrogate. 1. Job Data Blocks Associated uniquely with each job (user) logged in on the system are two 16 word data blocks. The first (called the Job Data Block) contains a pointer to the second (called the I/O block or I OB) as well as information relating to the job's status. The second block contains a list of "channels" (words which may contain pointers to I/O control blocks). There is a pointer entered in the I/O block for each file or device which the user has open. (See figures II. 1 and II. 2.) 2. File Control Blocks (FCB)/Device Data Blocks (DDB) Associated with each open file and each device in the system is a 16 word control block. When a user opens a file (device), a pointer to the FCB/DDB is stored in the appropriate channel of his I/O block. A FCB/DDB gives status and access information for its particular file (device) , Note that there is no FCB for an unopened file, however, the system still maintains a DDB for each device whether it is open or not. JOBTBL Mi m i IT J ob Data Blo ck I/Q Bi nfi k, Job Status Information I/O Block Up to 8 I/O channels File /Device Teletype JDB I/O Block FCB/DDB User TTY DDB Jser ConsoL Control Information FCB/DDB Control Information for Open Files or Devices User TTY DDB Figure II. 1 ETS Job Control Structure JDIOB - Pointer to I/O Block JDFLG - Job Status Flags 2 JDIOST - I/O Error Status k JDSP - Relative User Stack 6 JDCPU - CPU Time Used 10 JDKCT - KILO-CORE-Ticks Used 12 JDDEV - Device Time Used Ik JDSIZl - Next Si i JDSIZO se in K Present Size in 16 K JDUFD - Start Block of Job's UFD 20 JDPPN - Pro j -Prog Number 22 JDSGNW - Unused 2k JDSGMX - Unused 26 JDUFLG - User Communication Flags 30 JDNAME - Job Type Code 32 Unused 3h Unused 3^ Figure II. 2 Job Data Block 10 3. JOBTBL At initialization time, the system establishes a table of (possibly- null) pointers which will be used to point to the first Job Data Block (JDB) for each active job. There is a pointer position for each possible job in the system. When a job is created, and its Job Data Blocks are established, the appropriate entry in JOBTBL is loaded with a pointer to the JDB. Thus at any time, we may interrogate JOBTBL to find the number of active jobs in the system, as well as pointers to their control blocks. (See figure II. 1.) k . DEVTBL During initialization, a DDB is set up for each system device. Pointers to these devices are kept in DEVTBL. There is a unique entry for each device. Through DEVTBL, device service routines can record transaction results without knowing the owner job. When a device is opened by a user, note that a separate pointer to the DDB is placed in the user's IOB so that device independent routines can communicate with an arbitrary device without worrying about what it is. 5. JBSTAT-JBWAIT As it is quite possible for a job to request input from a currently inactive device or output to a busy device, it is necessary to have a mechanism for causing jobs to wait on the completion of an I/O request. This mechanism is implemented by assigning to each possible blockage condition a bit position from 0-15. We then associate two status words with each job. In the first — JBWAIT — we set a bit indicating any blockage condition that arises. When the condition no longer exists, the controlling service routine sets the same bit in JBSTAT. 11 We then define the condition that a job be runnable as JBSTAT(J0B#) * JBWAIT(JOB#) f 0. 6. CORTBL Independent of job status information, it is necessary for the system to keep information on each available core segment. CORTBL is a table with one entry of two bytes for each ^OOOq bytes of user core. The low byte of each entry contains the job therein resident. The high byte contains status information on that block of core. 7. Volatile System Information The system needs a number of variables which define its "state" at any given instant in time. These include such things as time and date, the current job with pointers to some of its relevant information, headers for system queues, file processor status, and swap processor status. 8. File System Information The system also has a fairly complex data structure to locate and control items in its filing system. The discussions of such structures will be left to chapter III. C. System Modules ETS uses five basic software processors to accomplish timesharing. (See figure II. 3.) In general, each processor operates asychronously from the other processors. Some sequencing and interlock mechanisms do exist and are explained in section D. We shall examine each processor, outline its basic functions and how it accomplishes them. 12 w -p *H b^ o 3 CO *H CO U CD CD O -P O s 5h H Ph t- - o h H •P O C h o •P C) C o <+H o o n, the last m-n blocks of core are removed from the end of the job. For n>m, the job is swapped out and brought in at the next size with the blocks added to the end of the job. .EXIT - programmed termination. .FIND - request to position a file at a particular block. (See chapter III.) .LOCK - request to set lock bit on job's entries in CORTBL. .TTAPE - request to change teletype to tape mode of input. .TTRST - request to change teletype to normal operation. .ULOCK - request to release core a user may have locked. •WAIT - request to wait on the appearance of a delimiter in the teletype buffer. 3. File Processor See chapter III, the ETS Filing System. h. I/O Processor The ETS I/O processor is comprised of a standardized "front-end" which communicates with the user and of separate device service routines for each type of device in the system. 16 Within reasonable limits, ETS I/O structure is device independent. A user simply constructs a transfer block (XRB) containing the necessary I/O parameters and executes a .READ/. WRITE passing the address of his XRB to the system. a. I/O Calls The user must allocate in his own area a transfer block (see Figure II. 5) and insert the appropriate parameters. He then places the address relative to the beginning of his area of the XRB in R3 and executes a .READ or .WRITE. b. Parameter Decoding ETS has a controlling I/O dispatch program (USERIO) which will check the I/O parameters supplied by the user for errors (does he want to write on the card reader?). If the user has asked for a valid operation and has the necessary files/devices open, USERIO will select the appropriate device service and pass control to it. c. Device Service Routines Associated with each device is a unique service routine which can cope with the special needs of the individual device. The service routine will attempt to transfer characters to/from the monitor chain buffers (see section IV. B. 2) from/to the user area. If chain buffers become full/empty, the device service routine will fire up the device interrupt service to empty/fill the buffers and will put the job to sleep to wait on the physical I/O completion. In order to provide a fast response to the user, i/O is considered to be a process between the user and the system. The system then uses its own interrupt service to do the actual I/O transfers. This technique allows users at TTY consoles to continue typing in IT XRB: XRLNK (=0) XRPTR (=2) XRLEN (=k) XRBC (=6) XRLOC (=10) - XRCI (=12) XRPPAP ( = lk) - XRPAR2 (=16) - System Link Word Offset from XRB to BUFFER— not Modified Maximum Transfer Length for Read Actual Transfer Count Offset from XRB to BUFFER— Updated Channel for Operation 1st Parameter Word 2nd Parameter Word On read operations, XRBC should be initially zero and the system will return the actual character transfer count. In the case of line oriented devices (e.g., TTY) a read operation will terminate on the transfer of a unless XRLEN is exceeded; otherwise, the system will fulfill XRLEN unless an EOF is encountered. In the case of character (non-disk) I/O, XRLOC will point to the last character transferred. Figure II. 5 XRB Structure 18 their next request -while the present request is being processed. The system will simply store the request in its own buffers and pass it on to the user program when requested. In order to prevent unnecessary "sleeping" of jobs, this same technique is used for output. When a user program wishes to perform output, this output is simply transferred to the system buffers and the job is allowed to continue processing. In order to prevent the user from outputting more than the system can handle, each device has associated with it a maximum number of buffers which may be used at any one time. If a user job needs more than this, it is forced to sleep until the system can catch up with some physical output. 5- Interrupt Processors ETS communicates with the outside world through the interrupt mechanism. All I/O devices are run in interrupt mode and communicate with their individual handlers which are responsible for interfacing with the system. Interrupt drivers are triggered by device service routines and will run until they deplete a necessary resource (e.g., buffer space) at which time they will cause the initiating job to be rescheduled. Communication between the device interrupt handler and the device service routine is diagrammed in figure II. 6 utilizing the monitor chain buffers. The asychronous operation of the device interrupt handlers and the device service routines is achieved by using a chain of system buffers (Monitor Chain Buffers) to store data on a temporary basis. These buffers are manipulated with two routines : STOKE - will store a character into the next available position in the chain buffers. If a particular •H CO Ri) in system core. When the system wishes to relocate a user, it will consult the relocation bytes and relocate any register for which REGREL+i^O. Since it is unreasonable (and suicidal) to expect beginning students to code without errors, and to code under ETS' coding restrictions, all user written code will be run under an interpreter. Once code has been completely debugged and modified to ETS' conventions, it may then be run without an interpreter. 5. Priority Control The PDP-11 hardware provides 8 levels of job priority. ETS breaks this into 3 operating ranges: a. Levels 0-3 Normal interruptable code (both system code and the user job) executes in this level. Priority arbitration within these levels is handled by the routine RTI3. All software interrupts, the clock, and the disk may cause control to pass to RTI3. RTI3 will automatically return control to the interrupted process if it was running at a priority > 3« Otherwise, it will process L3QUE to see if there are other tasks to be performed. b. Levels k--6 Device interrupt service routines run at these levels. Priority arbitration is by the hardware. 26 c. Level 7 Critical code segments run at priority 7 so that they may not be interrupted. 6. Flow of Control (Note: this section relies heavily on the diagrams in figure II. 7 and assumes a reasonable idea of both the purpose and structure of the routines mentioned. ) Flow of control in ETS may be thought of as a tree in which each external leaf on every tree is the root of some other tree (see figure II.7). Each node in the tree is a routine which may call one or more "lower level" routines. At any point where a node has 2 or more daughters, there is some condition or event which may be interrogated to determine which branch to follow. Notice that there is only one tree with a root of user LEVEL — this node is the user program. At any given time there is only one active user which is represented by this node. Since no other user is active, control cannot possibly pass out of these trees to another user. Any time that the scheduler (SCHED) is permitted to run, it may make another job the active job. These diagrams also do not show any device interrupts other than disk and clock. No other devices may cause control to be transferred to any part of this tree directly. Their interrupt handlers may simply store or fetch a character and (possibly) set a bit in JBSTAT, after which they must return to the interrupted process. There are two routines which are "operator-like" in nature. SAVJOB will cause the current job to be the NULJOB (if the current job is 27 a •H o CO g> CO •p M M 1) •H 28 already NULJOB, it has no effect). RESJOB will cause the current job to be anything other than NULJOB (if there is no job ready to run, it will not be called) . Normally, the system is executing code associated with the user LEVEL (user). This code runs at priority and may be stopped at any time. There are 3 events which may cause control to pass out of user LEVEL: a. A system tick may occur. The clock interrupts every l6 msec. Every 6th interrupt (100 msec) causes a system tick during which the clock will set the QSCHED bit in L3QUE so that the system will choose a new task at the next opportunity. If the priority at the time of the interrupt was < 2, the clock will execute SAVJOB and then branch to the common interrupt return RTIJ. If the CPU priority at the time of the interrupt was > 3, the clock will branch directly to RTI3 which will return to the interrupted process. b. A disk access completion interrupt may occur. The disk will set the Q-bit in L3QUE (QSWAP, QFILE, QFIP) for the service routine which requested the disk transfer, execute SAVJOB if the CPU priority was < 2, and branch to RTI3. c. The user may execute an EMT. Unlike the disk and clock interrupts over which the user has no control, the EMT is a request by the user for some type of system support. There are 3 types of support which a user may request: (l) File Processor Call The user wants a service provided by the file processor (FTP) such as creating or opening a file. 29 FIP operates in a strictly serial fashion on all user requests; thus, the user's request passes to a special FIP interface which checks to see whether or not FIP is currently busy with another request. If it is not busy, the job is saved and processing is started. Note that FIP generally requires one or more disk accesses to complete its work; consequently, the job is dumped and the system will look for something else to do while FIP is executing. If FIP is busy, the request is queued for FIP to find later, the job is saved and control passes to RTI3. In this case, the calling priority of RTI3 will be that of the user job (FR0), not that of the FIP interface; thus the job will be stopped and the system will look for another job to run. (2) Special EMT Function The user wants a service provided by one of the special EMT functions (see II. C. 2) such as .LOCK or .WAIT. These functions are executed at PR3 and when complete, they return to RTI3. Note that the calling priority in RTI3 will again be PR0 (SVC LEVEL) so the job may be dumped. However, it is likely that the QSCHED bit has not been set and control will soon get back to the same job. (3) USERIO Call The user requested an I/O transfer from disk or device. There are 3 possible paths: (a) The user has requested an illegal transfer. The user may have attempted to operate on an unopened device or file or he may have attempted an uncool like reading from the line printer. In either case, he will be given an error 30 code and control will be given to RTI3. The calling priority will again be level 0. (b) The user has requested a file transfer (I/O to or from disk) control will pass to the file service routine (FILSER) which will set up the parameters for the transfer. Control will then pass to DSKGO which will queue the transfer on the list of things the disk is to do (if this is the first item in the queue, it will be started). The job is saved and control passes to the SCHED to find something else to do. (c) The user has requested a device transfer from a non-file oriented device. Control will pass to the appropriate device service routine for the device in question. The service routine will attempt to complete the transfer based on the contents of its monitor chain buffers. If it completes the transfer, it returns through RTI3. If it cannot complete the transfer without doing some physical device transfers, it will fire up the device interrupt handler to do the physical transfer. Since it does not want to wait on the device to complete the transfer, it simply backs up the user PC by two (all I/O calls are one word instructions) so that the user will re-execute the call, sets the appropriate blockage bit in JBWAIT, saves the job, and branches to RTI3. Note that serial I/O calls are structured such that at each call to DEVSER, the transfer may be resumed from the point at which it left off previously, thus a single I/O request can cause multiple physical transfers. 31 The common interrupt return RTI3 is the basic dispatch point for all system functions. RTI3 dispatches control based on the CPU priority at the time of the interrupt which transferred control to it and the contents of L3QUE. a. CPU Priority > 2 or L3QUE=0 Control returns to the interrupted process. Note that even though interrupts may be nested, since all interrupt service routines run at priority 3 or higher control will return to the previous interrupt service. Note also that SAVJOB (which is never executed by any nested interrupt) switches to NULJOB by making it look like NULJOB was the interrupted process — not the user. b. CPU Priority < 2 and QSCHED=1 in L3QUE Control passes to the scheduler which attempts to find a job to run. SCHED has three alternatives: (1) The next job to be run is the current job. Control is simply returned to RTI3 and the scheduler has no effect. (2) The next job to be run is not the current job. If the current job is NULJOB, then control passes to RESJOB to establish the new current job. If the current job is not NULJOB, then the flag JFSTOP is set so that the job will be stopped at the next system tick. Control can then return to SCHED and the new job will be established. In either case, control returns through RTI3. (3) The next job is non-resident. Control will pass from SCHED to the swap processor (SCARAB) which will attempt to swap the next job into core. SWAPAR will initiate any disk transfer that is necessary (it may be necessary to swap some core resident jobs out first) through DSKGO and then return through RTI3. 32 c. CPU Priority < 2 and QSWAP=1 in L3QUE SWPRET is the return point for a previous call to SWAPAR which is queued only by a disk completion interrupt for a transfer initiated by a job swap. SWPRET will check if all swaps asked for by SWAPAR are complete, if so, it will return to scheduler. If not, it will choose the next swap, fire it up, and return through RTI3. d. CPU Priority < 2 and QFIB=1 in L3QUE FIPRET is the return point for the file processor. It will check for a successful disk transfer and then return to FIP at the point from which the previous operation left off. e. CPU Priority < 2 and $FILE=1 in L3QUE FILRET is the return point for FILSER requests. It will check for a successful transfer, relieve the disk blockage in JBSTAT for the appropriate job, and return through RTI3. 33 III. THE ETS FILING SYSTEM The ETS filing system is a complete management package for the disk file storage. Because of severe space limitations, it does not encompass DECtape or other devices as yet. All files in ETS consist of logically sequential blocks of 256 words each, numbered in order beginning with zero. Through the use of directories containing retrieval links and a mapping scheme from logical to physical blocks, ETS may dynamically allocate/ deallocate blocks for any file without causing garbage collection problems. The ETS file processor (FIP) is a separate subsystem from the monitor which operates asychronously from the monitor and services all users one at a time on a first come-first served basis. FIP maintains its own stack and switches to it whenever it is busy and switches back to the current stack when it either completes processing or has to wait on the disk. Only a small part of the FIP code is core-resident. The majority of it is disk resident and is brought into a special buffer (FIPBUF) when it is to be used. The code buffer is also 256 words long so each block of non-resident code fits nicely into a disk block. Similarly, FIP maintains a 256 data buffer (FIBUF) which it uses to store disk blocks which it needs to access on a temporary basis (e.g., a user directory). 3U A. File Organization This section will discuss the data structure used to control the filing system. 1. Directory Structure In order to facilitate protection and isolation of different user groups, ETS classifies users according to a "project" and according to "programmer" within a project. Thus each user may be assigned his own "project-programmer number" (PPN) which is a unique identifier of a special directory containing his files. Since file names need to be unique only within a particular PEN, this allows programmers to name files without worrying whether that name is used by some other programmer. Associated with each PPN is a unique directory called a User File Directory (UFD) which contains information on files belonging to a particular user. The system then maintains a Master File Directory (MFD) which lists all UFD's. Each file has associated with it a number of 8-word blocks which contain all the information necessary for describing and finding any part of that file. The first of these is a name block which (obviously) contains the file name as well as pointers to other information. The second is the accounting block whose use is again obvious. The third is a retrieval block which will be explained later, a. Master File Directory The Master File Directory is structured much like the User File Directory; however, instead of containing pointers to individual files, it contains pointers and information about the User File Directory associated with each project programmer number (PPN) known to the system. The first entry in the Master File Directory is the name block for PPN [1,1] (see Figure ni.l). The first entry in this name Header Block 35 User [1,1] Name Block User r 1.21 *0 MLNK N ) 2 MFROJ MPROG Name Block 1+ MPSWD 6 10 12 11+ MM MAA 16 1 /< MUFD '{ }• User [X,X] Accounting Block 2 MCPU 1+ MCON 6 MDVT MKCT 12 MSEGO 11+ MSEGP 16 { Accounting Block Name Block MAA MUFD A Accounting Block Figure III.l Master File Directory Structure 36 Name Block MLNK=0 MPR0G=2 MPR0J=3 MPSWD=if MAA=lJ+ MUFD=l6 Link to next name block 8-bit programmer group # 8-bit project number (a group is a suborder of project) 6-character password which is used when logging in under a specific Project-Programmer # Pointer to Accounting Block (Actual Logic-Address) Pointer to UFD header block (Physical Disk Segment Number) Accounting Block MCPU=2 ;Accumulated CPU time under account MCON=^ ;Accumulated connect time MDVT=6 ;Accumulated device (peripheral) time MKCT=10 Accumulated KCT's (KCT = 100 msec) MSEG0=12 ;# segments owned by user MSEGP=1^ ;# segments user is permitted to own. Figure III.l (continued) 37 block, MLNK, is a pointer to the name block for PPN [1,2]. In this name block is also the PPN which is associated with this block; in this case, [1,1] as well as a six -character password uniquely- associated with the PPN. The name block contains a pointer, MAA, to an accounting block which gives information on the use of the system by users which are logged in under this PPN. This name block also contains a pointer, MUFD, which points to the header block associated with the user file directory for project programmer [1,1]. For every PPN in the system there is a unique name block in the Master File Directory which gives the PPN as well as the password and pointers to an accounting block and the UFD header block for that particular PPN. The first name block in the Master File Directory would be associated with PPN [1,1]. The second entry will be associated with PPN [1,2]. After that, the pointers to the next name block go to successive PPN's in an arbitrary order. The accounting block in the Master File Directory provides a convenient place for keeping track of information relative to any given PPN. In the accounting block are words which will give the total accumulated CPU time under that account (MCPU), the accumulated connect time for that account (MCON), the accumulated device time (MDVT), the accumulated system ticks (KCT), the number of segments owned by the user (MSEGO), and the maximum number of segments the PPN is permitted to own (MSEGP). b. User File Directory A User File Directory begins with a header block which is pointed to by the entry for that PPN in the Master File Directory. This header block points to the first of a linked list of name blocks for the 38 individual files associated with that PPN (see figure III.2). Every time a file is created, a name block is created in the User File Directory and linked into the list of active files in that directory. Also, an accounting block is created as well as the number of retrieval blocks necessary to allow the individual segments of disk related to that file to be located. As is shown in figure III. 2 the first entry in each name block is a pointer to the name block associated with the next file. The last file in the list will have a link word of 0. The second, third, and fourth word of a file give the file name in RAD50. The first six characters is the name of the file. The next three characters is an extension. The next word gives the status of the file and protection associated with that file. The 6th word is an access count which tells the number of users currently logged in on that file. The last two words in the name block are pointers; first, to an accounting block for that file and second, to the first of a linked list of retrieval blocks for that file. The accounting block for a file will provide such information as the date of the last access, the number of segments in the file, and the date and time the file was created. The retrieval block contains in its first word a pointer to the next retrieval block in the chain or a if this is the last retrieval block in the chain. The next words in a given block are the disk segments associated with that file. Since a file is a logically contiguous stream of information, the segments are logically contiguous beginning with the first segment (which is pointed to by the second word of the first retrieval block). The last word of the first retrieval block points to segment 7 while the first word of the 2nd retrieval block points to the 8th segment of the file. This continues to the end of the file. Note that while the UFD Header 39 r Name Block ^0 ULNK 2 UNAM k 6 10 UFROT US TAT 12 UACNT Ik UAA 16 UAR 2 1* 6 10 12 lk\ 16 Accounting Block W UDLA USIZ UDC UTC Name Block ULNK UAA UAR \ Accounting Block Retrieval Block S. Name Block ULNK UAA UAR Accounting Block Retrieval Block s 1st Retrieval Block 2nd Retrieval Block nth Retrieval Block URLNK > URLNK > 1st Segment 8th Segment 7th Segment l^th Segment Figure III- 2 User File Directory Structure ho Name Block ULNK=0 UNAM=2 USTAT UPR0T=11 UACT=12 UAA=llj- UAR=l6 ;Link to next name block ;3 words FILNAM.EXT ; Status Byte 200 if to be deleted 100 if UFD protection Code lj-0 - Write Protect from World 20 - Read Protect from World 10 - Write Protect from Group k - Read Protect from Group 2 - Write Protect from Self 1 - Read Protect from Self ;Access Count ; Pointer to Accounting Block (Logical Address) ; Pointer to Retrieval Block (Logical Address) Accounting Block UDLA=2 ;Date of last access USIZ=4 ;# segments in file UDC=6 ;Date file was created UTC=10 ;Time file was created Retrieval Block URLNK=0 ;Link to next retrieval block Figure III. 2 (continued) kl file is logically continuous in terms of these retrieval blocks, on disk it is any arbitrary set of segments of 256 words. c. Directory Length Both the Master File Directory and the User File Directory may consist of up to eight physical disk segments of 256 words each. The last eight words in each disk segment provides a list, in order, of the physical segment numbers of all segments in this directory. The eight word header block of the Master File Directory is physically the first eight words of the first segment of the disk file area. Thus, the system finds the Master File Directory by looking in the header block in the first segment. Both the Master File Directory which is PEN [1,1] and the library which is PFN [1,2] reside somewhere in the first physical disk segment. d. File Contents FIP does not support any formatted files, nor does it maintain any type of parity information about the file itself. It does, however, support file name extensions which ETS' system software interprets to provide file types. 2. File Control Blocks In any filing system one would like to minimize the overhead in doing device transfers. Since ETS makes many demands on the disk, a scheme to minimize the number of disk transfers is very important. This usually implies keeping much information in core — another resource in which ETS is severely limited. The File Control Block (FCB) is a compromise which tries to minimize the number of disk transfers used to find pointers to blocks while minimizing the amount of core storage used for directories and retrieval lists. k2 Any time a user opens a file, a FCB (see figure III. 3) is set up for that file which will enable the user to operate on the file without excessive disk transfers. Since the file has a linked list of retrieval blocks pointing to its segments, we keep a copy of one retrieval block (called a WINDOW) in the FCB. The variable FCFLI gives the logical segment number of the first block in the current window. Thus if the block we wish to read/write lies in the interval [FCFLI, FCFLI+6], we simply subtract FCFLI from the block we want and use this as an index into the window to get immediately the disk segment # of the block we want. If the block we want does not lie in [FCFLI, FCFU+6] we are forced to "turn a window." Since we are normally operating in a forward sequential manner, FCWED, which contains the UFD address of the next window and FCPW which contains the disk address of the current window allow us to get a new window with normally only one additional disk access (see figure III. 10 . If we are not operating sequentially, and wish to move forward, we start from our present position and continue turning windows until we reach the window containing the block we want. If we want to move backwards, we must return to the name block which contains a pointer to the first retrieval block and search forward for the block we want. The address of any file control block is kept in an I/O slot in the I/O block (see section II. B). Some file operations require that file be open (e.g., Protect, Rename) while some require that they not be open (e.g., Open, Create). Open files are referred to by their channel index (location of FCB pointer in IOB) while closed or non-existent files are referred to by name. *o FCSTS FCTYPE FCASN FCBC FCSIZ FCNLB FCFLI FCFNB FCF¥ FCETC FCWND FCSEG1 FCSEG2 FCSEG3 FCSEGif FCSEG5 FCSEG6 FCSEG7 "N > Control Information > Current Retrieval Window J FCTYPE = FCSTS = 1 FCBC = 2 FCASN = 3 FCSIZ = k FCSIZ = 6 FCFLI = 10 FCFNB = 12 FCPW = Ik FCETC = 16 FCWND = 20 FCSEG1 = 22 FCSEGi = 36 I/O handler index - disk = Status bits for file Bit 1=1 User is not owner of file Bit 2=1 User may not read file Bit 3=1 User may not write file Block count for current transfer (He can only get 1 "block at a time unless he does a direct access read/write) Location of file name block in UFD (word offset) # of segments in file Logical block number of next block to read/write First logical block in window Disk physical segment containing name block Disk physical segment containing current window Miscellaneous word. Users doing a direct read/write put current memory address here UFD address of next retrieval window Physical segment corresponding to FCFLI Physical segment corresponding to FCFLI +i Figure III. 3 File Control Block kk FCB UFD Block FCFW FCWND Current Window Next Window UFD Descriptor FCPW contains the physical segment number of the disk block which contains the current window. This block is a UFD block belonging to the User File Directory in which the file is listed. FCWWD is a "UFD Address" i.e., the low byte of FCWND is an offset in words from the beginning of a UFD block to the start of the particular retrieval window. The upper byte contains a number in [0,7] *2 which is the particular UFD block containing the window. This is used as an index in the last 8 words (UFD descriptor) of any UFD block which contains the segment # of the UFD block in question. If the new block is the same as the current block (the normal occurrence) no additional disk accesses are necessary. If not, one additional access is necessary to get to the block containing the new retrieval window. Figure III. 4 UFD Window Turn h5 B. File Processor 1. Basic Design As is shown in figure III #5* FIP contains a major loop such that each function executed requires one pass around the loop. Since FIP can do only one thing at a time, all function requests are placed in a queue and FIP will cycle through them picking up a new request each time. FIP consists of both core resident and disk resident code. Before FIP attempts to execute a new function, it checks to see if the function is in core. If it is not in core, FIP must read it into a special buffer (FIPBUF) before execution. FIP also has a second buffer (FIBUF) for use in storing data brought in from disk. The FIP processor is self-sufficient in the sense that its only input is in the form of a File Request Queue Block (FIRQB) set up by the caller. It needs no device I/O other than disk, and uses no system resources other than CPU time and a few system buffers. It maintains its own stack which it switches to when running and switches back to the current stack when stopping (either for process completion or to wait on a disk transfer). With the exception of the EMT processor and RTI3, the system is not conscious of the presence of FIP. Figure III. 6 shows the control data which FIP uses to define its own state. Anytime FIP is running, it switches to a private stack. This is necessary to allow FIP to stop itself for disk transfers and to restart when they are complete, without worrying about the contents of its stack. Since the processing of each function is an independent task, when FIP completes a function, it throws away the contents of its stack; thus, it does not always worry about popping the stack as often as pushing. This is primarily k6 User FIP Request 2^L. Put Job to Sleep Q, Request in FIQUE Yes Return Through RTI3 Unqueue Next Request — Extract Function Yes L± Process Request Set Wake Bit for Job in JBSTAT Yes Return to System Through RTIJT No No Read Function into FIPBUF Figure III. 5 File Processor Flow Diagram ^7 Queue head for list of requests waiting for service. Buffer status of FIBUF. If the buffer is altered from what was "brought in from disk, it must he written hack to disk. = unaltered / altered Project -programmer number of job FIP is currently servicing. Address of job's first job data block (JDB). Non-resident code segment in FIPBUF (byte data). Logical segment index (*2) in FIBUF. A file directory (UFD or MFD) may consist of up to 8 logical segments. Physical disk segment in FIBUF. # of free (unallocated) segments in disk file area. Cyclic pointer to disk bit map (SAT = Surface Allocation Table). Segment number corresponding to SAT (SATPTR). Current FIP stack pointer — valid when stack is system or user stack. Current system stack pointer — valid when stack is FIP stack. Disk parameter block for only transfers required by FIP. Routine to search a directory for a file name or UFD. Called by routines who need to ascertain the existence of a file or UFD. Routine to read the start block of a UFD into core. Routine to allocate a disk block and add it to a file by updating the retrieval blocks. Routine to delete a file and return its blocks to the system. Routine to pick up a FCB and IOB pointer given a FIRQB pointer. Routine to get the name block of a file into core and to construct an absolute pointer to it. Routine to convert an absolute address into a logical UFD address. Routine to allocate a disk segment and mark it in bit map. Routine to deallocate a disk segment. Routine to read a segment into FIBUF. Routine to write FIBUF back to disk if FIBSTA ^ 0. Routine to search for an empty 8-word block in a directory. Routine to read segment given by UFD link into buffer and set up absolute address. Figure III. 6 FIP Control Information and Utility Routines 48 used in error exits where FIP simply traps to the error handler. Note that interrupts may occur while on the FIP stack, but since FIP runs at priority 3, any interrupts will return control when their processing is complete. 2. Support Routines As mentioned before, FIP consists of both resident and non-resident code. The criteria for determining whether a routine is to be resident or non-resident is the interdependence of routines. A routine may be non-resident only if it is not called by routines other than the non-resident code handler or other routines which reside in the same non-resident block. The resident code generally consists of utility type routines — disk allocation routine, address mapping routines, segment reading routines, etc. Figure III. 7 gives a list of many of the FIP utility routines and their functions. C. File Requests FIP uses a standard format for all file requests. A user who wishes service from FIP must allocte a system buffer (called a FIRQB) and supply in it the appropriate parameters (see figure III. 7). He then executes an EMT (CALFIP=1C4050) to call the file processor. At the time of the call, Rk points absolutely to the FIRQB. On return, the buffer may or may not be returned depending on the function used. FIP supports the following functions: 1. EXTFQ (=0) - Extend the file open on a channel given in FQFIL by an amount specified in FQSIZ. 2. WTEFQ (=2) - Turn a window on the given file (FQFIL) to include the block pointed to by FCNLB. 3. DELFQ (=*0 - Delete the open file given by FQJTL. k. CLSFQ (=6) - Close an open file, the FCB is returned to the system. ^9 5. OFNFQ ( :=io) 6. CREFQ ( :=i2) 7- RENFQ ( =uo 8. LLNFQ ( =16) 9- BYEFQ ( '=20) .0. DIRFQ < =22) 11. FROFQ 12 . PASFQ 13. ERRFQ ( '=30) Ik. OPTEST ( =32) 15- LOAFQ ( '=3h) 16. ASSFQ ( =36) IT. DEAFQ ( :=i+o) 18. RSTFQ ( \=^2) 19. DALFQ ( ;=w 20. CSIFQ ( \=hG) 21. SWIFQ ( :=50) 22 . FNDIL - Open the file at FQNAM1 on the channel in FQFIL. - Create a file by name FQNAM1 of length FQSIZ-- default size is one block. - Rename the file at FQNAM1 to the name given in FQNAM2. - Log a user in. The PFN is given in FQPFN1, the password is given in FQNAM1. - Log a user out. - Return directory information on the nth logical entry (specified by the word at FQSIZ) in the directory called in FQPPN1. =2*0 - Set protection on file at FQFIL to that given in FQPROT. =26) - Create a new user account. Current user must be logged in under account [ 1, 1] . The new pro j -prog is given in FQPPN1 and the password is given in FQNAKL. Return an error message, specified by number in FQERNO, from the error file. - Parse an instruction into its component parts. - System loader- -loads file given by FQFIL in user area with an offset given by FQSTRT. User must execute an EMT .LOCK before calling FIP. - Assign a device — presently disabled. - Deassign a device — presently disabled. - Close all I/O channels except user teletype. - Deassign all devices — presently unnecessary since assign is not in use. - Parse a file name in the form of DEV:FILE.EXT[N,M] and pack into appropriate FIRQB positions. - Parse a string of switches and parameters and return a buffer of results. String is pointed to by FQPTR and is of length FQLEN. ^52) - Routine to determine whether or not a file/device exists and if so whether or not it is open and the channel on which it is open. 50 Name Value Length (bytes) FQQQ 2 FQJOB 2 1 FQFUN 3 1 FQFIL k 1 FQERNO k 2 FQSIZ 5 1 FQFROT 5 1 FQPPN1 6 2 FQjmML 10 6 FQPPN2 16 2 FQNAM2 20 6 FQBLCK 22 2 FQCKSM 2^ 2 FQSTRT 26 2 FOJ)EV 30 2 FQJJEVN 32 2 FQLEN 3^ 2 FQPTR 36 2 Purpose Queue word for chaining requests. Job § issuing request (#2). Function requested. Channel index. Error or message # requested from file. Size of file to be created or number of segments to extend file. New protection code. Proj-prog number of UFD desired. File name and extension in RAD50. Proj-prog number of second UFD. File name and extension for second file. Number of absolute loader blocks loaded. Number of checksum errors encountered. Offset from beginning of user area to "relative 0" of file to be loaded. RAJJ50 device name. RAD50 device number. length of string to be parsed. Absolute pointer to buffer containing source string to be parsed — string is in chained set of system buffers. (Note that FQJ0B and FQFUN must always be supplied — all other parameters need be supplied when actually needed. ) Figure III. 7 FIRQB Structure 51 D. Errors and Protection In order to help insure the integrity of disk files, FIP does extensive error and protection checking in file operations. A user who wishes to modify a file must be write enabled on the file. ETS supports three levels of protection (see figure III. 8). When a user attempts to open a file, the OPEN processor checks the protection and sets protection bits in the FCB accordingly. A file marked protect from self for both read and write can only be opened by its owner. Anytime FIP finds an error, it will return an error code in the third word of the job data block (JDIOST). All EMT's below EMT 50 are FIP error calls. These must be used by FIP only, and they provide a means through which FIP can abort a function. Figure III. 9 gives a list of the errors and their meanings. 52 Code Bit kO 20 10 k 2 1 Meaning Write protect from world. Read protect from world. Write protect from group. Read protect from group. Write protect from self. Read protect from self. Note: Self implies other users with same PEN as owner. Group implies users with same 8-bit project #. World implies all others. Figure III. 8 File Protection Codes 53 Error Name Error Number BADCMD 1 BADDIR 2 BADNAM k NOTFND 6 INUSE 10 NOROOM 12 NOSUCH Ik NOTCLS 16 NOTAVL 20 NOTOPN 2Z PRVIOL 2h EOF 26 ABORT 30 DATERR 32 HNGDEV 3h NOLOAD 35 CKSMER 36 OUTRNG 37 Meaning Invalid command. Directory screwed up. Badly formed file name. File not found. File of same name is in use. Directory is full or disk is full. File or UFD does not exist. Can't open already open channel. Device not available to user. Trying to operate on unopened file/ device. Protection violation. End of file on read/write. Operation aborted. Data error on device. Hung device for job. No load address specified on object file. Checksum error in loader. User area not large enough. Figure III. 9 FIP Error Calls ^ IV. I/O SUBSYSTEM A. Basic Principles 1. Data Representation ETS supports two types of data representation: Seven-bit ASCII is used for the internal representation of character or string data. With the exception of cards, it is also the representation of such data on off-line storage mediums. Cards use the EBCDIC character set and are translated to ASCII by the card reader handler. Character data is handled as a stream of lines or blocks. Data which is not specifically ASCII is called binary. Binary data is full eight -bit character representation and has no preas signed meaning for any character or sequence. Consequently, when handling binary data, we depend on the device to inform us when we have reached the end of the text. 2. Data Transfers There are two modes of data transfer: Line-oriented transfers may be used when the data is in ASCII form. This type of transfer is used exclusively from the teletype when a program is inputting data. In a line-oriented read, the end of the transfer is determined by either the occurrence of a terminal character such as a carriage return, or the fulfillment of the maximum requested transfer length. 55 Block-oriented transfers are the normal mode and associate with each transfer a 'transfer length' which must be fulfilled in order to terminate the operation. When transferring to/from disk, block lengths are fixed by the system at 256 words. For other devices, the block length may be set by the user. 3. Device Independence In order to provide a reasonable degree of user convenience, ETS attempts to provide a measure of device independence. Device I/O requires the user to perform three basic steps. First, he must request the use of a device or file; he does this by calling the file processor to 'open' a file or device for him. Second, he must request the actual read/writes. Third, he returns the file/device to the system by again calling the file processor to close it for him. ETS uses three basic mechanisms to provide this device independence : When a file or device is opened, it is associated with the user job by assigning it to a 'channel' or 'slot'. Each gob may have up to eight active channels. Once a device is opened on a channel, the user may refer to it via the channel number and he needs only a vague idea of what type of device he is connected with. When performing I/O, a user must provide the system with a transfer control block (XRB) which contains the parameters to be used in the transfer of data. This control block contains only a channel number, a pointer to a buffer and transfer count, and possibly a few parameters. In general, the user may use the same XRB to control more than one device. Each of the ETS I/O handlers consists of two co-routines. The first is the device service routine which is responsible for the 56 communication between the user and the system. The device service routines (in the case of input) will take characters from system buffers and transfer them to the user. If the buffers become empty, the service routine will initiate the device interrupt service in order to refill the buffers. There is a specific interrupt handler for each device which is capable of catering to the special needs of that device. The device service routine can then worry about taking the data as returned by the interrupt handler and converting it to the standard system format. B. Data Structures and Control Routines 1. I/O Control Structure The basic control structure for an I/O device is the device data block for everything except disk, and the file control block for the disk. When a user opens a file/device, a pointer to the DDB/FCB is placed in one of his channels. In the case of devices, the user's job number is also placed in the DDB so that his job control blocks may be located if the DDB address is known. The file control block is described in section III. A. 2. The device data block has an organization which is unique to the particular device. All DDB's have common headers which provide type and status codes and the job number of the owning job. Second, DDB's contain the pointers which control the monitor chain buffers for that device. Third, DDB's contain any special control information required for the proper operation of a device. (figure IV. 1 is the DDB for the line printer.) 2. Character Handling — Monitor Chain Buffers With the exception of the disk, all devices operate on a character by character basis, i.e., the interrupt handlers get an interrupt 57 LPTSTS LPHAND LPJBNO LPTIME LPVERT LPHORZ LPTFP LPTFC LPTEP LPTEC LPTBC LPTAB LPCNT LPHAND = LPTSTS = 1 LPJBNO = 2 LPTIME = k LPHORZ = 6 LPVERT = 7 LPTFP = 10 LPTFC = 12 LPTEP =lk LPTEC =16 LPTBC =20 LPCNT =36 ; Handler index ; Status ; Owner job number ;Time device assigned ;Horizontal line position ;Vertical page position ; Chain buffer fill pointer ; Chain buffer fill count ; Chain buffer empty pointer ; Chain buffer empty count ; Chain buffer available buffer count ;Init count Figure IV. 1 Line Printer Device Data Block 58 for each character transferred. In order to simplify the reading and writing from the user programs, we want to transfer blocks or strings of characters to the device service routines. This allows us to swap the user programs out for the duration of the transfer. We implement this buffering through the use of the monitor chain buffers. Each monitor chain buffer requires five words of control in the DDB. The first four words simply implement a first-in first-out queue while the fifth gives the maximum size of the queue. The queue is implemented as a set of buffers which are chained together through their first words. As one buffer is filled, another is allocated and added into the chain. When a buffer is emptied, it is returned to the system. The chain buffer discipline is maintained by two routines called FETCH and STORE. Since either the filling or the emptying (depending on the type of device) of the buffers is under interrupt control and cannot therefore be anticipated, it is necessary to provide interlocks between FETCH and STORE to prevent misuse of the pointers. The simplest interlock is to have no overlap at all between the routines. This is done in ETS by running both routines at processor priority seven. 3. Transfer Control Blocks User programs control the transfer of data by means of a transfer control block (XRB) . The XRB tells the system the address and length of the user's buffers as well as the channel to which the I/O is to take place (see figure II. 5) • When a user is reading from a device, he must give the system a buffer address as well as a maximum length for the transfer. In the case of a block-oriented transfer (e.g., card reader), the system will continue reading until it fills the user buffer unless there is an error 59 or end-of-file during the operation. In the case of a line-oriented read, the system will transfer characters until an end-of-line is encountered or the buffer is full, whichever occurs first. When writing to a device, the system will transfer the exact amount given by the user in the byte count field of the XRB unless an error occurs. In the case of operations to/ from disk, all transfers are exactly 256 words. In actually executing the transfer, the system may not be able to fulfill the entire request at one time; consequently, it will transfer the maximum amount possible and put the job to sleep while the system performs physical I/O to catch up with the job. In order to pick up from the point at which this logical transfer leaves off, the system backs up the user's program counter before putting him to sleep so that when the user is awakened, he will immediately re-execute the transfer. The system modifies the XRB pointers during the transfer so that at any time, they show exactly how much information remains to be transferred. It should be noted that the system may be able to complete the logical transfer of information between the user and the system buffers before it can complete the physical transfer. Even though the actual physical transfer may not be complete, the user program is allowed to continue running. Should it then execute another I/O transfer, it is possible that that operation will complete before the first (e.g., write to TTY followed by a read from the TTY in which a message has already been typed). This effect allows full duplex communication between a user program and its devices. This can in turn cause such things as the sequence in which typing appears on a teletype to disagree with the order in which the program performed reads and writes; however, it will not affect the execution of the user program. 6o Since the execution of a read/write may take a large amount of real time but virtually no CPU time, the system may decide to swap a user out while it catches up with some physical I/O. When it swaps the user back to core, it may relocate him, consequently, all XRB pointers are user- job relative. h. Hardware Priority Arbitration In order to insure that devices may interrupt and be serviced in an amount of time commensurate with their need, they are assigned to different levels of hardware interrupt. Since the card reader has a fixed amount of time in which it must be serviced, it is given the highest level in the system. Similarly, the teletypes, line printer, etc. are not sensitive to time and are given lower levels. Figure IV. 2 gives the hardware priority of each of the devices on the system. Also shown is the processor priority which is used by the interrupt service for each of the devices. C. I/O Characteristics of Individual Devices 1. Disk I/O to/ from the disk is in the form of files. As described in chapter HI, files are sets of logically contiguous blocks with 256 words/block. All transfers involving the disk are of length 256 words. Successive transfers to/from a particular file advance a system pointer to the next block in the file thus giving the effect of reading a file sequentially. This is what a user normally wishes to do and is thus the default action; however, users may desire to transfer specific blocks of a file (e.g., each block contains a different segment of non-resident code). 61 Device Card Reader Clock Disk Line Printer Papertape Reader Papertape Punch Teletype Hardware Interrupt Level 6 5 k h k k Interrupt Service Priority 6 (drops to 5 after character in tumble -table) 5 5 k k k h Figure IV. 2 Device Priority Assignments 62 The system provides an EMT routine called. .FIND which may be used to position a file at any desired position. By executing a .FIND followed by a read/write the user may transfer any part of the file he desires. Should a user attempt to transfer to a block which does not exist, the system will generate an end-of-file error. The user may then call a system function to extend the file and try again. 2. Papertape Reader/ Punch The papertape reader/punch is the simplest of the I/O devices. All transfers are block oriented and will complete the transfer unless the reader or punch runs out of tape. No validating of the data is done by the system. 3. Card Reader The card reader is possibly the most complicated of the devices on the system, both from the standpoint of the data manipulation it does, as well as the control of the card reader by the system. The card reader accepts parameters from the user XRB which tell it the type of data to be read. The user may read EBCDIC as punched on an IBM 029 keypunch in which case the driver will convert it to the equivalent ASCII representations, or he may read in binary mode in which case the card reader will transfer directly the top eight rows of a card column as one byte. This mode is useful for reading the absolute loader format decks produced by the PAL-11 assembler on the IBM 360. When reading EBCDIC cards, the user may also specify card margins in order to read only those columns in which he is interested. The card reader Interrupt driver must be able to respond to interrupts at the rate of one interrupt every 800 microseconds. In order 63 to allow a reasonable safety factor in the time requirements, characters are placed in a 16 word tumble-table as they are received. Until the character is actually in the table, interrupts are not allowed, which takes approximately lOCu sees after which the reader is able to accept another interrupt. The characters are removed from the tumble-table in order, the desired translation is performed and the translated character is stored in the monitor chain buffers. By using this tumble-table, we need only insure that the average processing time for a character is less than 800u sees rather than the maximum time (the worst case max time is approximately 800u sees). The interrupt driver also attempts to save time when in EBCDIC mode by doing blank suppression. When a blank is received, it is simply counted. When the next non-blank character is received, the current number of blanks is stored (as a negative number to avoid confusion with regular characters which are always positive) followed by the character. The card reader to user interface will then expand the blank counts back into actual characters. This technique also makes trailing blank suppression trivial since all training blanks will be contained in a single byte which may be ignored. k. Line Printer The line printer looks somewhat like the papertape punch except that it does some character interpretation in order to provide formatting ability. The driver interprets tabs, line feeds, carriage returns, and form feeds. For the user, output to the line printer requires only an XRB with no parameters. The only consideration to worry about in the line printer interrupt driver is the speed with which the line printer may request interrupts. The line printer buffers internally up to twenty-four characters 6k and consequently may request them as fast as the system is able to supply them; this means that the interrupt handler must run at a high enough priority to block subsequent interrupts until it is ready for them. It should be noted that unlike the card reader, the line printer will wait indefinitely for the next character. 5. Teletype The only complicated part of the teletype I/O drivers comes from the fact that the teletype functions as both an I/O device and as a job control device. Consequently, characters received from the keyboard must be checked to determine their meaning. In general, characters are interpreted as simple line input which looks like any other I/O device. The system does check each character input against a list of 'control characters' to see if it requires special action. This is accomplished by using a system routine called TTSIVE which will check if a character is between a given set of limits; if not, it will compare it against a list of special characters and call a corresponding service routine if a match is found. The teletype keyboard and printer operate in full duplex mode which means that a user may be typing in one message on the keyboard while another message is printing on the printer. Since the printer will print characters as they are received by its service routine and placed in the monitor chain buffers, it is possible to have the echoes from the keyboard interspersed with the output from a user program. D. Error Recovery ETS does not attempt sophisticated error recovery. In general, ETS will terminate the current operation as quickly and neatly as possible and return an error code to the user program. 65 In the case of the disk, ETS -will re-attempt the transfer up to five times before returning the error. In the case of the card reader, the current transfer will be stopped and the eject command will be issued for the current card. This works well for source data since the user program can simply discard everything since the last line ended. The user may then reinsert the last card and re-execute the transfer. Things are somewhat messy when doing binary transfers; the best solution is to simply start all over. When an error occurs, ETS only returns the code to the appropriate user; it is the program's responsibility to type out the message if that is the desired action. 66 V. COMMAND STRING INTERPRETER The Command String Interpreter is probably the simplest part of the ETS monitor. The monitor assumes that a user always has a job -which is capable of running. When he first enters a command, he has not chosen what he wants to do, so the system connects him with what is in effect a default job which is the Command String Interpreter. The Command String Interpreter simply provides the user with a minimum set of operations to allow him to connect himself with the system and to initiate one of the system programs. These operations are: Login . When a user first sits down at a console, he must identify himself to the system. This identification will establish whether or not he is a valid user of the system, and if so, allow the system to locate the appropriate user file directory. Until he successfully logs in, the system will not honor any other requests a user may make. Time and Date . The system provides commands which return the present time and date to the user. Core . When the system first establishes the presence of a new user, it will allocate a default region of 102^ words of core. Since this is insufficient for most programs, the Command String Interpreter provides a command through which a user may request a new region size. This command is useful for either increasing or decreasing a user's region size. Run . Since all useful work by a user is accomplished using one oi the system programs, the RUN command is used to initiate the execution of 67 one of the system packages. This command will first of all check that the requested job is one of the system library programs (users may not run their own programs directly). It will then close any I/O channels which the user may have left open from previous operations and call the system loader to load the specified program. If the program is loaded successfully, control will be transferred directly from the Co mman d String Interpreter to the specified program. Logout . When a user has completed his work session, he tells the system of his desire to quit through the logout command. The system will then tidy up after the user by making sure that all resources have been returned and terminate the job. Other operations which are not actually part of the Command String Interpreter but are used to control the execution of a job are the teletype characters which receive special processing by the teletype interrupt handlers : tC (Called Control C and is typed by holding down the CNTL key and striking C) . This command causes the system to set the abort flag on the user's job. The next time the scheduler selects this job, it will refresh the stack and return control to the Command String Interpreter. tQUIT (CNTL Q) . This command is the normal means of terminating the execution of a system job. The system will set a flag for the user program. When the program recognizes the flag, it may tidy up after itself and then return control to the system. This is much better than tC since the program may close files and write out information which the system would normally be unable to recover. 68 tV (CNTL V) . This works in a manner similar to tQUIT except that it does not request that the program terminate. It is normally used to request that a program return to its own command mode as the user has made some type of error in his input (e.g., the program is in an infinite loop because of a user input). tQ (CNTL 0) . This is a system command which will cause the termination of printing of programmed output on the teletype. If a user performs a function which causes an unexpectedly large volume of output to be printed, he may ignore it by using tO. The effect of this command is terminated by a TTY reset or the typing of a carriage return. t B (CNTL B) . This is a useful device for preventing the echoing of code words. The command operates a toggle switch (each occurrence changes the state of the switch). When the switch is on, nothing that is typed is echoed on the TTY printer. The Command String Interpreter is simply an always resident reentrant job. It is composed of a central loop (NEWGUY) which will accept a string from the teletype and use the first two characters of the string as a command. Based on those characters, it will dispatch to the appropriate routine to process the command. The major difference between the CSI and a normal program is the way it does I/O. The Command String Interpreter performs its I/O at a much lower level than the normal case. This is necessary to allow it to pick up only a part of a line at a time from the chain buffers. In general, each part of the Command String Interpreter picks up only those characters which it needs to do its specific processing. The Command String Interpreter also provides a central error routine which may be called from any program. This routine will get the 69 specified message from the system message file and type it out on the teletype. Since the messages are stored on disk, this provides a convenient means having a number of messages available without using excessive storage to keep them. Figure V.l gives the command format and a list of accepted commands. TO Command Interpretation HEllo 2 7 PASWRD Size 3 Time DAte RUn EDETS MEssage 23 BYe Log onto system under user code [2,7] which has code password PASWRD Request the allocation of 3K (3072 10 ) words of core Request for the present time Request for today's date Request to load and execute the system editor Asks the system to give the meaning of message #23 Log out, user done (lower case letters need not be typed) Figure V.l System Commands 71 VI. PERFORMANCE AND IMPROVEMENTS A. Performance At the time of this writing, ETS has been operational for about a month; however, it has not been in heavy use as yet because it was felt that the switch from batch to timesharing in the middle of a semester might delay students too much. Also at this time, additional core memory has not been installed on our system. The addition of this core will have a major effect on the throughput of the system. As a result of these two things, we have not had time to collect extensive statistics on the performance of the system under normal loads for extended periods of time. Even without extended data collection, we can learn much about the system performance from a few simple measurements. 1. Execution Time for Selected Segments We can calculate the execution time of some of the heavily used sections of code and project the CPU time that will be spent executing those routines. Figure VI. 1 gives the execution time for some common system routines. The execution time for device interrupt services is very important to the system since it must be handled in real time. In particular, the card reader and line printer can absorb a large amount of the available CPU time while running. The teletype interrupt service also requires a considerable amount of processing although the character 72 Routine Time (jisecs ) Buffer Allocation Get l6 word buffer and clear it Get l6 word buffer, clear first word Buffer Deallocation Return buffer FETCH Character from Monitor Chain Buffers Character in buffer and more than one block chain Character in buffer and one block in chain Character is last one in a block STORE Character in Monitor Chain Buffers No buffers exist in chain Buffer exists and is not full Current buffer is full Turn off all interrupts Turn interrupts back on Register Save 275 75 100 k2 51 1^5 186 81 2k 1 23 18 Processor priority <3 Processor priority >k Register Restore Processor priority <3 Processor priority >k 77 30 133 32 Figure VI. 1 Execution Time for Some System Routines 73 transmission rate is low. We consider the effect of these three devices on the system: a. Card Reader We assume an average user who is reading a source language deck into the system. We assume that the cards have an average of about kO characters. We count single blanks as characters and spans of blanks as single characters. We can then interpret the card as containing ^6 'characters' and 3k blanks which have been compressed. Reading cards require two system routines: the card reader interrupt handler and the card reader user service. The interrupt handler requires ~^35 jusecs/char on the k6 'characters' and ~331 jusecs/char on the 3^- blanks* This is an average of 391 usecs/char for the 80 column card. (Note: This time includes 153 /isecs/char to translate the card code to ASCII. By using a 128 word table and the translate facilities of the card reader, this can be cut to k.9 jusecs.) For a 600 cpm card reader, this operation requires about 31*^ of the available CPU time. The card reader user service requires about l60 jusecs/char on the non-blanks and about 100 (usees each for the blanks which are members of a span of blanks. This is about 129 /-/sec/char for the 80 column card. This is about 10.3$ of the available CPU. If trailing blanks are suppressed, this is closer to 8%. Since much of the processing is simpler when copying binary cards, the total CPU commitment is closer to 25$. However, the reading of binary decks is almost negligible when compared with the number of source decks read. b. Line Printer We can assume that the user is getting an assembly listing with an average of 100 char/line. For lines of this length, the line printer can print about 256 lines/minute or ^20 char/second. The line printer interrupt service requires about 198 usecs/char to process the outgoing characters — which is about 8.5$ of the CPU. The line printer user interface requires about l6o Msecs/char to get the characters from the user and store them in the monitor chain buffers. At ^20 char/sec, this is about 6.9$ of the CPU. Of all devices on the system, the card reader and line printer make the greatest demands on the system. However, when operating in timeshare mode (instead of batch) the amount of time that either is in use is small (~5$). Even with a batch partition, it would seem unreasonable to expect the actual time that the card reader is in use would go above 20$. However, at this level, the savings from using hardware translate facilities for the characters become appreciable. c. Teletype Because of the many interpretations a character from the teletype may have, they require more processing/character than any other device. From a low of ~^00 /usees for a character which requires no special processing they may require up to ~2000 /usees for a control character which requires extensive processing and multiple echoes. Even though they may require much processing per character, the CPU time necessary to support teletypes is small. We may assume 10 users who are all using their teletype at the maximum rate (a highly 75 unlikely circumstance). Since no extended sequence of control characters is meaningful, we assume 500 u sec/char processing. The maximum transfer rate for a teletype is 10 char/sec. Thus, 10 users need not more than 5$ of the CPU. Since 10$ teletype usage is probably a better estimate, we really expect NTIS-35 ( 10-70) 19.. Security Class (This Report) UNCLASSIFIED 20. Security Class (This Page UNCLASSIFIED 21. No. of Pages 80 22. Price USCOMM-DC 40329-P7 1 •ty 6 '% n ■ \tCM< ilni MM no *'' °** v ssssssbs 0112088400418 i.-, V ■ ■ ^1 I ■I ■ \ y ■ ■ ■ ^^^H IB I^H 1 I BBS HH ''•']• • vii H I Hi iftpj ■HO HU :>v'; )( K>p. BfisE RHH iran ^^H in In Sii Bil t&BM U KHKwfflSIls SBB " > I -iiH RHsSalSE Ifii) Hi ESKflH Hi u iffl? fflffl