mxProzess.c


/* mxProzess.c */

#include "mxProzess.h"
#include "mxStrukturen.h"
#include "mxKernStruk.h"
#include "mxListe.h"
#include "mxCPUVerwaltung.h"
#include "mxKontrolle.h"
#include "mxTrap.h"
#include "mxFehler.h"
#include "mxSystemAufruf.h"
#include "mxSystem.h"
#include "mxLib.h"


/* -------------------------------------------------------------------------------------------------------------------- */
/***************
** Funktionen **
***************/
tProzessNummer ProzessAnmelden(void)
{
  tProzessNummer ProzessNummer;
  tListenKnoten *Knoten;

  ProzesswechselUnterbinden();
  if (!(ListeLeer(&FreiListe))) {                                       /* noch freie Prozessverwaltungsbloecke da ?    */
    Knoten = KnotenAbhaengen(&FreiListe);                               /*   ja -> PVB aus Freiliste holen und fuer     */
    ProzessNummer = Knoten->Index;                                      /*         neuen Prozess verwenden              */
    ProzessTabelle[ProzessNummer].Status = eExistent;
  } else {
    ProzessNummer = 0;                                                  /* nein -> 0 zurueckgeben                       */
  }
  ProzesswechselZulassen();
  return ProzessNummer;
} /* ProzessAnmelden */

/* -------------------------------------------------------------------------------------------------------------------- */

void *BenutzerUmgebungHerstellen(void *UserStackEnde, void *RuecksprungAdresse, tString Kommando, tString ArgZeile)
{
  char *argP;
  int  argc=0, i;

  UserStackEnde -= strlen(ArgZeile) + 1;                                /* Kommandozeilenargumente auf den Userstack    */
  strcpy(UserStackEnde, ArgZeile);                                      /* Argumente kopieren                           */

  UserStackEnde -= strlen(Kommando) + 1;                                /* Platz reservieren...                         */
  strcpy(UserStackEnde, Kommando);                                      /* Kommando wird argv[0]!                       */

  argP           = UserStackEnde;                                       /* hier beginnt der Textbereich der Argumente   */
  argP[strlen(Kommando)] = ' ';                                         /* zwischen Kommando und Argumenten ein ' '     */
  while ((int)UserStackEnde & 3) UserStackEnde--;                       /* USP durch 4 teilbar machen                   */

  UserStackEnde          -= sizeof(char *);                             /* Platz auf Userstack reservieren              */
  *(char **)UserStackEnde = NULL;                                       /* Nullzeiger argv[argc] eintragen              */

  for (i = strlen(argP) - 1; i >= 0; i--) {                             /* Kommando & Argumente rueckwaerts parsen      */
    if (argP[i] == ' ') {                                               /*   wenn Leerzeichen, dann                     */
      argP[i] = 0;                                                      /*     durch '\0' ersetzen,                     */
    }
    if (i==0 || (argP[i] != 0 && argP[i-1] == ' ')) {                   /*   wenn Anfang oder Leerzeichen davor, dann   */
      argc++;                                                           /*     beginnt hier ein neues Argument          */
      UserStackEnde          -= sizeof(char *);                         /*     Platz auf Userstack reservieren          */
      *(char **)UserStackEnde = &argP[i];                               /*     Zeiger auf akt. Argument eintragen       */
    }
  }

  UserStackEnde        -= sizeof(char **);                              /* Platz auf Userstack reservieren              */
  *(char ***)UserStackEnde = (UserStackEnde + sizeof(char **));         /* char *argv[] ablegen                         */
  UserStackEnde        -= sizeof(int);                                  /* Platz auf Userstack reservieren              */
  *(int    *)UserStackEnde = argc;                                      /* int argc ablegen                             */

  UserStackEnde        -= sizeof(void *);                               /* Ruecksprungadresse oder wenigstens Platzhal- */
  *(void **)UserStackEnde = RuecksprungAdresse;                         /*   ter, damit die Argumente gefunden werden   */

  return UserStackEnde;
} /* BenutzerUmgebungHerstellen */

/* -------------------------------------------------------------------------------------------------------------------- */

