Finally gotten to the point with NO MORE WARNINGS!!! YAY
This commit is contained in:
parent
fda21f3cb6
commit
722df73955
4 changed files with 283 additions and 47 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue