Finally gotten to the point with NO MORE WARNINGS!!! YAY

This commit is contained in:
Charles Descamps 2024-04-18 22:05:38 -07:00
parent fda21f3cb6
commit 722df73955
4 changed files with 283 additions and 47 deletions

View file

@ -341,9 +341,35 @@ Device Input/Device: none
Device Output/Device: none
Dependencies: none
*/
void interruptManager()
bool interruptManager(ConfigDataType *configPtr, ProcessControlBlock *singlePCB, INTERRUPT_ROUTINE interruptRequest)
{
// need to check which interrupt service routine that is selected from the list
switch (interruptRequest)
{
case IO_RETURN:
// unset the PCB's state from blocked to ready.
singlePCB->process_state = PROCESS_STATE_READY;
return true;
break;
case QUANTUM_TIMEOUT:
// set something?
// this may need to stop the current process from running, and force a new one... not sure.
return true;
break;
case CPU_SWITCH:
// needs to switch to the next process, schedule to the next process?
return true;
break;
// case FOUR:
// /* code */
// break;
case CLEAR_INTERRUPT:
// COMMENT HERE
return false;
break;
}
//
return false;
}
/*
@ -610,28 +636,52 @@ Device Input/Device: none
Device Output/Device: none
Dependencies: pthreads, sprintf, logOutput, ???
*/
void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId)
void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr,
int processId, ProcessControlBlock *singlePCB, ConfigDataCodes schedMethod)
{
double timeDigits;
char timeStringy[MAX_STR_LEN];
// char *command = workingMeta->command;
// char *argument = workingMeta->strArg1;
// int intArg = workingMeta->intArg2;
char cpuOutput[MAX_STR_LEN];
char cpuOutput[MAX_STR_LEN * 4];
int cpuTime = 0;
int *cpuTimePtr = &cpuTime;
cpuTime = intArg * configPtr->procCycleRate;
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(cpuOutput, "%f, Process: %d, %s %s operation start\n", timeDigits, processId, command, argument);
logOutput(configPtr, cpuOutput, false);
// run timer for intArg * procCycleRate
pthread_t cpuThread;
pthread_create(&cpuThread, NULL, runTimer, (void *)cpuTimePtr);
pthread_join(cpuThread, NULL);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(cpuOutput, "%f, Process: %d, %s %s operation end\n", timeDigits, processId, command, argument);
logOutput(configPtr, cpuOutput, false);
// pthread_exit(NULL);
switch (schedMethod)
{
case NON_PREEMPTIVE_CODE:
cpuTime = intArg * configPtr->procCycleRate;
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(cpuOutput, "%f, Process: %d, %s %s operation start\n", timeDigits, processId, command, argument);
logOutput(configPtr, cpuOutput, false);
// run timer for intArg * procCycleRate
pthread_create(&cpuThread, NULL, runTimer, (void *)cpuTimePtr);
pthread_join(cpuThread, NULL);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(cpuOutput, "%f, Process: %d, %s %s operation end\n", timeDigits, processId, command, argument);
logOutput(configPtr, cpuOutput, false);
// pthread_exit(NULL);
break;
case PREEMPTIVE_CODE:
cpuTime = intArg * configPtr->procCycleRate;
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(cpuOutput, "%f, Process: %d, %s %s operation start\n", timeDigits, processId, command, argument);
logOutput(configPtr, cpuOutput, false);
// run timer for intArg * procCycleRate
pthread_create(&cpuThread, NULL, runTimer, (void *)cpuTimePtr);
pthread_join(cpuThread, NULL);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(cpuOutput, "%f, Process: %d, %s %s operation end\n", timeDigits, processId, command, argument);
logOutput(configPtr, cpuOutput, false);
break;
default:
// this should never happen... if it does, you'll know.
break;
}
}
/*
@ -644,23 +694,51 @@ Device Input/Device: none
Device Output/Device: none
Dependencies: pthreads, sprintf, logOutput, ???
*/
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId)
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr,
int processId, ProcessControlBlock *singlePCB, ConfigDataCodes schedMethod)
{
double timeDigits;
char timeStringy[MAX_STR_LEN];
char ioOutput[MAX_STR_LEN];
char ioOutput[MAX_STR_LEN * 4];
int ioTime = 0;
int *ioTimePtr = &ioTime;
ioTime = intArg * configPtr->ioCycleRate;
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(ioOutput, "%f, Process: %d, %s %s operation start\n", timeDigits, processId, command, argument);
logOutput(configPtr, ioOutput, false);
pthread_t ioThread;
pthread_create(&ioThread, NULL, runTimer, (void *)ioTimePtr);
pthread_join(ioThread, NULL);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(ioOutput, "%f, Process: %d, %s %s operation end\n", timeDigits, processId, command, argument);
logOutput(configPtr, ioOutput, false);
switch (schedMethod)
{
case NON_PREEMPTIVE_CODE:
ioTime = intArg * configPtr->ioCycleRate;
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(ioOutput, "%f, Process: %d, %s %s operation start\n", timeDigits, processId, command, argument);
logOutput(configPtr, ioOutput, false);
pthread_create(&ioThread, NULL, runTimer, (void *)ioTimePtr);
pthread_join(ioThread, NULL);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(ioOutput, "%f, Process: %d, %s %s operation end\n", timeDigits, processId, command, argument);
logOutput(configPtr, ioOutput, false);
break;
case PREEMPTIVE_CODE:
// need to set this to 'blocked' state here.
singlePCB->process_state = PROCESS_STATE_BLOCKED;
ioTime = intArg * configPtr->ioCycleRate;
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(ioOutput, "%f, Process: %d, %s %s operation start\n", timeDigits, processId, command, argument);
logOutput(configPtr, ioOutput, false);
pthread_create(&ioThread, NULL, runTimer, (void *)ioTimePtr);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(ioOutput, "%f, Process: %d, %s %s operation end\n", timeDigits, processId, command, argument);
logOutput(configPtr, ioOutput, false);
// pthread_join(ioThread, NULL); // not sure if this will be needed...
// pthread_exit(NULL); // this may be needed if pthread_join doesn't produce expected results.
// call the interruptManager here, with the IO Return code.
interruptManager(configPtr, singlePCB, IO_RETURN);
break;
default:
// this shouldn't happen, but if it does, you'll know...
break;
}
}
/*
@ -673,13 +751,14 @@ Device Input/Device: none
Device Output/Device: none
Dependencies: accessTimer, compareString, runCPU, runIO, ???
*/
void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr, ProcessControlBlockLL *pcbList)
void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr, ProcessControlBlockLL *pcbList,
ConfigDataCodes schedMethod)
{
double timeDigits;
// run over the entire process, running the CPU when a CPU cycle comes up
// or a run IO when an IO cycle comes up
char timeStringy[MAX_STR_LEN];
char processOutput[HUGE_STR_LEN];
char processOutput[HUGE_STR_LEN * 4];
// grab the next operation code for the
OpCodeType *workingMeta = singlePCB->nextOpCode;
char *command;
@ -701,12 +780,14 @@ void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr, Proce
if (compareString(command, "cpu") == EQUIV && compareString(argument, "process") == EQUIV)
{
// run the CPU for the required amount of time.
runCPU(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid);
runCPU(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid,
singlePCB, schedMethod);
}
if(compareString(command, "dev") == EQUIV)
{
// run IO operations for the required amount of time.
runIO(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid);
runIO(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid,
singlePCB, schedMethod);
}
if(compareString(command, "mem") == EQUIV)
{
@ -751,6 +832,17 @@ void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr, Proce
argument = workingMeta->strArg1;
intArg = workingMeta->intArg2;
intArgTwo = workingMeta->intArg3;
switch (schedMethod)
{
case PREEMPTIVE_CODE:
interruptManager(configPtr, singlePCB, CLEAR_INTERRUPT);
break;
default:
// this will only happen when NON_PREEMPTIVE is in progress, but
// warnings will result without having this here, so...
break;
}
}
// display the process exited, if not segfaulted.
if(memManagerSuccess)
@ -794,7 +886,8 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
// string variable for nextCode, temp unused
// char *nextCode;
// string variable for the timer stuff
char simulatorOutput[MAX_STR_LEN];
int schedulingMethod = configPtr->cpuSchedCode;
char simulatorOutput[MAX_STR_LEN * 4];
double timeDigits;
char timeStringy[MAX_STR_LEN];
int processCount = 0;
@ -802,6 +895,19 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
int memoryOffset = 0;
int memorySize = 1;
if (schedulingMethod == CPU_SCHED_FCFS_P_CODE ||
schedulingMethod == CPU_SCHED_RR_P_CODE ||
schedulingMethod == CPU_SCHED_SRTF_P_CODE)
{
// if in a preemptive scheduling method, set to PREEMPTIVE MODE
schedulingMethod = PREEMPTIVE_CODE;
}
else
{
// if in a non-preemptive scheduling method, set to NON_PREEMPTIVE MODE
schedulingMethod = NON_PREEMPTIVE_CODE;
}
accessTimer(ZERO_TIMER, timeStringy);
// Operating System start timer goes here, log it.
timeDigits = accessTimer(LAP_TIMER, timeStringy);
@ -858,13 +964,23 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
logOutput(configPtr, simulatorOutput, false);
pthread_t runThread;
pthread_create(&runThread, NULL, runTimer, (void *)processTimeLeftPtr);
runProcess(pcbPtr, configPtr, pcbList);
// when finished, set to terminated
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(simulatorOutput, "%f, OS: Process %d set to TERMINATED state from RUNNING state\n\n", timeDigits,
pcbPtr->uniquePid);
logOutput(configPtr, simulatorOutput, false);
pcbPtr->process_state = PROCESS_STATE_TERMINATED;
runProcess(pcbPtr, configPtr, pcbList, schedulingMethod);
switch (schedulingMethod)
{
case NON_PREEMPTIVE_CODE:
// when finished, set to terminated
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(simulatorOutput, "%f, OS: Process %d set to TERMINATED state from RUNNING state\n\n", timeDigits,
pcbPtr->uniquePid);
logOutput(configPtr, simulatorOutput, false);
// this assumes that the processes finish executing all the way though.
pcbPtr->process_state = PROCESS_STATE_TERMINATED;
break;
case PREEMPTIVE_CODE:
// will need to instead, set the next process up?
interruptManager(configPtr, pcbPtr, CPU_SWITCH);
break;
}
pthread_join(runThread, NULL);
}
processTimeLeft = pcbPtr->timeLeft;
@ -973,9 +1089,55 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt
break;
case CPU_SCHED_FCFS_P_CODE:
// TODO: First Come, First Served, Preemptive Scheduling
// try copying the previous code, making sure that if it is in a
// blocked state, it cannot be scheduled,
// if it is in a waiting state, then it can be scheduled.
// can also be scheduled or not based on the previous section of
// code as well.
while (wkgPtr != NULL)
{
//
if (wkgPtr->process_state == PROCESS_STATE_NEW)
{
// set the process within the PCB to the ready state, report in ready state.
wkgPtr->process_state = PROCESS_STATE_READY;
// printf("Process %d set to READY from NEW\n", wkgPtr->uniquePid);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(loggingStr, "%f, OS: Process %d set to READY state from NEW state\n", timeDigits,
wkgPtr->uniquePid);
logOutput(configPtr, loggingStr, false);
}
// move to the next pointer
wkgPtr = wkgPtr->nextPtr;
}
// reset the pointer to get ready for selection of process
wkgPtr = headPointer->headPtr;
while (wkgPtr != NULL && (returnPid == -1))
{
// check if the process is NOT running, terminated OR blocked.
if (wkgPtr->process_state != PROCESS_STATE_RUNNING &&
wkgPtr->process_state != PROCESS_STATE_TERMINATED &&
wkgPtr->process_state != PROCESS_STATE_BLOCKED)
{
// printf("Process %d Selected with %.0f ms remaining\n", wkgPtr->uniquePid, wkgPtr->timeLeft);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(loggingStr, "%f, OS: Process %d selected with %.0f ms remaining\n", timeDigits,
wkgPtr->uniquePid, wkgPtr->timeLeft);
logOutput(configPtr, loggingStr, false);
returnPid = wkgPtr->uniquePid;
}
// move to next pointer
wkgPtr = wkgPtr->nextPtr;
}
break;
case CPU_SCHED_RR_P_CODE:
// TODO: Round Robin Scheduling
// need to FCFS first. however, just rotate through each process.
// maybe keep track via an array or previously used process? not sure how exactly I want this.
// maybe an extern??? not sure how to essentially keep track even when scope is lost here.
// actually, I think a static variable may be the key to solving this.
// alternatively, I could use a circularly linked list, given that proper scheduling is done.
break;
case CPU_SCHED_SJF_N_CODE:
// Shortest Job First Scheduling
@ -1053,6 +1215,77 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt
break;
case CPU_SCHED_SRTF_P_CODE:
// TODO: Shortest Run-time First Scheduling
// may be able to copy the same code that I've used above, just
// with more restrictive rules similarly to the FCFS described above.
while (wkgPtr != NULL)
{
//
if (wkgPtr->process_state == PROCESS_STATE_NEW)
{
// set the process within the PCB to the ready state, report in ready state.
wkgPtr->process_state = PROCESS_STATE_READY;
// printf("Process %d set to READY from NEW\n", wkgPtr->uniquePid);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(loggingStr, "%f, OS: Process %d set to READY state from NEW state\n", timeDigits,
wkgPtr->uniquePid);
logOutput(configPtr, loggingStr, false);
}
// move to the next pointer
wkgPtr = wkgPtr->nextPtr;
}
// reset the pointer to get ready for selection of process
wkgPtr = headPointer->headPtr;
// load in the first process time
shortestJob = wkgPtr->timeLeft;
// move to the next pointer.
wkgPtr = wkgPtr->nextPtr;
while (wkgPtr != NULL && (returnPid == -1))
{
// check if the process is NOT terminated and NOT blocked. (can only be waiting)
// now, ALSO needs to check which process takes the least time.
if (wkgPtr->process_state != PROCESS_STATE_RUNNING &&
wkgPtr->process_state != PROCESS_STATE_TERMINATED &&
wkgPtr->process_state != PROCESS_STATE_BLOCKED)
{
// check to see if the working pointer job is shorter than the current shortest job
shortestJob = findMin(shortestJob, wkgPtr->timeLeft);
// check to see if the shortest job time changed, if it did, change the process number
if (shortestJob == wkgPtr->timeLeft)
{
// change process number, or leave it unchanged.
shortestJobProcNum = wkgPtr->uniquePid;
}
}
// move to next pointer
wkgPtr = wkgPtr->nextPtr;
}
// check the number of processes, if there is one left, then
wkgPtr = headPointer->headPtr;
if (processCount == 1)
{
// find the last process that is READY but not TERMINATED, set it's PID as the return.
while (wkgPtr != NULL)
{
//
if (wkgPtr->process_state != PROCESS_STATE_TERMINATED)
{
//
shortestJobProcNum = wkgPtr->uniquePid;
shortestJob = wkgPtr->timeLeft;
}
wkgPtr = wkgPtr->nextPtr;
}
}
if (processCount != 0)
{
// printf("Process %d Selected with %.0f ms remaining\n", wkgPtr->uniquePid, wkgPtr->timeLeft);
timeDigits = accessTimer(LAP_TIMER, timeStringy);
sprintf(loggingStr, "%f, OS: Process %d selected with %.0f ms remaining\n", timeDigits,
shortestJobProcNum, (double)shortestJob);
logOutput(configPtr, loggingStr, false);
}
returnPid = shortestJobProcNum;
break;
}
// return returnPid