|
mxCPUVerwaltung.c |
/* mxCPUVerwaltung.c */
#include "mxCPUVerwaltung.h"
#include "mxStrukturen.h"
#include "mxKernStruk.h"
#include "mxListe.h"
#include "mxUhr.h"
#include "mxInterrupt.h"
#include "mxKontrolle.h"
#include "mxTrap.h"
#include "mxVT.h"
#include "mxLED.h"
#include "mxLib.h"
/* -------------------------------------------------------------------------------------------------------------------- */
/**********************
** Globale Veriablen **
**********************/
extern int ErlaubtZaehler; /* importiert aus mxKontrolle.c */
tProzessTabelle ProzessTabelle; /* Die Prozesstabelle */
tListe FreiListe, BereitListe; /* Die Bereit- und Freiliste */
tProzessNummer Laufender; /* Prozessnummer des laufenden Prozesses */
int RestZeit; /* wie lange hat der laufende Prozess noch */
/* die CPU? */
unsigned jiffies; /* Zaehler fuer die Uhrticks seit Systemstart */
/* -------------------------------------------------------------------------------------------------------------------- */
/***************
** Funktionen **
***************/
void CPUEntziehen(tProzessNummer Laufender)
/*
* Haengt den laufenden Prozess, falls er noch weiterlaufen darf,
* an die Bereitliste an.
*/
{
tProzessVerwaltungsBlock *PVB = &ProzessTabelle[Laufender];
if (PVB->Status == eLaufend) { /* kann aktueller Prozess noch weiterlaufen ? */
PVB->Status = eBereit; /* ja --> seinen Statusknoten an die */
KnotenAnhaengen(&BereitListe, &PVB->StatusKnoten); /* Bereitliste anhaengen */
}
} /* CPUEntziehen */
/* -------------------------------------------------------------------------------------------------------------------- */
void CPUNeuVergeben(void)
/*
* Vergibt die CPU an den ersten Prozess in der Bereitliste
*/
{
tProzessVerwaltungsBlock *PVB;
tListenKnoten *NaechsterP; /* naechster zu startender Prozess */
NaechsterP = KnotenAbhaengen(&BereitListe); /* ersten Knoten aus Bereitliste holen */
Laufender = NaechsterP->Index; /* sein Prozess wird zum laufenden Prozess */
PVB = &ProzessTabelle[Laufender];
PVB->Status = eLaufend;
RestZeit = PVB->Zeitscheibe; /* Zeit, die der Prozess laufen darf, bestimmen */
Setze7SegmentZahl(PVB->LED.Zahl, PVB->LED.Stellen); /* prozess-spezifischer LED-Inhalt */
} /* CPUNeuVergeben */
/* -------------------------------------------------------------------------------------------------------------------- */
tProzessUmgebung *ProzessWechsel(tProzessUmgebung *ProzessUmgebungP)
{
ProzessTabelle[Laufender].ProzessUmgebungP = ProzessUmgebungP; /* Verweis auf Prozessumgebung speichern */
ProzessTabelle[Laufender].WechselZaehler = ErlaubtZaehler; /* Wert des Wechselzaehlers merken */
CPUEntziehen(Laufender); /* laufendem Prozess die CPU entziehen */
CPUNeuVergeben(); /* naechsten Prozess weiterlaufen lassen */
ErlaubtZaehler = ProzessTabelle[Laufender].WechselZaehler; /* Wert des Wechselzaehlers wieder einsetzen */
return ProzessTabelle[Laufender].ProzessUmgebungP; /* dessen Prozessumgebung wieder herstellen */
} /* ProzessWechsel */
/* -------------------------------------------------------------------------------------------------------------------- */
tProzessUmgebung *ZeitUeberwachung(tProzessUmgebung *ProzessUmgebungP)
{
jiffies++;
RestZeit--;
if ((RestZeit <= 0) && ProzesswechselErlaubt()) { /* Zeitscheibe abgelaufen und Wechsel erlaubt? */
ProzessUmgebungP = ProzessWechsel(ProzessUmgebungP); /* ja --> Prozesswechsel */
}
return ProzessUmgebungP;
} /* ZeitUeberwachung */
/* -------------------------------------------------------------------------------------------------------------------- */
tProzessNummer LaufenderProzess(void)
{
return Laufender;
} /* LaufenderProzess */
/* -------------------------------------------------------------------------------------------------------------------- */
void Setze7SegmentFuerProzess(int Zahl, int Stellen)
{
ProzessTabelle[Laufender].LED.Zahl = Zahl; /* Werte abspeichern fuer Prozesswechsel */
ProzessTabelle[Laufender].LED.Stellen = Stellen;
Setze7SegmentZahl(Zahl, Stellen); /* LED-Anzeige programmieren */
} /* Setze7SegmentFuerProzess */
/* -------------------------------------------------------------------------------------------------------------------- */
void ProzessListenInit(void)
/*
* Loescht die Bereitliste und haengt alle Prozesse in die Freiliste
*/
{
tProzessNummer PTI;
ListeInitialisieren(&BereitListe);
ListeInitialisieren(&FreiListe);
for (PTI = 0; PTI < cMaximaleProzessAnzahl; PTI++) { /* Alle Prozesse in Freiliste geben */
KnotenInitialisieren(&ProzessTabelle[PTI].StatusKnoten, PTI); /* freien Knoten fuer jeden PVB erzeugen */
ProzessTabelle[PTI].Status = eFrei;
KnotenAnhaengen(&FreiListe, &ProzessTabelle[PTI].StatusKnoten); /* und in die Freiliste einhaengen */
}
} /* ProzessListenInit */
/* -------------------------------------------------------------------------------------------------------------------- */
void KernInit(void)
/*
* Nimmt den Kernprozess aus der Freiliste und markiert ihn als
* laufenden Prozess
*/
{
tProzessVerwaltungsBlock *PVB = &ProzessTabelle[cKernProzess];
KnotenExtrahieren(&FreiListe, &PVB->StatusKnoten); /* Knoten des Kernprozesses aus der */
/* Freiliste holen */
strncpy(PVB->Name, "Kernprozess", cProzessNameLaenge);
PVB->Name[cProzessNameLaenge] = cNUL;
PVB->Status = eLaufend;
PVB->Zeitscheibe = cKernTickAnzahl;
PVB->AmTerminieren = FALSE;
PVB->Abgeschossen = FALSE;
PVB->WechselZaehler = 0;
PVB->LED.Zahl = cKernProzess;
PVB->LED.Stellen = 1;
Laufender = cKernProzess; /* am Anfang waren der Kernprozess ... */
RestZeit = ProzessTabelle[Laufender].Zeitscheibe; /* ... und seine Zeitscheibe */
} /* KernInit */
/* -------------------------------------------------------------------------------------------------------------------- */
int InitCPUVerwaltung(void)
{
jiffies = 0;
ProzessListenInit();
KernInit();
return TRUE;
}
Bei Problemen mit der Seite bitte eine Mail an Marek
Converted with C2HTML V0.669 by Iluvatar
Prozeßdatenverarbeitung