tProzessUmgebung *UmgebungHerstellen(void *KernStackEnde, void *aUserStackZeiger, void *StartAdresse)
{
  int i;
  tProzessUmgebung *ProzessUmgebungP;

  ProzessUmgebungP = KernStackEnde - sizeof(tProzessUmgebung);          /* Platz auf Kernstack fuer                     */
                                                                        /* Anfangs-Prozessumgebung benutzen             */
  for (i=0; i < 7; i++) {                                               /* Prozessumgebung herstellen                   */
    ProzessUmgebungP->AdressRegister[i] = 0;
  }
  for (i=0; i < 8; i++) {
    ProzessUmgebungP->DatenRegister[i]  = 0;
  }
  ProzessUmgebungP->UserStackZeiger    = aUserStackZeiger;
  ProzessUmgebungP->StatusRegister     = 0;
  ProzessUmgebungP->RuecksprungAdresse = StartAdresse;
  return ProzessUmgebungP;
} /* UmgebungHerstellen */

/* -------------------------------------------------------------------------------------------------------------------- */

void ProzessStarten(tProzessNummer ProzessNummer, void *KernStackEnde, void *UserStackEnde,
		    void *StartAdresse, int aZeitscheibe, tString Kommando, tString ArgZeile)
{
  tProzessVerwaltungsBlock *PVB = &ProzessTabelle[ProzessNummer];
  int i;

  ProzesswechselUnterbinden();

  if (PVB->Status == eExistent) {                                       /* wurde Prozess vorher angemeldet ?            */
    UserStackEnde = BenutzerUmgebungHerstellen(UserStackEnde,           /* Argumente und Ruecksprungadresse auf U-Stack */
 					       sys_Terminiere,
					       Kommando,
					       ArgZeile);

    PVB->ProzessUmgebungP = UmgebungHerstellen(KernStackEnde,           /* Prozessumgebung erzeugen                     */
					       UserStackEnde,
					       StartAdresse );

    while (*ArgZeile == ' ') ArgZeile++;                                /* keine Zwischen-Leerzeichen ist schoener      */
    i = snprintf(PVB->Name, cProzessNameLaenge, /*%s %s*/,                /* Prozessnamen in PVB eintragen                */
	         Kommando, ArgZeile) - 2;
    while (i>=0 && PVB->Name[i]==' ') PVB->Name[i--] = cNUL;            /* Leerzeichen am Ende weg ist schoener         */
    PVB->Zeitscheibe      = aZeitscheibe;                               /* Zeitscheibe in PVB eintragen                 */
    PVB->Status           = eBereit;                                    /* PVB als lauffaehig ausweisen                 */
    PVB->Abgeschossen     = FALSE;
    PVB->AmTerminieren    = FALSE;
    PVB->WechselZaehler   = 0;
    PVB->LED.Zahl         = ProzessNummer;
    PVB->LED.Stellen      = 1;
    KnotenAnhaengen(&BereitListe, &PVB->StatusKnoten);                  /* und in die Bereitliste einhaengen            */
  } else {
    SystemFehler(cStatusFehler);
  }

  ProzesswechselZulassen();
} /* ProzessStarten */

/* -------------------------------------------------------------------------------------------------------------------- */

int BeendenVorbereiten(tProzessNummer ProzessNummer)
{
  tProzessVerwaltungsBlock *PVB = &ProzessTabelle[ProzessNummer];
  int ok = FALSE;

  ProzesswechselUnterbinden();
  while ((PVB->AmTerminieren) &&                                        /* wurde Termination des laufenden Prozesses    */
	 (ProzessNummer == LaufenderProzess())) {                       /* bereits von anderem Prozess begonnen ?       */
    CPUWeitergeben();                                                   /* -> dann gibt es nichts mehr zu tun.          */
  }

  if (!(PVB->AmTerminieren || (PVB->Status == eFrei)                    /* laesst Status Beenden des Prozesses zu ?     */
    || (PVB->Status == eTerminiert) || (PVB->Status == eExistent))) {
    if ((PVB->Status == eLaufend)                                       /* darf laufender Prozess den Prozess beenden?  */
	|| !((1 << cSupervisorBit) & PVB->ProzessUmgebungP->StatusRegister)) {
      ok = TRUE;                                                        /*   ja -> alles klar                           */
      PVB->AmTerminieren = TRUE;                                        /*         markieren, dass Prozess gerade       */
                                                                        /*         terminiert wird                      */
    } else {
      PVB->Abgeschossen = TRUE;                                         /* nein -> als zu terminieren markieren         */
    }
  }
  ProzesswechselZulassen();
  return ok;
} /* BeendenVorbereiten */

