|
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