class ProcInfo {
// megastructure avec le tout ce qui faut
// un seul objet en sera cree a l'utilisation
// contient entre autres un vector de ProcData's
// qui sont les objets par programme/processus
// chaque ProcData contient divers renseignements
// (initialisees, constants ou evoluant, comme des
// accumulateurs de temps, l'etat du processus, etc.)
// et aussi un vector de ProcInstruction, nomme proGram
// tres important, chaque ProcData a bien entendu un
// programCounter, qui est l'indice dans le proGram
// donnant l'instruction EN COURS
// on parlera de pid de programme/processus a simuler,
// et ce pid est un simple entier, indice dans le
// vector de ProcData's
// ce pid ne doit pas etre confondu avec le pid Unix reel,
// qui intervient egalement lors des fork()'s Unix reels,
// effectues pour simuler les operations de type io
// lorsqu'il n'est pas clair du contexte, il en est fait
// mention explicite pour les distinguer
public:
enum ProcStatus {
STAT_WAITING, STAT_RUNNING,
STAT_IO, STAT_SYS, STAT_TERMINATED
};
enum ProcInfoOperType { // c'est pour demander a
// la fonction
// updateProcData(), d'avancer pas-a-pas
// chaque processus en cours de simulation
ADVANCE_PROC,
IO_TERM, CPU_TERM
};
private:
enum ProcInstructionType { // pour la traduction
// de chaque programme a simuler
DO_CPU, DO_IO, DO_FORK
// dont la syntaxe tres simple est
// {compute,io,fork} {exact,approx,random} <nombre>
// dans la suite, on ecrira 'compute', 'io' et 'fork'
// si autrement il y aurait ambiguite
};
enum ProcInstructionDurationType { // pour varier un peu
// les manieres d'estimation des durees
EXACT_TIME, APPROX_TIME, RANDOM_TIME
// approx == <nombre> + (plus ou moins 20% de <nombre>)
// random == entre 1 et <nombre>
};
// on appellera ce <nombre> la "Requested Duration"
// et le resultat du calcul ci-avant la "Decided Duration"
// toutes les durees sont en secondes,
// rappel: meme le time_t est en secondes, a savoir le nombre
// de seconde depuis l'Epoque Unix (1er janvier 1970)
struct ProcInstruction { // pour chaque instruction
ProcInstructionType instructionType;
ProcInstructionDurationType instructionDurationType;
int instructionRequestedDuration;
int instructionDecidedDuration;
ProcInstruction (ProcInstructionType t,
ProcInstructionDurationType d,
int r, int v);
}; // seront mises dans le tableau proGram
struct ProcData { // pour chaque programme/processus a simuler
string progName; // nom du fichier
vector<ProcInstruction> proGram;
ProcStatus procStatus;
unsigned int programCounter; // index dans proGram
int currentInstructionRemainingTime; // en secondes
time_t startTime; // Unix time du debut, reinitialise lors d'un 'fork'
// (ici on parle du 'DO_FORK' et non pas du fork() unix pour le IO)
int totalTime; // in seconds, Unix time at the end - startTime
// sommes des requested durations
unsigned int totalReqMinDuration; // toutes
unsigned int totalReqCPUDuration; // compute
unsigned int totalReqIODuration; // io
unsigned int totalReqSYSDuration; // fork
// sommes des instruction decided durations
unsigned int totalMinDuration; // toutes
unsigned int totalCPUDuration; // compute
unsigned int totalIODuration; // io
unsigned int totalSYSDuration; // fork
// ces quatre valeurs sont affichees sur les quatre dernieres colonnes
// par ProcInfo::dumpProcInfoStat()
unsigned int CPUusage; // accumulator, which can be reset
// cet accumulateur sert pour le multilevel queue
time_t waitDuration; // accumulator
time_t lastTimeEnQueued; // dans la waiting queue
int priorityLevel; // pour la multilevel queue
ProcData (const string &name = "<Anonymous>") ;
int parseProg (const string &fileLine,
unsigned int lineNumber,
const string &fileName); // ligne par ligne, pour
// empiler chaque fois un nouvel objet ProcInstruction dans proGram
void computeDuration ();
void computeWaitDuration ();
void resetCPUusage ();
int computePriorityLevel(); // for the multilevel queue
// ce qui suit est pour le pretty printing
int line2print;
static string linePad;
static unsigned int reqLength;
void setLinePad (const string &lp);
string procStatus2Str (char *pad = 0) const;
string progLine2Str (const unsigned int lineNumber) const;
string progCrtLine2Str () const;
string procStats () const;
void resetLine2StrGen ();
string nextLine2Str ();
};
map<pid_t,int> procSupp2procData; // pour faire correspondre
// le pid Unix avec le pid du programme/processus a simuler
// (ce dernier pid est un simple entier -- indice dans le tableau
// vector<ProcData> ProcInfo::procData qui contient les renseignements
// pour chaque processus)
// ces deux methodes sont appelees par updateProcData(), qui fait
// tout avancer; elles s'occupent de 'fork' et respectivement 'io',
// SI l'instruction courante est de ce type, sinon elles ne font rien
int doForkIfCrtInstruction(const int procPid);
int doIOIfCrtInstruction (const int procPid);
public:
vector<ProcData> procData; // indexe par les pids des
// programmes/processus a simuler
int outstandingProcCount; // decremente au fur et a
// mesure que les processus terminent
static const int invalidProcPid = -1;
double averageWaitDuration;
Scheduler *scheduler;
unsigned int longestProgramLength; // pretty printing
int progPerLine; // pretty printing
string lineSeparator; // pretty printing
ProcInfo();
ProcInfo(const string &);
void displayProcInfo (ostream *);
void dumpProcInfoStat (ostream *) const;
string getProcName (const int procPid) const;
void computePriorityLevel(); // pour la multilevel queue
void computeAverageWait ();
int updateProcData (const int procPid,
const ProcInfoOperType p,
int allotedTime = 0,
const pid_t supportPid = 0);
};