/* -------------------------------------------------------------------------------------------------------------------- */

void ProzessBeenden(tProzessNummer ProzessNummer)
{
  tProzessVerwaltungsBlock *PVB = &ProzessTabelle[ProzessNummer];

  ProzesswechselUnterbinden();
  if (PVB->Status == eBereit) {                                         /* ist zu beendender Prozess bereit ?           */
    KnotenExtrahieren(&BereitListe, &PVB->StatusKnoten);                /*   ja -> aus der Bereitliste holen            */
    PVB->Status = eTerminiert;
  } else if (PVB->Status == eLaufend) {                                 /* oder terminiert er sich selbst ?             */
    PVB->Status = eTerminiert;                                          /*   ja -> auch gut                             */
  } else {                                                              /* sonst                                        */
    SystemFehler(cStatusFehler);                                        /*   Systemfehler                               */
  }
  ProzesswechselZulassen();
} /* ProzessBeenden */

/* -------------------------------------------------------------------------------------------------------------------- */

void ProzessAbmelden(tProzessNummer ProzessNummer)
{
  tProzessVerwaltungsBlock *PVB = &ProzessTabelle[ProzessNummer];

  ProzesswechselUnterbinden();
  if ((PVB->Status == eTerminiert) || (PVB->Status == eExistent)) {     /* laesst Status Abmelden zu ?                  */
    PVB->Status = eFrei;                                                /*   ja -> PVB als frei markieren               */
    KnotenAnhaengen(&FreiListe, &PVB->StatusKnoten);                    /*         und in Freiliste einhaengen          */
  } else {
    SystemFehler(cStatusFehler);
  }
  if (ProzessNummer == LaufenderProzess()) {                            /* hat sich der Prozess selbst abgemeldet ?     */
    CPUWeitergeben();                                                   /*   ja -> dann hat er jetzt Feierabend         */
  }
  ProzesswechselZulassen();
} /* ProzessAbmelden */

/* -------------------------------------------------------------------------------------------------------------------- */

int IstAbgeschossen(tProzessNummer ProzessNummer)
{
  return ProzessTabelle[ProzessNummer].Abgeschossen;
} /* IstAbgeschossen */

/* -------------------------------------------------------------------------------------------------------------------- */

int HatStackUeberlauf(void)
{
  return GetUSP() <=                                                    /* UserStack ist voll, wenn der abwaerts        */
    ProzessTabelle[LaufenderProzess()].Speicher.UserStack;              /*   laufende USP den Stack-Start erreicht hat! */
} /* HatStackUeberlauf */

/* -------------------------------------------------------------------------------------------------------------------- */

void ProzessInformationen(tProzessInformation Infos[])
{
  tProzessVerwaltungsBlock *PVB;
  tProzessNummer i;

  ProzesswechselUnterbinden();                                          /* konsistenten Zustand auslesen                */
  for (i = 0; i < cMaximaleProzessAnzahl; i++) {                        /* gewuenschte Informationen aus der            */
    PVB = &ProzessTabelle[i];
    strncpy(Infos[i].Name, PVB->Name, cProzessNameLaenge);              /* Prozessnamen kopieren                        */
    Infos[i].Name[cProzessNameLaenge] = cNUL;
    Infos[i].Status        = PVB->Status;
    Infos[i].AmTerminieren = PVB->AmTerminieren;
    Infos[i].Abgeschossen  = PVB->Abgeschossen;
    if ((PVB->Status == eFrei ) || (PVB->Status == eExistent)           /* Wo ist ein Prozess, der noch nie lief        */
	|| (PVB->Status == eTerminiert)) {                              /* oder nicht mehr laueft?                      */
      Infos[i].ImKern = FALSE;                                          /*   jedenfalls nicht im Kern                   */
    } else {
      Infos[i].ImKern = ((1 << cSupervisorBit) & (PVB->ProzessUmgebungP->StatusRegister)) != 0;
                                                                        /* sonst aus SR lesen, wo er sich befindet      */
    }
  }
  ProzesswechselZulassen();
} /* ProzessInformationen */

/* -------------------------------------------------------------------------------------------------------------------- */

int InitProzess(void)
{
  return TRUE;
}


Bei Problemen mit der Seite bitte eine Mail an Marek
Converted with C2HTML V0.669 by Iluvatar
Prozeßdatenverarbeitung