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