TS 860409 (c) 1986 by ORD-GROUP 29 TS TimeSharing Ons Timesharing operating system, gewoonlijk TS genoemd, stelt de ORDINATOR in staat om meerdere gebruikers tegelijk te bedienen. We gebruiken TS vrijwel altijd en het is ons tot nu toe uitstekend bevallen. Het is het grootste systeemprogramma dat we voor onze computer hebben geschreven. De basisideeën voor TS hadden we al voordat we met het project begonnen. Eisen De doelstelling van het hele ORDINATOR projekt was het voorzien in een tekort aan computer capaciteit. De eerste eis aan TS was dus het kunnen werken met meerdere gebruikers tegelijk. Aangezien we al werkten met CP/M 2.2 en daar veel programma's voor hadden geschreven moest TS compatibel zijn met CP/M 2.2. Bij voorkeur zodanig dat de bestaande diskettes zonder meer bruikbaar zouden blijven. Een algemene eis was een zekere elegantie en flexibiliteit in het gebruik. Hieronder valt bijvoorbeeld het dynamisch kunnen toe- kennen van terminals en de printer. Door de beperkte hoeveelheid hardware werden nog was extra eisen gesteld. Zo hebben we maar twee disk drives, hetgeen met meerdere gebruikers erg weinig is. Er moest dus een manier gevonden worden om de disk drives te delen. Werken met TS Wanneer men met meerdere personen tegelijk van het systeem gebruik maakt, gedraagt het zich als meerdere onafhankelijke CP/M systemen. Een niet actieve terminal staat op "login". Het systeem verwacht dan de naam van de diskette waarop een gebruiker wil werken. Na die ingetypt te hebben, krijgt men een CP/M terminal ter beschikking, met een default omgeving. De commando inter- preter is dezelfde als onder single user CP/M, onze eigen CCP. Zij bevat een extra commando, BYE, dat dient om het systeem te kennen te geven dat men er mee ophoudt (uitlogt). CP/M werkt met virtuele devices, namelijk CON: (console), RDR: (algemeen invoer apparaat), PUN: (algemeen uitvoer apparaat), en LST: (algemeen listing apparaat). De beschikbare diskettes dragen de namen A:, B:, C: en D:. Deze virtuele devices worden door TS gekoppeld aan reële devices. Elk reëel device heeft een unieke naam, die de funktie uitdrukt. Voorkomende namen van karakter devices zijn VIDEO0 en VIDEO1, PRINTER, PIPE0 t/m PIPE2, SERIAL0 t/m SERIAL2. Elke diskette is een disk device, met namen zoals TS_SYS (TS systeem diskette), UTIL_DEV (utilities ontwikkel disk), enzovoorts. Er is geen beperking op het totaal aantal devices, slechts een beperking op het totaal aantal tegelijk aanspreekbare devices. Deze koppeling valt onder de omgeving, alsmede de hoeveelheid ter beschikking staand geheugen, en het al dan niet bezitten van super user status. TS 860409 (c) 1986 by ORD-GROUP 30 Om de omgeving te veranderen staan systeem funkties ter be- schikking, die vanaf het commando niveau beschikbaar zijn via een aaltal utilities. Vanuit machinetaal zijn alle funkties, hier- onder genoemd, beschikbaar. Functies Het CP/M 2.2 operating systeem is als basis gebruikt. Dit systeem heeft alle hardware afhankelijke functies geconcentreerd in een component, het Basic I/O System (BIOS). Ons TS operating systeem gedraagt zich als een uitgebreide BIOS, voor meerdere CP/M's tegelijk. Extra TS funkties zijn beschikbaar via een uitbreiding van de BIOS, de zogenaamde system call. De standaard CP/M funkties worden gezien als speciale system calls. System calls zijn dus de werkelijke TS functies. Ze bewerkstel- ligen de verandering van protectie domein, van gebruikers naar systeem omgeving. De beschikbare system calls kunnen ruwweg gegroepeerd worden in karakter I/O, disk I/O, omgevings controle, en proces controle. De karakter functies zijn in termen van de CP/M devices, die werken met één karakter per keer. Disk functies zijn in termen van de CP/M devices, maar werken met een sector van 128 bytes per keer. De meeste omgevings parameters van een CP/M kunnen opgevraagd en gewijzigd worden via twee system calls. De "set" system call accepteert een ASCII string met toekenningen aan parameters, bv "A:=MY_DISK". De "get" system call accepteert op analoge wijze een lijst parameters, en antwoordt met een lijst toekenningen zoals die door "set" geaccepteerd wordt. Een CP/M onder TS heeft, net als onder single user, een privilege status. Deze kan opgevraagd en veranderd worden. Om super user status te verkrijgen moet een wachtwoord ingetypt worden vanaf de terminal. We kunnen processen starten, zowel CP/M als login processen. Een proces kan zichzelf beeindigen, zijn eigen proces nummer op- vragen, signals naar andere processen zenden, de alarm klok zetten (zodat binnen zoveel seconden er een alarm signal gezonden wordt), en zichzelf stoppen tot er een signal ontvangen wordt. Dit laatste is nuttig, in combinatie met de alarm klok, voor het implementeren van delays. Op memory mapped video terminals bestaan enige speciale opera- ties. Deze dienen om het memory-mapped aanspreken van zo'n terminal mogelijk te maken, zowel voor onze eigen SEDN editor, als voor WordStar. De beschikbare operaties zijn het in en uit zetten van de memory mapped mode, en het zetten en weghalen van de cursor. Het TS systeem houdt per proces de verbruikte processor tijd bij, gespecificeerd in gebruikers en systeem tijd. Deze tijden kunnen uiteraard opgevraagds worden. Ze hebben een resolutie van één milliseconde. Ook kunnen programma's gebruik maken van de TS TS 860409 (c) 1986 by ORD-GROUP 31 profiling funktie. Het programma moet dan zijn huidige toestand doorgeven aan TS, die dan bijhoudt hoeveel tijd in elke toestand doorgebracht werd. Toestanden kunnen bij voorbeeld corresponderen met funkties in het gebruikersprogramma. Een programma kan van TS gegevens opvragen. In het uiterste geval kunnen alle gegevens verkregen worden door direct lezen uit de TS adres ruimte, hetgeen mogelijk is. Om dit wat te reguleren is er configuratie informatie beschikbaar, onder andere de locaties en groottes van de verschillende arrays binnen TS. Er zijn speciale funkties voor het opvragen van alle karakter respectievelijk disk devices die beschikbaar zijn. Interne structuur Het totale TS systeem is op te delen een een aantal min of meer hierarchisch gerangschikte modules. De buitenste module is de BIOS voor CP/M, het enige deel van TS dat zichtbaar is voor de gebruiker. Deze verzorgt het omschakelen van gebruikers naar systeem domein, en rouleert de system calls naar de juiste module. De volgende module vertaalt de locale device namen per gebruiker (zoals CP/M die gebruikt) naar de werkelijke systeem-wijde namen (bijvoorbeeld: CON: wordt VIDEO0). Deze module beheert ook de access permissie voor devices. Karakter devices zijn slechts toegankelijk vanuit één proces tegelijk, dit om onderlinge beinvloeding te voorkomen. Disks zijn leesbaar voor iedereen, maar mogen slechts aan één CP/M disk device tegelijk schrijfbaar gekoppeld zijn. Dit beperkt schrijf toegang dus automatisch tot één proces tegelijk. Als we de karakter I/O volgen komt er nu een support laag voor de hardware drivers. Deze omvat routines voor het beheren van karakter lists (nodig voor type ahead, en seriele apparaten), en voor de translatie van device-onafhankelijke codes gebruikt binnen TS naar de device-afhankelijke codes. Ook het herkennen van het zogenaamde "DEL" karakter vindt hier plaats. Dit karakter (de naam is een erfenis uit het verleden: het karakter kan ingesteld worden) heeft als resultaat het zenden van "breek programma af" signal (SIGDEL) naar het bijbehorende proces. Tenslotte volgt het allerlaagste niveau van karakter I/O, de drivers met bijbehorende interrupt routines. In de meeste gevallen doen deze drivers niet meer dan de directe aansturing van de hardware, gebruik makend van de beschikbare subroutines uit het vorige niveau voor de device-onafhankelijke functies. Als we de disk I/O volgen komen we nog meer lagen tegen. Aller- eerst komt nu de disk cache. De cache reduceert disk I/O en buffert sectoren voor CP/M. CP/M werkt namelijk met logische sectoren van 128 bytes, terwijl onze fysieke sectoren vier keer zo groot zijn. Bovendien doet zij aan vooruitlezen, zodat de snelheid van sequentiele disk I/O sterk toeneemt. Beneden de disk cache volgt de virtuele disk behandeling. Deze TS 860409 (c) 1986 by ORD-GROUP 32 laag vertaalt functies in termen van disks in termen van disk drives. Indien een bepaalde disk niet online beschikbaar is, wordt een attentie signaal gegenereerd dat de disk nodig is. Dan zijn we op het laagste disk I/O niveau beland . Hier wordt de hardware direkt aangestuurd. Een disk I/O driver is helaas complexer dan een karakter I/O driver, maar door het delegeren van alle hardware-onafhankelijke operaties naar het direct- bovenliggende niveau blijft de complexiteit beperkt. Wat een driver doet is weinig meer dan het ordenen van de I/O en het fysiek uitvoeren ervan. Wanneer in de nabije toekomst ons lokale netwerk operationeel wordt, zal er een netwerk niveau bijkomen, beneden zowel het karakter als disk I/O. Op deze twee niveaus zullen dan "drivers" bijkomen voor de aansturing van devices over het netwerk. Direct onder het BIOS zitten nog andere modules, zoals de klok module. Zij behandelt de hardware timer (een 10 Hz interrupt en een 1 KHz teller). De externe tijd (uren, minuten, seconden) wordt, evenals de allocatie van processortijd voor diverse doel- einden, bijgehouden. Een "profiling" functie is beschikbaar voor gebruikers programma's. Dit alles met een nauwkeurigheid van één milliseconde. Er is ook een "proces" module. Deze bevat functies voor het creeren en termineren van processen, zowel binnen als buiten de kernel. De onderliggende "scheduler" verzorgt multiprocessing en de synchronisate tussen de verschillende processen, alsmede de overdracht van en het reageren op signals (zie verderop). De "memory" module draagt zorg voor het beheer van het geheugen en de toewijzing ervan aan de diverse gebruikers. Wegens beper- kingen van CP/M is dynamisch beheer niet mogelijk, alle beheer is statisch. Dit wil zeggen dat de hoeveelheid beschikbaar geheugen constant is tijdens één programma. Met behulp van de "set" system call kan een gebruiker (onder andere) zijn geheugen grootte instellen. De "login" module verzorgt het inloggen van gebruikers op het systeem. Inloggen gebeurt door aan te geven op welke disk he wilt werken. Het is niets meer dan het opstarten van een CP/M met een bepaalde default omgeving. Een sub-module is de "console". Deze verzorgt een display van actieve en benodigde disks, zodat de gebruiker het systeem kan voorzien van de disks die het nodig heeft. De console module werkt samen met de module voor virtuele disk behandeling. De debug en panic module verzorgt de informatie die noodzakelijk is om TimeSharing te kunnen debuggen met behulp van DIAMOND. In geval van fatale systeem fouten wordt een paniek boodschap afgedrykt en stopt het systeem. Tenslotte is er nog een opstart module, die het systeem van single user CP/M naar TimeSharing CP/M brengt. Deze module TS 860409 (c) 1986 by ORD-GROUP 33 initialiseert het systeem en start console en login processen op. Multiprocessing en synchronisatie Multiprocessing is gerealiseerd met behulp van conventionele processen. Binnen de TS kernel zijn het eigenlijk geen processen, doch slechts coroutines. Deze coroutines geven de CPU alleen op door een expliciete actie, namelijk een aanroep van de routine "sleep". Omdat er slechts een processor is, hebben coroutines dus de CPU (en de datastructuren van TS) voor zich alleen. De uitzon- deringen op deze situatie zijn de interrupts. Wanneer ook deze niet toegestaan zijn (bijvoorbeeld tijdens het veranderen van een kritieke datastructuur) worden de interrupts ge-disabled. TS coroutines kunnen in diverse toestanden verkeren. In een aantal toestanden staan ze op een "queue". De queues die TS bijhoudt zijn de "user queue", de "system queue" en de "sleep queue". De user queue bevat gebruikers processen, de system queue processen in de systeem fasen. De sleep queue bevat "slapende" coroutines (routines die de subroutines "sleep" aan hebben geroepen). Het actieve proces (of coroutine) staat op geen enkele queue. Coroutines hebben de hoogste prioriteit: zolang er nog coroutines op de system queue staan, komen gebruikers processen niet aan de beurt. Wanneer de system queue leeg is, wordt de user queue geconsulteerd. Is die ook leeg, dan krijgt het speciale "null" process de processor. Dit proces doet niets, op een speciale manier. Met behulp van de machine instructie HALT wordt gewacht op de eerstvolgende interrupt. Daarna wordt de processor vrijgegeven. Synchronisatie tussen coroutines vindt plaats door te wachten op "events". Een event is een willeurige 16-bits waarde, bij conventie het adres van een tabel geassocieerd met de conditie waarop gesynchroniseerd wordt. Een coroutine die besluit te gaan wachten roept de subroutine "sleep" aan met als argument het event waarop gewacht moet worden. De coroutine wordt dan inactief (op de sleep queue geplaatst) tot het moment dat er een "wakeup" plaatsvindt op dat event. De subroutine "wakeup" accepteert op gelijke wijze een event als argument. Alle coroutines die op dat event aan het wachten waren worden van de sleep queue naar de system queue verplaatst. Wanneer een "sleep" aanroep terugkeert, is er echter geen garantie dat de gewenste conditie bestaat. Er kunnen namelijk andere coroutines uitgevoerd zijn tussen de bijbehorende wakeup en het terugkeren van de "sleep" aanroep. Dus, sleep/wakeup biedt mogelijkheden tot synchronisatie, maar is niet voldoende. Dit wordt ondervangen door in plaats van een simpele "sleep" aanroep een lus te gebruiken van de vorm "WHILE conditie niet waar DO sleep(wachtpunt) OD". Het bovenbeschreven probleem kan nog verergerd worden door het bestaan van "signals". Signals vertellen een proces of coroutine om iets te doen. Signals kunnen onder andere zijn "Breek TS 860409 (c) 1986 by ORD-GROUP 34 programma af", "Pleeg zelfmoord", "Alarm klok timeout". Signals worden altijd geaccepteerd, zelfs wanneer een proces aan het slapen was. Dit betekent dat het terugkeren van een "sleep" aanroep geen garantie biedt voor het plaats gevonden hebben van de bijbehorende "wakeup". Bovendien is het mogelijk dat een "sleep" aanroep helemaal niet terugkeert. Hieruit volgt dat locks als zodanig in TS niet gebruikt kunnen worden, daar een proces op elk synchronisatiepunt afgebroken kan worden. Daar waar nodig is dit ondervangen met delays, zodat er in feite locks met een beperkte tijdsduur gebruikt zijn. Conclusie Het blijkt dat time sharing op een Z80 systeem mogelijk is. Ondanks de beperkingen van een klein budget is toch een systeem ontwikkeld dat zeer goed in staat is meerdere gebruikers tegelijk van dienst te zijn, tot een aantal van vier of vijf. Zelfs dan bereiken we slechts een nuttig CPU gebruik van rond de 60 procent. Wanneer er meerdere rekenintensieve programma's tegelijk lopen neemt de snelheid duidelijk af, doch in de meeste gevallen niet zoveel dat het hinderlijk is. Daar het systeem het grootste deel van de tijd niet rekenintensief belast wordt, is dit zeer wel aanvaardbaar. Uitgaan van CP/M is een gerechtvaardigde beslissing gebleken, ook al liepen we soms wel eens tegen de inherente beperkingen op. De geëiste compatibiliteit was hierdoor echter eenvoudig te realiseren.