diff --git a/Sim02/config0.cnf b/Sim02/config0.cnf new file mode 100644 index 0000000..8a10b96 --- /dev/null +++ b/Sim02/config0.cnf @@ -0,0 +1,13 @@ +Start Simulator Configuration File: +Version/Phase : 1.05 +File Path : metadata5NoMem.mdf +CPU Scheduling Code : FCFS-N +Quantum Time (cycles) : 3 +Memory Available (KB) : 11100 +Memory Display (On/Off) : On +Processor Cycle Time (msec) : 10 +I/O Cycle Time (msec) : 20 +Log To : Both +Log File Path : logfile_1.lgf +End Simulator Configuration File. + diff --git a/Sim02/logfile_1.lgf b/Sim02/logfile_1.lgf new file mode 100644 index 0000000..e69de29 diff --git a/Sim02/metadata5NoMem.mdf b/Sim02/metadata5NoMem.mdf new file mode 100644 index 0000000..0336fb8 --- /dev/null +++ b/Sim02/metadata5NoMem.mdf @@ -0,0 +1,65 @@ +Start Program Meta-Data Code: +sys start +app start, 0 +dev in, serial, 28 +dev out, video signal, 42 +dev in, sound signal, 40 +dev out, hard drive, 15 +dev in, keyboard, 80 +dev in, serial, 28 +cpu process, 10 +cpu process, 8 +cpu process, 6 +dev out, video signal, 49 +app end +app start, 0 +dev in, serial, 20 +cpu process, 6 +cpu process, 8 +dev out, monitor, 70 +cpu process, 6 +cpu process, 9 +dev out, sound signal, 45 +dev out, hard drive, 15 +dev in, video signal, 49 +dev out, serial, 20 +app end +app start, 0 +dev in, hard drive, 18 +dev out, video signal, 49 +dev out, usb, 14 +dev out, monitor, 70 +cpu process, 7 +cpu process, 9 +dev in, keyboard, 70 +dev in, video signal, 42 +cpu process, 5 +cpu process, 6 +app end +app start, 0 +dev in, hard drive, 21 +dev out, sound signal, 30 +cpu process, 7 +dev in, keyboard, 80 +dev in, hard drive, 30 +dev out, video signal, 63 +dev in, serial, 28 +dev out, sound signal, 25 +cpu process, 9 +dev out, sound signal, 45 +app end +app start, 0 +dev in, serial, 24 +dev out, video signal, 42 +cpu process, 5 +dev in, usb, 10 +cpu process, 8 +cpu process, 9 +cpu process, 6 +dev out, hard drive, 18 +dev out, hard drive, 24 +dev out, hard drive, 21 +app end +sys end +End Program Meta-Data Code. + diff --git a/Sim02/sim02 b/Sim02/sim02 index 8ff2006..199358a 100755 Binary files a/Sim02/sim02 and b/Sim02/sim02 differ diff --git a/Sim02/simulator.c b/Sim02/simulator.c index 6869601..f271348 100644 --- a/Sim02/simulator.c +++ b/Sim02/simulator.c @@ -2,6 +2,7 @@ #include "metadataops.h" #include "StandardConstants.h" #include "simulator.h" +#include /* Name: addProcess @@ -26,12 +27,6 @@ ProcessControlBlock *addProcess(const ProcessControlBlock source) workingNode->timeLeft = source.timeLeft; workingNode->totalCycles = source.totalCycles; workingNode->nextPtr = NULL; - printf("uniquePID: %d\n", workingNode->uniquePid); - printf("process state: %d\n", workingNode->process_state); - printf("io cycles: %d\n", workingNode->ioCycles); - printf("cpu cycles: %d\n", workingNode->cpuCycles); - printf("total cycles: %d\n", workingNode->totalCycles); - printf("time left in ms: %f\n\n", workingNode->timeLeft); // return workingNode return workingNode; } @@ -117,7 +112,6 @@ ProcessControlBlockLL *fillProcessList(OpCodeType *metadataPtr, ProcessControlBl // initialize function/variables // need a working pointer for the metadata OpCodeType *wkgMetaPtr; - OpCodeType *wkgInternalPtr; ProcessControlBlock currentPCB; ProcessControlBlock *wkgPCBPtr; // need a variable to count how many IO cycles are in the process @@ -125,14 +119,12 @@ ProcessControlBlockLL *fillProcessList(OpCodeType *metadataPtr, ProcessControlBl // need a variable to count how many CPU cycles are in the process int cpuCycleCount = 0; // need a variable to calculate the time left in ms for a process - int timeLeftCount = 0; + double timeLeftCount = 0.0; // need a variable that fills PIDs, starting at 0 int processId = 0; // process variables? char *command; - char *commandInt; char *argument; - char *argumentInt; char *inOutArg; int integerArgumentOne; // unused as of current @@ -146,10 +138,16 @@ ProcessControlBlockLL *fillProcessList(OpCodeType *metadataPtr, ProcessControlBl // grab the first command and argument command = wkgMetaPtr->command; argument = wkgMetaPtr->strArg1; + inOutArg = wkgMetaPtr->inOutArg; + // integer argument two is unused atm + //integerArgumentTwo = wkgMetaPtr->intArg3; + // loop through the process list, until you hit a sys end. - while(wkgMetaPtr->nextNode != NULL || (compareString(argument, "end") && compareString(command, "sys"))) + while(wkgMetaPtr->nextNode != NULL && !(compareString(argument, "end") == 0 && compareString(command, "sys") == 0)) { + integerArgumentOne = wkgMetaPtr->intArg2; + // printf("%s command, %s argument, %d\n", command, argument, integerArgumentOne); // if app start, if (compareString(command, "app") && compareString(argument, "start")) { @@ -160,40 +158,42 @@ ProcessControlBlockLL *fillProcessList(OpCodeType *metadataPtr, ProcessControlBl currentPCB.process_state = PROCESS_STATE_NEW; // set the nextOpCode as a pointer to the first place metadataPtr started currentPCB.nextOpCode = wkgMetaPtr; - - // set the internal pointer to the location that wkgPtr is at - wkgInternalPtr = wkgMetaPtr; - // set the internal command and argument - commandInt = wkgInternalPtr->command; - argumentInt = wkgInternalPtr->strArg1; - inOutArg = wkgInternalPtr->inOutArg; - integerArgumentOne = wkgInternalPtr->intArg2; - // integer argument two is unused atm - //integerArgumentTwo = wkgInternalPtr->intArg3; - // loop while no longer have io or cpu instructions? (aka not at app end?) - while(wkgInternalPtr->nextNode != NULL || (compareString(argumentInt, "end") && compareString(commandInt, "app"))) + } + // + // count number of io cycles + // if ((compareString(command, "dev") == 0 && compareString(inOutArg, "in") == 0)) + // { + // integerArgumentOne = wkgMetaPtr->intArg2; + // ioCycleCount = ioCycleCount + integerArgumentOne; + // } + // if ((compareString(command, "dev") == 0 && compareString(inOutArg, "out") == 0)) + // { + // integerArgumentOne = wkgMetaPtr->intArg2; + // ioCycleCount = ioCycleCount + integerArgumentOne; + // } + if(compareString(command, "dev") == 0) + { + integerArgumentOne = wkgMetaPtr->intArg2; + if(compareString(inOutArg, "in") == 0) { - // count number of io cycles - if((compareString(commandInt, "dev") == 0 && compareString(inOutArg, "in") == 0)) - { - ioCycleCount = ioCycleCount + integerArgumentOne; - } - if((compareString(commandInt, "dev") == 0 && compareString(inOutArg, "out") == 0)) - { - ioCycleCount = ioCycleCount + integerArgumentOne; - } - // count number of cpu cycles - if((compareString(argumentInt, "process") == 0 && compareString(commandInt, "cpu") == 0)) - { - cpuCycleCount = cpuCycleCount + integerArgumentOne; - } - // move to next node, set relevant args - wkgInternalPtr = wkgInternalPtr->nextNode; - commandInt = wkgInternalPtr->command; - argumentInt = wkgInternalPtr->strArg1; - inOutArg = wkgInternalPtr->inOutArg; + // + ioCycleCount = ioCycleCount + integerArgumentOne; } + else + { + // + ioCycleCount = ioCycleCount + integerArgumentOne; + } + } + // count number of cpu cycles + if ((compareString(argument, "process") == 0 && compareString(command, "cpu") == 0)) + { + integerArgumentOne = wkgMetaPtr->intArg2; + cpuCycleCount = cpuCycleCount + integerArgumentOne; + } + if ((compareString(argument, "end") == 0 && compareString(command, "app") == 0)) + { // set the ioCycles from variable currentPCB.ioCycles = ioCycleCount; // set the cpuCycles from variable @@ -201,7 +201,7 @@ ProcessControlBlockLL *fillProcessList(OpCodeType *metadataPtr, ProcessControlBl // set totalCycles from adding both IO/CPU currentPCB.totalCycles = ioCycleCount + cpuCycleCount; // set the time left from (ioCycles * ioCycleRate) + (cpuCycles * procCyclesRate) - // this gets the number of ms in the process. + // this gets the number of ms in the process. currentPCB.timeLeft = timeLeftCount; // increment the PID counter processId = processId + 1; @@ -209,21 +209,64 @@ ProcessControlBlockLL *fillProcessList(OpCodeType *metadataPtr, ProcessControlBl ioCycleCount = 0; cpuCycleCount = 0; timeLeftCount = 0.0; + // needs to add nodes to the end and all data once parsed + // do both the metadata and PCBs + if(headPointer->headPtr == NULL) + { + // + headPointer->headPtr = addProcess(currentPCB); + wkgPCBPtr = headPointer->headPtr; + } + else + { + // + wkgPCBPtr->nextPtr = addProcess(currentPCB); + wkgPCBPtr = wkgPCBPtr->nextPtr; + } + } // move to the next bit of data wkgMetaPtr = wkgMetaPtr->nextNode; command = wkgMetaPtr->command; argument = wkgMetaPtr->strArg1; + inOutArg = wkgMetaPtr->inOutArg; - // needs to add nodes to the end and all data once parsed - // do both the metadata and PCBs - wkgPCBPtr = addProcess(currentPCB); - wkgPCBPtr = wkgPCBPtr->nextPtr; } // return null (temp) (should return the headpointer) return headPointer; } +/* +Name: logOutput +Process: Takes in a string, and then outputs it to monitor AND/OR file +Function Input/Parameters: string (char *), file pointer (FILE *), + configuration data (ConfigDataType *), + end of simulator (bool) +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Device: none +Dependencies: sprintf, ??? +*/ +void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd) +{ + FILE *fileWritePtr; + fileWritePtr = fopen(configPtr->logToFileName, "w"); + if(fileWritePtr != NULL) + { + // + printf("%s\n", logStr); + } + // no return, void + // close the file, if at the end. + // if(isEnd) + // { + // // + // fclose(fileWritePtr); + // } + fclose(fileWritePtr); +} + /* Name: runSim Process: primary simulation driver @@ -238,15 +281,21 @@ Dependencies: ??? void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) { // initialize function/variables - // need a FILE * for file operations - FILE *fileWritePtr; // need two working pointers, one for master loop, one for internal loop OpCodeType *wkgPtrMaster; // currentTime variable that stores the time. [now unsure if needed] // need a variable for headPointer to point ProcessControlBlockLL *pcbList; + ProcessControlBlock *pcbPtr; // string variable for nextCode, temp unused // char *nextCode; + // string variable for the timer stuff + char *simulatorOutput = "Simulator Start\n"; + + // Operating System start timer goes here, log it. + // sprintf(simulatorOutput, "Simulator start\n"); + logOutput(configPtr, simulatorOutput, false); + // int variable for process to run int currentPid; // create the process list with createProcessList, store the pointed to address @@ -256,34 +305,53 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) // create temp strings char *command; char *argument; + // int iterator + int pcbIterator; // get the first data out of the metadata command = metaDataMstrPtr->command; argument = metaDataMstrPtr->strArg1; // set the master working pointer to the first metadata block - wkgPtrMaster = metaDataMstrPtr; + // wkgPtrMaster = metaDataMstrPtr; + pcbPtr = pcbList->headPtr; + // set the current process id to the first scheduled process + currentPid = scheduleProcess(pcbList, configPtr); // function holds master loop, loops until sys end opcode found OR wkgPtrMaster nextNode != NULL - while(wkgPtrMaster->nextNode != NULL || (compareString(argument, "end") && compareString(command, "sys"))) + // while(wkgPtrMaster->nextNode != NULL && !(compareString(argument, "end") == 0 && compareString(command, "sys") == 0)) + // { + // currentPid = scheduleProcess(pcbList, configPtr); + // // will have a loop that goes from app start to app end for a PCB + // // (checks to see if the next instruction is NOT app end), using getNextProcess? + // // this will getNextOpCode + // // this will checkForIO and run the IO operations, outputting to FILE * and/or monitor + // // checkForIO will need the FILE * passed, will need timer access, and ??? + // // this will checkForCPU and run the CPU operations, outputting to FILE * and/or monitor + // // checkForCPU will need the FILE * passed, will need timer access, and ??? + // // move the wkgPtrMaster to the next metadata block + // wkgPtrMaster = wkgPtrMaster->nextNode; + // // set the command and argument to the current cmd and arg + // command = wkgPtrMaster->command; + // argument = wkgPtrMaster->strArg1; + // } + // loop until current process is hit + while(pcbPtr != NULL) { - currentPid = scheduleProcess(pcbList, configPtr); - // will have a loop that goes from app start to app end for a PCB - // (checks to see if the next instruction is NOT app end), using getNextProcess? - // this will getNextOpCode - // this will checkForIO and run the IO operations, outputting to FILE * and/or monitor - // checkForIO will need the FILE * passed, will need timer access, and ??? - // this will checkForCPU and run the CPU operations, outputting to FILE * and/or monitor - // checkForCPU will need the FILE * passed, will need timer access, and ??? - // move the wkgPtrMaster to the next metadata block - wkgPtrMaster = wkgPtrMaster->nextNode; - // set the command and argument to the current cmd and arg - command = wkgPtrMaster->command; - argument = wkgPtrMaster->strArg1; - } // + if(pcbPtr->uniquePid == currentPid) + { + // + printf("Process %d running", currentPid); + pcbPtr->process_state = PROCESS_STATE_TERMINATED; + } + pcbPtr = pcbPtr->nextPtr; + } + + // // deallocate the process list with destroyProcessList destroyProcessList(pcbList); // once complete, log the output to FILE if required + logOutput(configPtr, "", true); // void function, no return. } @@ -303,6 +371,7 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt ProcessControlBlock *wkgPtr; int returnPid = -1; wkgPtr = headPointer->headPtr; + char *loggingStr; // switch case for each scheduling algorithm switch (configPtr->cpuSchedCode) { @@ -312,20 +381,33 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt // need to find whichever process is first, AND the state is NEW. // will set the state to READY, return the pid of the process which // was set to ready. - // ignores any process which has a state of TERMINATED - // printf("uniquePID: %d\n", wkgPtr->uniquePid); - // printf("process state: %d\n", wkgPtr->process_state); - // printf("io cycles: %d\n", wkgPtr->ioCycles); - // printf("cpu cycles: %d\n", wkgPtr->cpuCycles); - // printf("total cycles: %d\n", wkgPtr->totalCycles); - // printf("time left in ms: %f\n", wkgPtr->timeLeft); - // while(wkgPtr->nextPtr != NULL || wkgPtr->process_state == PROCESS_STATE_NEW) - // { - // // - // returnPid = wkgPtr->uniquePid; - // printf("%d was selected.\n", returnPid); - // wkgPtr = wkgPtr->nextPtr; - // } + + // set every process in the list to READY from NEW + while(wkgPtr != NULL) + { + // + wkgPtr->process_state = PROCESS_STATE_READY; + //printf("Process %d set to READY from NEW\n", wkgPtr->uniquePid); + sprintf(loggingStr, "Process %d set to READY state from NEW state\n", wkgPtr->uniquePid); + logOutput(configPtr, loggingStr, false); + 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 terminated + if (wkgPtr->process_state == PROCESS_STATE_READY) + { + //printf("Process %d Selected with %.0f ms remaining\n", wkgPtr->uniquePid, wkgPtr->timeLeft); + sprintf(loggingStr, "Process %d selected with %.0f ms remaining\n", wkgPtr->uniquePid, wkgPtr->timeLeft); + logOutput(configPtr, loggingStr, false); + returnPid = wkgPtr->uniquePid; + } + // move to next pointer + wkgPtr = wkgPtr->nextPtr; + } break; case CPU_SCHED_FCFS_P_CODE: // TODO: First Come, First Served, Preemptive Scheduling diff --git a/Sim02/simulator.h b/Sim02/simulator.h index fc06d28..69bdff0 100644 --- a/Sim02/simulator.h +++ b/Sim02/simulator.h @@ -146,13 +146,16 @@ ProcessControlBlockLL *fillProcessList(OpCodeType *metadataPtr, ProcessControlBl /* Name: logOutput Process: Takes in a string, and then outputs it to monitor AND/OR file -Function Input/Parameters: string (char *), file pointer (FILE *) +Function Input/Parameters: string (char *), file pointer (FILE *), + configuration data (ConfigDataType *), + end of simulator (bool) Function Output/Parameters: none Function Output/Returned: none Device Input/Device: none Device Output/Device: none Dependencies: sprintf, ??? */ +void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd); /* Name: runSim