Il Quarto Membro dell’Equipaggio (7) – L’Executive

Alcuni dei moduli che costituivano l’AGC

L’AGC come abbiamo visto era un computer RTC (real time), multitasking e capace di interagire con una serie di interrupt. Il fatto di essere multitasking significa che era in grado di gestire l’esecuzione di diversi programmi (job) contemporaneamente. A questi programmi veniva assegnata una priorità: in ogni momento l’AGC eseguiva il programma con la priorità più alta. Un altro modo di definire l’AGC è che si trattava di un priority-interrupt system.

Per quanto riguarda il multitasking, questa era una tecnica fondamentale per un sistema real time, che si trovava a gestire operazioni diverse nello stesso momento. Ovviamente l’AGC aveva un solo ‘processore’ e quindi il multitasking era più un effetto generato dalla velocità di esecuzione e dalla lentezza della percezione umana: i job venivano in realtà eseguiti uno alla volta, ma la velocità con cui venivano eseguiti e il continuo passaggio da un job all’altro in base alla priorità creavano l’illusione dell’esecuzione contemporanea.

Il compito di orchestrare il multitasking, col suo balletto di job prioritizzati, era compito principalmente dell’ Executive. Questo programma può essere considerato il sistema operativo dell’AGC.

L’Executive utilizzava la combinazione di due diverse strategie di multitasking:

  • il Cooperative Multitasking: come dice il nome stesso, in questa strategia i job ‘collaboravano’ alla gestione della priorità. Periodicamente il job in esecuzione cedeva volontariamente il controllo all’Executive, il quale rivedeva la priorità di tutti i job e, solo in base a questa, selezionava il job da eseguire. Il ruolo dell’Executive era dunque quello di creare nuovi job, tracciarne l’attività, gestire il passaggio da uno all’altro e terminarli. Ovviamente con questo approccio i programmi dovevano essere sviluppati con questa ‘volontà di collaborazione’

  • il Preemptive Multitasking: in questa strategia non era richiesta la collaborazione dei job. Un timer generava un interrupt che eseguiva l’Executive. Questo salvava lo stato del job in esecuzione, verificava la presenza di job a priorità superiore e in base a questa verifica sceglieva cosa eseguire (fino al prossimo interrupt). Come abbiamo visto nel post sugli interrupt, la Waitlist funzionava così (sfuttando il timer TIME3)

L’AGC era in grado di gestire una coda di 6 job per il CM e 7 per il LM. Questa coda veniva gestita tramite la manipolazione di una serie di aree di memoria chiamate Core Set.

Un Core Set

Ciascun Core Set era costituito da 12 word che contenevano:

  • le informazioni necessarie alla gestione dell’esecuzione nelle prime 5 word: la priorità del job, l’indirizzo di partenza, una copia del registro BBANK, diversi flag e un puntatore ad un’altra area di memoria chiamata VAC (su cui tornerò a breve)

  • le rimanenti 7 word disponibile come area di memorizzazione di variabili temporanee e che prendevano il nome cumulativo di Multipurpose Accumulator (MPAC)

I Core Set si trovavano tutti in un’area di memoria contigua nella memoria riscrivibile (ovviamente) ed erano numerati da 0 a 6. C’era poi un Core Set speciale e riservato al job denominato DUMMY: questo veniva eseguito quando non c’era nessun job in coda!

Core Set e lo scheduling

Il job in esecuzione si trovava sempre nel Core Set 0. Questo significa che nel momento in cui cambiava il job in esecuzione, avveniva uno scambio (swap) tra il contenuto del Core Set 0 e quello del nuovo job attivo.

I Core Set disponibili venivano identificati dal valore di zero-negativo (00000) nella priorità (vi ricordo che l’AGC utilizzava l’aritmetica in complemento a uno, caratterizzata dall’avere due rappresentazioni dello zero).

L’inizializzazione di un nuovo job cominciava con l’esecuzione della routine NOVAC: questa routine verificava la disponibilità di un Core Set, e inizializzava l’area (priorità compresa). A quel punto il job era pronto per essere eseguito. Ovviamente non subito ma nel momento determinato dalla priorità.

Il VAC (Vector Accumulator)

Potrebbe sembrare che l’area a disposizione dei job per salvare eventuali valori durante l’elaborazione fosse un pò piccola. E in effetti esisteva una seconda area a disposizione: il VAC (Vector Accumulator). Il nome deriva dal fatto che tale area veniva utilizzata principalmente dalle istruzioni avanzate per il calcolo vettoriale messe a disposizione dall’Interpreter (che vedremo la prossima settimana). Il VAC era costituito da 43 word nella memoria riscrivibile (42 i realtà, poiché la prima word indicava se il VAC era in uso o meno) e per ciascun Core Set era disponibile un VAC. Anziché la routine NOVAC si utilizzava la FINDVAC se occorreva allocare un Core Set e un VAC.

Ogni esecuzione dell’Executive scorreva i Core Set alla ricerca del job con la priorità più alta: una volta trovato, scriveva l’indirizzo del Core Set selezionato nella locazione di memoria NEWJOB. A quel punto, l’Executive terminava e riprendeva l’esecuzione al job precedentemente interrotto: era questo job (nello spirito del Cooperative Multitasking) a doversi occupare di verificare che ci fosse un nuovo job a priorità più elevata a cui cedere il controllo (ci si aspettava che questo controllo avvenisse ogni 20 ms circa).

Un’altra operazione molto frequente era il richiamo della routine PRIOCHNG. Tramite questa routine, un job poteva cambiare la propria priorità. Come passo finale della procedura, si scorreva la serie dei Core Set per verificare che, a fronte della nuova priorità, non si dovesse cedere ad un altro job il controllo.

La fine di un job poteva avvenire perché effettivamente si era esaurito il compito del job, oppure per un intervento manuale (tramite DSKY) o per un riavvio. In ogni caso veniva chiamata la routine ENDOFJOB, che ripuliva (e rendeva disponibili) il Core Set e il VAC in uso. A quel punto l’Executive entrava in azione per ricercare il prossimo job con la priorità più elevata e lo lanciava.

Ricordate quegli errori che afflissero Apollo 11 durante l’allunaggio? Quei Program Alarm 1201 e 1202? Beh, in soldoni significavano che non erano più disponibili Core Set (per l’allarme 1201) o VAC (per l’allarme 1202).

I Major Modes dell’AGC
Abbiamo visto come venivano gestiti i job. Ma chi decideva i job da avviare? Alcuni erano parte delle routine legati alla Waitlist, altri venivano lanciati da job già in esecuzione e un terzo ed ultimo modo era specificare un Major Mode tramite il DSKY (quello che veniva mostrato sul DSKY come PROG).

Il modo migliore di definire un Major Mode è: un programma molto lungo (destinato a durare minuti o addirittura ore) che controllava una funzione importante della missione come il lancio, l’allunaggio o il rendezvous. I Major Mode si differenziavano per pochi particolare dagli altri job e non potevano monopolizzare l’uso dell’AGC. Quindi, un pò sorprendentemente, la loro priorità era bassa, in modo da permettere l’esecuzione di altri job, piccoli magari ma importanti.

Piccola curiosità: il Major Mode in esecuzione in ogni momento era memorizzato nella locazione di memoria MODREG. Cambiare il valore di questa locazione di memoria non andava a modificare il job in esecuzione, ma c’erano delle routine che per sapere quale era il Major Mode corrente facevano riferimento a questa locazione. Per Apollo 14, questo fatto fu di vitale importanza per il successo della missione.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...