From d98c6640027ef69c77fb074783f2721fc1ea96cb Mon Sep 17 00:00:00 2001 From: cdez Date: Sun, 21 Apr 2024 10:34:25 -0700 Subject: [PATCH] Revert "Merge branch 'main' of https://git.cdezselfhosted.pw/cdez/CS480-Projects" This reverts commit 37aa8c3b81b1204fbbee3837ee67854da226eb79, reversing changes made to d5705e42a478c00e5d003f57711f68227a9f85fd. --- Sim03/Sim03_GradingForm_413499.xlsx | Bin 22830 -> 0 bytes Sim03/logfile_1.lgf | 8 +- Sim03/sim03_mf | 2 +- Sim03/simtimer.c | 41 +- Sim03/simtimer.h | 2 +- Sim03/simulator.c | 687 +++----------- Sim03/simulator.h | 168 +--- Sim04/OS_SimDriver.c | 246 ----- Sim04/OS_SimDriver.h | 74 -- Sim04/StandardConstants.h | 79 -- Sim04/StringUtils.c | 454 ---------- Sim04/StringUtils.h | 176 ---- Sim04/config0.cnf | 13 - Sim04/configops.c | 608 ------------- Sim04/configops.h | 168 ---- Sim04/logfile_1.lgf | 0 Sim04/metadata5.mdf | 75 -- Sim04/metadataops.c | 729 --------------- Sim04/metadataops.h | 207 ----- Sim04/sim04 | Bin 73944 -> 0 bytes Sim04/sim04_mf | 32 - Sim04/simtimer.c | 270 ------ Sim04/simtimer.h | 49 - Sim04/simulator.c | 1293 --------------------------- Sim04/simulator.h | 232 ----- Sim04/testfile-dnw.mdf | 86 -- Sim04/testfile.cnf | 12 - Sim04/testfile.mdf | 40 - 28 files changed, 142 insertions(+), 5609 deletions(-) delete mode 100644 Sim03/Sim03_GradingForm_413499.xlsx delete mode 100644 Sim04/OS_SimDriver.c delete mode 100644 Sim04/OS_SimDriver.h delete mode 100644 Sim04/StandardConstants.h delete mode 100644 Sim04/StringUtils.c delete mode 100644 Sim04/StringUtils.h delete mode 100644 Sim04/config0.cnf delete mode 100644 Sim04/configops.c delete mode 100644 Sim04/configops.h delete mode 100644 Sim04/logfile_1.lgf delete mode 100644 Sim04/metadata5.mdf delete mode 100644 Sim04/metadataops.c delete mode 100644 Sim04/metadataops.h delete mode 100755 Sim04/sim04 delete mode 100644 Sim04/sim04_mf delete mode 100644 Sim04/simtimer.c delete mode 100644 Sim04/simtimer.h delete mode 100644 Sim04/simulator.c delete mode 100644 Sim04/simulator.h delete mode 100644 Sim04/testfile-dnw.mdf delete mode 100644 Sim04/testfile.cnf delete mode 100644 Sim04/testfile.mdf diff --git a/Sim03/Sim03_GradingForm_413499.xlsx b/Sim03/Sim03_GradingForm_413499.xlsx deleted file mode 100644 index 5d4670dbd09d264c143ba68e1ea173b8a3f18301..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22830 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 = malloc(sizeof(source.stringData)); - // get each value from the source, and set their values - copyString(workingNode->stringData, source.stringData); - // make sure to set the next pointer to NULL! - workingNode->nextPtr = NULL; - // return workingNode - return workingNode; + // no return, void (temp) } /* @@ -68,9 +40,6 @@ ProcessControlBlock *addProcess(const ProcessControlBlock source) workingNode->process_state = source.process_state; workingNode->timeLeft = source.timeLeft; workingNode->totalCycles = source.totalCycles; - workingNode->allocatedMemOffsets = (int *) malloc(sizeof(int) * source.memArraySize); - workingNode->allocatedMemSizes = (int *) malloc(sizeof(int) * source.memArraySize); - workingNode->memArraySize = source.memArraySize; // make sure to set the next pointer to NULL! workingNode->nextPtr = NULL; // return workingNode @@ -82,46 +51,14 @@ Name: allocMemory Process: 'allocates' memory within the PCB, stores offset and size within it's PCB Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int) Function Output/Parameters: none -Function Output/Returned: boolean to indicate success or failure of allocated memory +Function Output/Returned: none? Device Input/Device: none Device Output/Device: none Dependencies: ??? */ -bool allocMemory(ProcessControlBlock *singlePCB, int offset, int size, int arraySize) +void allocMemory(ProcessControlBlock *singlePCB, int offset, int size) { - int allocateIterator = 0; - // while until a '-1' is hit, then store the value. - while(singlePCB->allocatedMemSizes[allocateIterator] != -1 && allocateIterator < arraySize) - { - // - singlePCB->allocatedMemOffsets[allocateIterator] = offset; - singlePCB->allocatedMemSizes[allocateIterator] = size; - allocateIterator = allocateIterator + 1; - // printf("Alloc Iter: %d\n", allocateIterator); - } - // return true (temp) - return true; -} - -/* -Name: createFileLogList -Process: initializes the logging file struct -Function Input/Parameters: none -Function Output/Parameters: none -Function Output/Returned: head pointer to the logfile struct -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, sizeof, ??? -*/ -logFileLL *createFileLogList() -{ - // allocate and create the logFileLL using malloc and size of - logFileLL *headBlock; - headBlock = malloc(sizeof(logFileLL)); - // set the head pointer to NULL - headBlock->headPtr = NULL; - // return headBlock - return headBlock; + // no return, void (temp) } /* @@ -147,46 +84,17 @@ ProcessControlBlockLL *createProcessList() /* Name: deallocMemory -Process: 'deallocates' memory within the PCB, removes every offset and size within it's PCB -Function Input/Parameters: source PCB (ProcessControlBlock *) +Process: 'deallocates' memory within the PCB, removes offset and size within it's PCB +Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int) Function Output/Parameters: none -Function Output/Returned: boolean to indicate success or failure of allocated memory +Function Output/Returned: none? Device Input/Device: none Device Output/Device: none Dependencies: ??? */ -bool deallocMemory(ProcessControlBlock *singlePCB, int arraySize) +void deallocMemory(ProcessControlBlock *singlePCB, int offset, int size) { - int deallocateIterator; - // while until a '-1' is hit, then store the value. - for (deallocateIterator = 0; deallocateIterator < arraySize; deallocateIterator++) - { - // - singlePCB->allocatedMemOffsets[deallocateIterator] = -1; - singlePCB->allocatedMemSizes[deallocateIterator] = -1; - } - // return true (temp) - return true; -} - -/* -Name: destroyFileLogList -Process: deallocates memory used for the linked list struct -Function Input/Parameters: head pointer to linked list (logFileLL *) -Function Output/Parameters: none -Function Output/Returned: NULL -Device Input/Device: none -Device Output/Device: none -Dependencies: free, destroyFileLogHelper, ??? -*/ -logFileLL *destroyFileLogList(logFileLL *linkedListPtr) -{ - // call the first destroyFileLogHelper - destroyFileLogHelper(linkedListPtr->headPtr); - // free the rest of the struct - free(linkedListPtr); - // return null - return NULL; + // no return, void (temp) } /* @@ -209,30 +117,6 @@ ProcessControlBlockLL *destroyProcessList(ProcessControlBlockLL *linkedListPtr) return NULL; } -/* -Name: destroyFileLogHelper -Process: recursively clears the logfile linked list struct, freeing the struct -Function Input/Parameters: head pointer to logfile list (logFile *) -Function Output/Parameters: none -Function Output/Returned: NULL -Device Input/Device: none -Device Output/Device: none -Dependencies: free, destroyFileLogHelper(recursively), ??? -*/ -logFile *destroyFileLogHelper(logFile *nodePtr) -{ - // check to see if the pointer is NOT null - if (nodePtr != NULL) - { - // if not null, move to the next pointer (recurse) - nodePtr->nextPtr = destroyFileLogHelper(nodePtr->nextPtr); - } - // free the 'parent' node - free(nodePtr); - // return null - return NULL; -} - /* Name: destroyProcessListHelper Process: recursively clears the PCB linked list struct, freeing the struct @@ -248,8 +132,6 @@ ProcessControlBlock *destroyProcessListHelper(ProcessControlBlock *nodePtr) // check to see if the pointer is NOT null if(nodePtr != NULL) { - free(nodePtr->allocatedMemOffsets); - free(nodePtr->allocatedMemSizes); // if not null, move to the next pointer (recurse) nodePtr->nextPtr = destroyProcessListHelper(nodePtr->nextPtr); } @@ -286,8 +168,6 @@ ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *me double timeLeftCount = 0.0; // need a variable that fills PIDs, starting at 0 int processId = 0; - // need a variable that checks how many allocate statements there are. - int memAllocation = 0; // process variables? char *command; char *argument; @@ -346,12 +226,6 @@ ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *me cpuCycleCount = cpuCycleCount + integerArgumentOne; } - // count number of times memory is done, sub checks for how many allocates, accesses, etc. - if ((compareString(argument, "allocate") == EQUIV && compareString(command, "mem") == EQUIV)) - { - // allocate the memory - memAllocation = memAllocation + 1; - } if ((compareString(argument, "end") == EQUIV && compareString(command, "app") == EQUIV)) { // set the ioCycles from variable @@ -360,9 +234,6 @@ ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *me currentPCB.cpuCycles = cpuCycleCount; // set totalCycles from adding both IO/CPU currentPCB.totalCycles = ioCycleCount + cpuCycleCount; - // set number of allocations from variable, then reset. - currentPCB.memArraySize = memAllocation; - memAllocation = 0; // currentPCB must have the starting instruction from wkgInsPtr wkgInsPtr = wkgMetaPtr; @@ -434,350 +305,48 @@ Device Input/Device: none Device Output/Device: none Dependencies: fprintf, ??? */ -logFileLL *logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd, logFileLL *logPtr) +void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd) { - logFile toLog; - // toLog.stringData = malloc(sizeof(*logStr)); - logFile *wkgLogPtr; - wkgLogPtr = logPtr->headPtr; - if (configPtr->logToCode == LOGTO_BOTH_CODE) + if(configPtr->logToCode == LOGTO_BOTH_CODE) { + // + FILE *fileWritePtr; + fileWritePtr = fopen(configPtr->logToFileName, "w+"); + if (fileWritePtr != NULL) + { + fprintf(fileWritePtr, "%s", logStr); + fprintf(stdout, "%s", logStr); + } + // no return, void // close the file, if at the end. if (isEnd) { - FILE *fileWritePtr; - fileWritePtr = fopen(configPtr->logToFileName, "w"); - if (fileWritePtr != NULL) - { - // - while(wkgLogPtr != NULL) - { - // - printf("Data being written."); - fprintf(fileWritePtr, "%s", wkgLogPtr->stringData); - wkgLogPtr = wkgLogPtr->nextPtr; - } - } fclose(fileWritePtr); } - else - { - // need to add the string to the end of the LL. - // fprintf(fileWritePtr, "%s", logStr); - copyString(toLog.stringData, logStr); - toLog.nextPtr = NULL; - while(wkgLogPtr != NULL) //wkgLogPtr->nextPtr != NULL - { - // need to add at the end of the LL. - // if (logPtr->headPtr == NULL) - // { - // printf("Added to log."); - // logPtr->headPtr = addLog(toLog); - // // wkgLogPtr = logPtr->headPtr; - // } - // else - // { - // while(wkgLogPtr != NULL) - // { - // printf("Added to log at end."); - // wkgLogPtr->nextPtr = addLog(toLog); - // wkgLogPtr = addLog(toLog); - // wkgLogPtr = wkgLogPtr->nextPtr; - // - // } - // } - wkgLogPtr = wkgLogPtr->nextPtr; - } - // if (wkgLogPtr == NULL) - // { - // // - // printf("Added to end of log."); - // wkgLogPtr = addLog(toLog); - // } - if (logPtr->headPtr == NULL) - { - printf("Added to log."); - logPtr->headPtr = addLog(toLog); - // wkgLogPtr = logPtr->headPtr; - } - // wkgLogPtr->nextPtr = addLog(toLog); - fprintf(stdout, "%s", logStr); - } + // fclose(fileWritePtr); } - else if (configPtr->logToCode == LOGTO_FILE_CODE) + else if(configPtr->logToCode == LOGTO_FILE_CODE) { + // + printf("\nSimulator will output to a file.\n"); + FILE *fileWritePtr; + fileWritePtr = fopen(configPtr->logToFileName, "w+"); + if (fileWritePtr != NULL) + { + fprintf(fileWritePtr, "%s", logStr); + } + // no return, void // close the file, if at the end. - // if (isEnd) - // { - // printf("\nSimulator will output to a file.\n"); - // FILE *fileWritePtr; - // fileWritePtr = fopen(configPtr->logToFileName, "w"); - // if (fileWritePtr != NULL) - // { - // // - // while(wkgLogPtr->nextPtr != NULL) - // { - // // - // fprintf(fileWritePtr, "%s", wkgLogPtr->stringData); - // wkgLogPtr = wkgLogPtr->nextPtr; - // } - // } - // fclose(fileWritePtr); - // } - // else - // { - // // need to add the string to the end of the LL. - // // fprintf(fileWritePtr, "%s", logStr); - // copyString(toLog.stringData, logStr); - // toLog.nextPtr = NULL; - // while(wkgLogPtr->nextPtr != NULL) - // { - // // - // wkgLogPtr = wkgLogPtr->nextPtr; - // } - // wkgLogPtr->nextPtr = addLog(toLog); - // // fprintf(stdout, "%s", logStr); - // } + if (isEnd) + { + fclose(fileWritePtr); + } + // fclose(fileWritePtr); } else { fprintf(stdout, "%s", logStr); } - // if(configPtr->logToCode == LOGTO_BOTH_CODE) - // { - // // - // FILE *fileWritePtr; - // fileWritePtr = fopen(configPtr->logToFileName, "w+"); - // if (fileWritePtr != NULL) - // { - // fprintf(fileWritePtr, "%s", logStr); - // fprintf(stdout, "%s", logStr); - // } - // // no return, void - // // close the file, if at the end. - // if (isEnd) - // { - // fclose(fileWritePtr); - // } - // // fclose(fileWritePtr); - // } - // else if(configPtr->logToCode == LOGTO_FILE_CODE) - // { - // // - // printf("\nSimulator will output to a file.\n"); - // FILE *fileWritePtr; - // fileWritePtr = fopen(configPtr->logToFileName, "w+"); - // if (fileWritePtr != NULL) - // { - // fprintf(fileWritePtr, "%s", logStr); - // } - // // no return, void - // // close the file, if at the end. - // if (isEnd) - // { - // fclose(fileWritePtr); - // } - // // fclose(fileWritePtr); - // } - // else - // { - // fprintf(stdout, "%s", logStr); - // } - return logPtr; -} - -/* -Name: memManager -Process: checks to make sure an allocate will be successful, - makes sure that an access will not segfault (or return segfault if it does), - and initializes memory and deallocates memory -Function Input/Parameters: PCBList (ProcessControlBlockLL *), memory code (MEMORY_SIGNALS), - offset (int), size (int), configuration data (ConfigDataType *) -Function Output/Parameters: none -Function Output/Returned: boolean for success or failure of memory management -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool memManager(ProcessControlBlockLL *pcbList, MEMORY_SIGNALS memCode, int offset, int size, ConfigDataType *configPtr, ProcessControlBlock *singlePCB, logFileLL *logList) -{ - bool memDisplay = configPtr->memDisplay; - ProcessControlBlock *wkgPtr; - int availableMem = configPtr->memAvailable; - int usedMem = 0; - int currentOffset = 0; - int currentSize = 0; - int memIterator; - int *memorySizeArray; - int totalArraySize = 0; - bool subFunctionSuccess = true; - wkgPtr = pcbList->headPtr; - - // grab how much memory is being used total, then count how big the total memory array should be - while(wkgPtr != NULL) - { - // count up the total used memory within each process control block. - for(memIterator = 0; memIterator < wkgPtr->memArraySize; memIterator++) - { - if(wkgPtr->allocatedMemSizes[memIterator] != -1) - { - // grab how much memory is used by that process - usedMem = usedMem + wkgPtr->allocatedMemSizes[memIterator]; - } - totalArraySize = totalArraySize + 1; - } - // move to the next pointer - wkgPtr = wkgPtr->nextPtr; - } - - // reset the working pointer - wkgPtr = pcbList->headPtr; - - // declare the array for the memory - memorySizeArray = malloc(sizeof(int) * totalArraySize); - - // grab the entire memory structure, so that the memory can be contiguous - while (wkgPtr != NULL) - { - // count up the total used memory within each process control block. - for (memIterator = 0; memIterator < totalArraySize; memIterator++) - { - // grab how much memory is used by that process - memorySizeArray[memIterator] = wkgPtr->allocatedMemSizes[memIterator]; - } - // move to the next pointer - wkgPtr = wkgPtr->nextPtr; - } - - // grab the size of the - // while() - // { - // // - // } - - // switch case for each memory code - switch (memCode) - { - case MEMORY_INITIALIZE: - for(memIterator = 0; memIterator < singlePCB->memArraySize; memIterator++) - { - // initialize the arrays with all '-1' to 'nullify' the memory, make it easier to iterate through later - singlePCB->allocatedMemOffsets[memIterator] = -1; - singlePCB->allocatedMemSizes[memIterator] = -1; - } - if(memDisplay) - { - // - printf("--------------------------------------------------\n"); - printf("After memory initialization\n"); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - break; - - case MEMORY_ALLOCATE: - // check if the memory allocation can happen before storing it. - if(size <= availableMem - usedMem + 1) - { - // grab the offset and size, store it, using the allocate memory function. - subFunctionSuccess = allocMemory(singlePCB, offset, size, singlePCB->memArraySize); - usedMem = usedMem + size; - } - else - { - // set the subfunction success to false. - subFunctionSuccess = false; - } - // if the function returns true, then it successfully did the operation, display as such. - if (memDisplay) - { - if(subFunctionSuccess) - { - // - printf("--------------------------------------------------\n"); - printf("After memory allocation\n"); - printf("%d [ Used, P#: %d, %d-%d ] %d\n", offset - offset, singlePCB->uniquePid, offset, offset + size - 1, size - 1); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - else - { - // - printf("--------------------------------------------------\n"); - printf("After memory allocation failure\n"); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - } - break; - - case MEMORY_ACCESS: - // printf("Used memory at current: %d\n", usedMem); - subFunctionSuccess = accessMemory(singlePCB, offset, size); - if (memDisplay) - { - if (subFunctionSuccess) - { - // - printf("--------------------------------------------------\n"); - printf("After access success\n"); - printf("%d [ Used, P#: %d, %d-%d ] %d\n", offset - offset, singlePCB->uniquePid, offset, offset + size - 1, size - 1); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - else - { - // - printf("--------------------------------------------------\n"); - printf("After access failure\n"); - printf("%d [ Used, P#: %d, %d-%d ] %d\n", offset - offset, singlePCB->uniquePid, offset, offset + size - 1, size - 1); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - } - break; - - case MEMORY_DEALLOCATE: - subFunctionSuccess = deallocMemory(singlePCB, singlePCB->memArraySize); - if (memDisplay) - { - if (subFunctionSuccess) - { - // THIS SHOULD ALWAYS HAPPEN. - printf("--------------------------------------------------\n"); - printf("After clear process %d success\n", singlePCB->uniquePid); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem - usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - else - { - // THIS SHOULD NEVER HAPPEN. - printf("--------------------------------------------------\n"); - printf("After clear process %d failure\n", singlePCB->uniquePid); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem - usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - } - break; - - case MEMORY_CLEAR: - if (memDisplay) - { - // this will happen regardless. Will always be cleaning up memory with dealloc. - printf("--------------------------------------------------\n"); - printf("After memory clear\n"); - printf("No memory configured\n"); - printf("--------------------------------------------------\n"); - } - break; - - default: - break; - } - // clear out the dynamic array - free(memorySizeArray); - // return if the subfunction succeeded, if applicable - return subFunctionSuccess; } /* @@ -830,7 +399,7 @@ Device Input/Device: none Device Output/Device: none Dependencies: pthreads, sprintf, logOutput, ??? */ -void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId, logFileLL *logList) +void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId) { char timeStringy[MAX_STR_LEN]; // char *command = workingMeta->command; @@ -838,16 +407,15 @@ void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr // int intArg = workingMeta->intArg2; char cpuOutput[MAX_STR_LEN]; int cpuTime = 0; - int *cpuTimePtr = &cpuTime; cpuTime = intArg * configPtr->procCycleRate; sprintf(cpuOutput, "%f, Process: %d, %s %s operation start\n", accessTimer(LAP_TIMER, timeStringy), processId, command, argument); - logOutput(configPtr, cpuOutput, false, logList); + logOutput(configPtr, cpuOutput, false); // run timer for intArg * procCycleRate pthread_t cpuThread; - pthread_create(&cpuThread, NULL, runTimer, (void *)cpuTimePtr); + pthread_create(&cpuThread, NULL, (void *)&simThread, (void *)cpuTime); pthread_join(cpuThread, NULL); sprintf(cpuOutput, "%f, Process: %d, %s %s operation end\n", accessTimer(LAP_TIMER, timeStringy), processId, command, argument); - logOutput(configPtr, cpuOutput, false, logList); + logOutput(configPtr, cpuOutput, false); // pthread_exit(NULL); } @@ -861,20 +429,19 @@ Device Input/Device: none Device Output/Device: none Dependencies: pthreads, sprintf, logOutput, ??? */ -void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId, logFileLL *logList) +void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId) { char timeStringy[MAX_STR_LEN]; char ioOutput[MAX_STR_LEN]; int ioTime = 0; - int *ioTimePtr = &ioTime; ioTime = intArg * configPtr->ioCycleRate; sprintf(ioOutput, "%f, Process: %d, %s %s operation start\n", accessTimer(LAP_TIMER, timeStringy), processId, command, argument); - logOutput(configPtr, ioOutput, false, logList); + logOutput(configPtr, ioOutput, false); pthread_t ioThread; - pthread_create(&ioThread, NULL, runTimer, (void *)ioTimePtr); + pthread_create(&ioThread, NULL, (void *)&simThread, (void *)ioTime); pthread_join(ioThread, NULL); sprintf(ioOutput, "%f, Process: %d, %s %s operation end\n", accessTimer(LAP_TIMER, timeStringy), processId, command, argument); - logOutput(configPtr, ioOutput, false, logList); + logOutput(configPtr, ioOutput, false); } /* @@ -887,89 +454,39 @@ Device Input/Device: none Device Output/Device: none Dependencies: accessTimer, compareString, runCPU, runIO, ??? */ -void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr, ProcessControlBlockLL *pcbList, logFileLL *logList) +void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr) { // 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]; // grab the next operation code for the OpCodeType *workingMeta = singlePCB->nextOpCode; char *command; char *argument; int intArg; - int intArgTwo; - bool memManagerSuccess = true; - // char *inOutArg; + char *inOutArg; command = workingMeta->command; argument = workingMeta->strArg1; intArg = workingMeta->intArg2; - intArgTwo = workingMeta->intArg3; - // inOutArg = workingMeta->inOutArg; - while (!(compareString(command, "app") == EQUIV && compareString(argument, "end") == EQUIV) && !(compareString(command, "sys") == EQUIV && compareString(argument, "end") == EQUIV) && memManagerSuccess) + inOutArg = workingMeta->inOutArg; + while (!(compareString(command, "app") == EQUIV && compareString(argument, "end") == EQUIV) && !(compareString(command, "sys") == EQUIV && compareString(argument, "end") == EQUIV)) { // check to see what operation will be performed 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, logList); + runCPU(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid); } if(compareString(command, "dev") == EQUIV) { // run IO operations for the required amount of time. - runIO(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid, logList); - } - if(compareString(command, "mem") == EQUIV) - { - // run memory operations with the memory manager - if(compareString(argument, "allocate") == EQUIV) - { - sprintf(processOutput, "%f, Process: %d, %s %s request (%d, %d)\n", accessTimer(LAP_TIMER, timeStringy), singlePCB->uniquePid, command, argument, intArg, intArgTwo); - logOutput(configPtr, processOutput, false, logList); - // run the memory manager in allocate mode - memManagerSuccess = memManager(pcbList, MEMORY_ALLOCATE, intArg, intArgTwo, configPtr, singlePCB, logList); - if(!memManagerSuccess) - { - // - sprintf(processOutput, "%f, Process: %d, failed %s %s request (%d, %d)\n", accessTimer(LAP_TIMER, timeStringy), singlePCB->uniquePid, command, argument, intArg, intArgTwo); - logOutput(configPtr, processOutput, false, logList); - } - } - else if(compareString(argument, "access") == EQUIV) - { - sprintf(processOutput, "%f, Process: %d, %s %s request (%d, %d)\n", accessTimer(LAP_TIMER, timeStringy), singlePCB->uniquePid, command, argument, intArg, intArgTwo); - logOutput(configPtr, processOutput, false, logList); - // run the memory manager in access mode - memManagerSuccess = memManager(pcbList, MEMORY_ACCESS, intArg, intArgTwo, configPtr, singlePCB, logList); - if (!memManagerSuccess) - { - // - sprintf(processOutput, "%f, Process: %d, failed %s %s request (%d, %d)\n", accessTimer(LAP_TIMER, timeStringy), singlePCB->uniquePid, command, argument, intArg, intArgTwo); - logOutput(configPtr, processOutput, false, logList); - } - } + runIO(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid); } workingMeta = workingMeta->nextNode; command = workingMeta->command; argument = workingMeta->strArg1; intArg = workingMeta->intArg2; - intArgTwo = workingMeta->intArg3; } - // display the process exited, if not segfaulted. - if(memManagerSuccess) - { - // - sprintf(processOutput, "\n%f, OS: Process %d ended\n", accessTimer(LAP_TIMER, timeStringy), singlePCB->uniquePid); - logOutput(configPtr, processOutput, false, logList); - } - else - { - // - sprintf(processOutput, "\n%f, OS: Segmentation Fault, Process %d ended\n", accessTimer(LAP_TIMER, timeStringy), singlePCB->uniquePid); - logOutput(configPtr, processOutput, false, logList); - } - // deallocate the memory for the process - memManager(pcbList, MEMORY_DEALLOCATE, intArg, intArgTwo, configPtr, singlePCB, logList); } /* @@ -987,12 +504,11 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) { // initialize function/variables // need two working pointers, one for master loop, one for internal loop - // OpCodeType *wkgPtrMaster; + OpCodeType *wkgPtrMaster; // currentTime variable that stores the time. [now unsure if needed] // need a variable for headPointer to point ProcessControlBlockLL *pcbList; ProcessControlBlock *pcbPtr; - logFileLL *loggingList; // string variable for nextCode, temp unused // char *nextCode; // string variable for the timer stuff @@ -1000,17 +516,13 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) char timeStringy[MAX_STR_LEN]; int processCount = 0; int processIterator; - int memoryOffset = 0; - int memorySize = 1; - // create the file list with createFileLogList, store the pointed to address - loggingList = createFileLogList(); - accessTimer(ZERO_TIMER, timeStringy); // Operating System start timer goes here, log it. sprintf(simulatorOutput, "%f, OS: Simulator start\n", accessTimer(LAP_TIMER, timeStringy)); - logOutput(configPtr, simulatorOutput, false, loggingList); - // int variable for process to run + logOutput(configPtr, simulatorOutput, false); + + // int variable for process to run int currentPid; // create the process list with createProcessList, store the pointed to address pcbList = createProcessList(); @@ -1027,23 +539,43 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) processCount = processCount + 1; } pcbPtr = pcbList->headPtr; - int *totalPCBTimePtr = &totalPCBTime; - pthread_t cpuThread; - pthread_create(&cpuThread, NULL, runTimer, (void *)totalPCBTimePtr); + pthread_create(&cpuThread, NULL, (void *)&simThread, (void *)totalPCBTime); // int processTimeLeft = pcbPtr->timeLeft; - int *processTimeLeftPtr = &processTimeLeft; // set the current process id to the first scheduled process - currentPid = scheduleProcess(pcbList, configPtr, loggingList); - - // initialize memory with the memManager - memManager(pcbList, MEMORY_INITIALIZE, memoryOffset, memorySize, configPtr, pcbList->headPtr, loggingList); - + currentPid = scheduleProcess(pcbList, configPtr); // loop until current process is hit + // while(pcbPtr->process_state != PROCESS_STATE_TERMINATED && pcbPtr != NULL && processCount != 0) + // { + // if(pcbPtr->uniquePid == currentPid) + // { + // // needs to set from READY to RUNNING + // pcbPtr->process_state = PROCESS_STATE_RUNNING; + // sprintf(simulatorOutput, "%f, OS: Process %d set to RUNNING state from READY state\n\n", accessTimer(LAP_TIMER, timeStringy), pcbPtr->uniquePid); + // logOutput(configPtr, simulatorOutput, false); + // pthread_t runThread; + // pthread_create(&runThread, NULL, (void *)&simThread, (void *)processTimeLeft); + // runProcess(pcbPtr, configPtr); + // // when finished, set to terminated + // sprintf(simulatorOutput, "%f, OS: Process %d set to TERMINATED state from RUNNING state\n\n", accessTimer(LAP_TIMER, timeStringy), pcbPtr->uniquePid); + // logOutput(configPtr, simulatorOutput, false); + // pcbPtr->process_state = PROCESS_STATE_TERMINATED; + // processCount = processCount - 1; + // pthread_join(runThread, NULL); + // } + // processTimeLeft = pcbPtr->timeLeft; + // pcbPtr = pcbPtr->nextPtr; + // currentPid = scheduleProcess(pcbList, configPtr); + // if(configPtr->cpuSchedCode == CPU_SCHED_SJF_N_CODE && pcbPtr == NULL) + // { + // // + // pcbPtr = pcbList->headPtr; + // } + // } for(processIterator = 0; processIterator < processCount; processIterator++) { while (pcbPtr != NULL) @@ -1056,36 +588,31 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) // needs to set from READY to RUNNING pcbPtr->process_state = PROCESS_STATE_RUNNING; sprintf(simulatorOutput, "%f, OS: Process %d set to RUNNING state from READY state\n\n", accessTimer(LAP_TIMER, timeStringy), pcbPtr->uniquePid); - logOutput(configPtr, simulatorOutput, false, loggingList); + logOutput(configPtr, simulatorOutput, false); pthread_t runThread; - pthread_create(&runThread, NULL, runTimer, (void *)processTimeLeftPtr); - runProcess(pcbPtr, configPtr, pcbList, loggingList); + pthread_create(&runThread, NULL, (void *)&simThread, (void *)processTimeLeft); + runProcess(pcbPtr, configPtr); // when finished, set to terminated sprintf(simulatorOutput, "%f, OS: Process %d set to TERMINATED state from RUNNING state\n\n", accessTimer(LAP_TIMER, timeStringy), pcbPtr->uniquePid); - logOutput(configPtr, simulatorOutput, false, loggingList); + logOutput(configPtr, simulatorOutput, false); pcbPtr->process_state = PROCESS_STATE_TERMINATED; pthread_join(runThread, NULL); } processTimeLeft = pcbPtr->timeLeft; - processTimeLeftPtr = &processTimeLeft; pcbPtr = pcbPtr->nextPtr; } - currentPid = scheduleProcess(pcbList, configPtr, loggingList); + currentPid = scheduleProcess(pcbList, configPtr); pcbPtr = pcbList->headPtr; } pthread_join(cpuThread, NULL); - // deallocate all the memory for each process. - memManager(pcbList, MEMORY_CLEAR, memoryOffset, memorySize, configPtr, pcbList->headPtr, loggingList); sprintf(simulatorOutput, "%f, OS: System Stop\n", accessTimer(LAP_TIMER, timeStringy)); - logOutput(configPtr, simulatorOutput, false, loggingList); + logOutput(configPtr, simulatorOutput, false); sprintf(simulatorOutput, "%f, OS: Simulation End\n", accessTimer(LAP_TIMER, timeStringy)); - logOutput(configPtr, simulatorOutput, true, loggingList); + logOutput(configPtr, simulatorOutput, true); // deallocate the process list with destroyProcessList destroyProcessList(pcbList); // once complete, log the output to FILE if required - // logOutput(configPtr, "", true, loggingList); - // deallocate the file log list with destroyFileLogList - destroyFileLogList(loggingList); + logOutput(configPtr, "", true); // pthread_exit(NULL); // this line seems to make the program execution stop short... no warning either // void function, no return. } @@ -1101,7 +628,7 @@ Device Input/Device: none Device Output/Device: none Dependencies: sprintf, logOutput, ??? */ -int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr, logFileLL *logList) +int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr) { ProcessControlBlock *wkgPtr; int returnPid = -1; @@ -1110,9 +637,6 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt char timeStringy[MAX_STR_LEN]; int processCount = 0; - int shortestJob = 0; - int shortestJobProcNum = 0; - while (wkgPtr != NULL) { if(wkgPtr->process_state != PROCESS_STATE_TERMINATED) @@ -1143,7 +667,7 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt wkgPtr->process_state = PROCESS_STATE_READY; // printf("Process %d set to READY from NEW\n", wkgPtr->uniquePid); sprintf(loggingStr, "%f, OS: Process %d set to READY state from NEW state\n", accessTimer(LAP_TIMER, timeStringy), wkgPtr->uniquePid); - logOutput(configPtr, loggingStr, false, logList); + logOutput(configPtr, loggingStr, false); } // move to the next pointer wkgPtr = wkgPtr->nextPtr; @@ -1158,7 +682,7 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt { //printf("Process %d Selected with %.0f ms remaining\n", wkgPtr->uniquePid, wkgPtr->timeLeft); sprintf(loggingStr, "%f, OS: Process %d selected with %.0f ms remaining\n", accessTimer(LAP_TIMER, timeStringy), wkgPtr->uniquePid, wkgPtr->timeLeft); - logOutput(configPtr, loggingStr, false, logList); + logOutput(configPtr, loggingStr, false); returnPid = wkgPtr->uniquePid; } // move to next pointer @@ -1176,7 +700,8 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt // need to find shortest job, maybe using a find min function? // reuse the previous code to set each process to READY from NEW // will select the process that is in the READY state, with the shortest time. - + int shortestJob = 0; + int shortestJobProcNum = 0; while (wkgPtr != NULL) { // @@ -1186,7 +711,7 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt wkgPtr->process_state = PROCESS_STATE_READY; // printf("Process %d set to READY from NEW\n", wkgPtr->uniquePid); sprintf(loggingStr, "%f, OS: Process %d set to READY state from NEW state\n", accessTimer(LAP_TIMER, timeStringy), wkgPtr->uniquePid); - logOutput(configPtr, loggingStr, false, logList); + logOutput(configPtr, loggingStr, false); } // move to the next pointer wkgPtr = wkgPtr->nextPtr; @@ -1237,7 +762,7 @@ int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPt { // printf("Process %d Selected with %.0f ms remaining\n", wkgPtr->uniquePid, wkgPtr->timeLeft); sprintf(loggingStr, "%f, OS: Process %d selected with %.0f ms remaining\n", accessTimer(LAP_TIMER, timeStringy), shortestJobProcNum, (double)shortestJob); - logOutput(configPtr, loggingStr, false, logList); + logOutput(configPtr, loggingStr, false); } returnPid = shortestJobProcNum; break; @@ -1259,8 +784,8 @@ Device Input/Device: none Device Output/Device: none Dependencies: pthreads, runTimer */ -// void *simThread(int milSec) -// { -// runTimer(milSec); -// pthread_exit(NULL); -// } \ No newline at end of file +void *simThread(int milSec) +{ + runTimer(milSec); + pthread_exit(NULL); +} \ No newline at end of file diff --git a/Sim03/simulator.h b/Sim03/simulator.h index 4851092..30541cb 100644 --- a/Sim03/simulator.h +++ b/Sim03/simulator.h @@ -21,23 +21,9 @@ typedef enum{ MEMORY_INITIALIZE = 0, MEMORY_ACCESS, MEMORY_ALLOCATE, - MEMORY_CLEAR, MEMORY_DEALLOCATE } MEMORY_SIGNALS; -typedef struct logFileStruct -{ - char stringData[HUGE_STR_LEN]; - // connect to the next process control block here - struct logFileStruct *nextPtr; -} logFile; - -typedef struct logFileLLStruct -{ - // holds the head ptr for PCBs - logFile *headPtr; -} logFileLL; - typedef struct ProcessControlBlockStruct { int uniquePid; @@ -62,8 +48,6 @@ typedef struct ProcessControlBlockStruct int *allocatedMemOffsets; // allocated memory array sizes (stores the sizes for each offset) int *allocatedMemSizes; - // size of memory array - int memArraySize; // connect to the next process control block here struct ProcessControlBlockStruct *nextPtr; } ProcessControlBlock; @@ -96,31 +80,6 @@ Device Output/Device: none Dependencies: ??? */ -/* -Name: accessMemory -Process: checks that the memory is between the offset and the size. - checks that the memory is ??? -Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int) -Function Output/Parameters: none -Function Output/Returned: boolean to indicate success or failure of accessed memory -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool accessMemory(ProcessControlBlock *singlePCB, int offset, int size); - -/* -Name: addLog -Process: allocates the memory for the log, ... -Function Input/Parameters: source log (logFile) -Function Output/Parameters: none -Function Output/Returned: filled PCB (logFile *) -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, sizeof, ??? -*/ -logFile *addLog(const logFile source); - /* Name: addProcess Process: allocates the memory for the pcb, grabs the data from the created PCB, @@ -134,33 +93,9 @@ Dependencies: malloc, sizeof, ??? */ ProcessControlBlock *addProcess(const ProcessControlBlock source); -/* -Name: allocMemory -Process: 'allocates' memory within the PCB, stores offset and size within it's PCB -Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int) -Function Output/Parameters: none -Function Output/Returned: boolean to indicate success or failure of allocated memory -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool allocMemory(ProcessControlBlock *singlePCB, int offset, int size, int arraySize); - -/* -Name: createFileLogList -Process: initializes the logging file struct -Function Input/Parameters: none -Function Output/Parameters: none -Function Output/Returned: head pointer to the logfile struct -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, sizeof, ??? -*/ -logFileLL *createFileLogList(); - /* Name: createProcessList -Process: reads through the opcode struct to fill out the linked list of PCBs +Process: initializes head pointer to the PCBs Function Input/Parameters: none Function Output/Parameters: none Function Output/Returned: head pointer to the PCBs @@ -170,30 +105,6 @@ Dependencies: malloc, sizeof, ??? */ ProcessControlBlockLL *createProcessList(); -/* -Name: deallocMemory -Process: 'deallocates' memory within the PCB, removes every offset and size within it's PCB -Function Input/Parameters: source PCB (ProcessControlBlock *) -Function Output/Parameters: none -Function Output/Returned: boolean to indicate success or failure of allocated memory -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool deallocMemory(ProcessControlBlock *singlePCB, int arraySize); - -/* -Name: destroyFileLogList -Process: deallocates memory used for the linked list struct -Function Input/Parameters: head pointer to linked list (logFileLL *) -Function Output/Parameters: none -Function Output/Returned: NULL -Device Input/Device: none -Device Output/Device: none -Dependencies: free, destroyFileLogHelper, ??? -*/ -logFileLL *destroyFileLogList(logFileLL *linkedListPtr); - /* Name: destroyProcessList Process: deallocates memory used for the linked list struct @@ -206,18 +117,6 @@ Dependencies: free, destroyProcessListHelper, ??? */ ProcessControlBlockLL *destroyProcessList(ProcessControlBlockLL *linkedListPtr); -/* -Name: destroyFileLogHelper -Process: recursively clears the logfile linked list struct, freeing the struct -Function Input/Parameters: head pointer to logfile list (logFile *) -Function Output/Parameters: none -Function Output/Returned: NULL -Device Input/Device: none -Device Output/Device: none -Dependencies: free, destroyFileLogHelper(recursively), ??? -*/ -logFile *destroyFileLogHelper(logFile *nodePtr); - /* Name: destroyProcessListHelper Process: recursively clears the PCB linked list struct, freeing the struct @@ -258,31 +157,16 @@ int findMin(int one, int another); /* 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: fprintf, ??? +Dependencies: sprintf, ??? */ -logFileLL *logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd, logFileLL *logPtr); - -/* -Name: memManager -Process: checks to make sure an allocate will be successful, - makes sure that an access will not segfault (or return segfault if it does), - and initializes memory and deallocates memory -Function Input/Parameters: PCBList (ProcessControlBlockLL *), memory code (MEMORY_SIGNALS), - offset (int), size (int), configuration data (ConfigDataType *) -Function Output/Parameters: none -Function Output/Returned: boolean for success or failure of memory management -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool memManager(ProcessControlBlockLL *pcbList, MEMORY_SIGNALS memCode, int offset, int size, ConfigDataType *configPtr, ProcessControlBlock *singlePCB, logFileLL *logList); +void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd); /* Name: runCPU @@ -292,9 +176,9 @@ Function Output/Parameters: none Function Output/Returned: none Device Input/Device: none Device Output/Device: none -Dependencies: pthreads, sprintf, logOutput, ??? +Dependencies: ??? */ -void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId, logFileLL *logList); +void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId); /* Name: runIO @@ -304,46 +188,44 @@ Function Output/Parameters: none Function Output/Returned: none Device Input/Device: none Device Output/Device: none -Dependencies: pthreads, sprintf, logOutput, ??? +Dependencies: ??? */ -void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId, logFileLL *logList); - -/* -Name: runProcess -Process: runs the process that was selected -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: accessTimer, compareString, runCPU, runIO, ??? -*/ -void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr, ProcessControlBlockLL *pcbList, logFileLL *logList); - +void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId); /* Name: runSim Process: primary simulation driver Function Input/Parameters: configuration data (ConfigDataType *), - metadata (OpCodeType *) + metadata (OpCodeType *) Function Output/Parameters: none Function Output/Returned: none Device Input/Device: none Device Output/Device: none -Dependencies: pthreads, accessTimer, sprintf, logOutput, runProcess, destroyProcessList, ??? +Dependencies: ??? */ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr); /* Name: scheduleProcess Process: takes in the scheduling data, and then returns which process is to be ran -Function Input/Parameters: head pointer of PCB List (ProcessControlBlockLL *), - configuration data (ConfigDataType *) +Function Input/Parameters: head pointer of PCB List (ProcessControlBlockLL *) Function Output/Parameters: none Function Output/Returned: none Device Input/Device: none Device Output/Device: none -Dependencies: sprintf, logOutput, ??? +Dependencies: ??? */ -int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr, logFileLL *logList); +int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr); + +/* +Name: simThread +Process: wrapper functions for threading in the simulator +Function Input/Parameters: milliseconds (int) +Function Output/Parameters: none +Function Output/Returned: none +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void *simThread(int milSec); #endif // SIMULATORX \ No newline at end of file diff --git a/Sim04/OS_SimDriver.c b/Sim04/OS_SimDriver.c deleted file mode 100644 index 7d1fbf0..0000000 --- a/Sim04/OS_SimDriver.c +++ /dev/null @@ -1,246 +0,0 @@ -// header files -#include "OS_SimDriver.h" - -int main(int argc, char **argv) -{ - // initialize program (variables and title) - ConfigDataType *configDataPtr = NULL; - OpCodeType *metaDataPtr = NULL; - char errorMsg[MAX_STR_LEN]; - CmdLineData cmdLineData; - bool configUploadSuccess = false; - - // show title - // fct: printf - printf("\nSimulator Program\n"); - printf("=================\n\n"); - - // process command line arguments - // check for at least one correct switch and config file name verified - // fct: processCmdLine - if(processCmdLine(argc, argv, &cmdLineData)) - { - // upload config file, check for success - // fct: getConfigData - if(getConfigData(cmdLineData.fileName, &configDataPtr, errorMsg)) - { - // check for config display flag - if(cmdLineData.configDisplayFlag) - { - // display config display flag - // fct: displayConfigData - displayConfigData(configDataPtr); - } - // set config upload success flag - configUploadSuccess = true; - } - // otherwise, assume config file upload failure - else - { - // show error message, end program - // fct: printf - printf("\nConfig Upload Error: %s, program aborted\n\n", errorMsg); - } - - // check for config success and need for metadata - if(configUploadSuccess && - (cmdLineData.mdDisplayFlag || cmdLineData.runSimFlag)) - { - // upload metadata file, check for success - // fct: getMetaData - if(getMetaData(configDataPtr->metaDataFileName, - &metaDataPtr, errorMsg)) - { - // check metadata display flag - if(cmdLineData.mdDisplayFlag) - { - // display metadata - // fct: displayMetaData - displayMetaData(metaDataPtr); - } - // check run simulator flag - if(cmdLineData.runSimFlag) - { - // run simulator - // fct: runSim - runSim(configDataPtr, metaDataPtr); - } - - } - // otherwise, assume metadata upload failure - else - { - // show error message, end program - // fct: printf - printf("\nMetadata Upload Error: %s, program aborted\n", - errorMsg); - } - } - // end check for config success and need for metadata - - // clean up config data as needed - // fct: clearConfigData - configDataPtr = clearConfigData(configDataPtr); - - // clean up metadata as needed - // fct: clearMetaDataList - metaDataPtr = clearMetaDataList(metaDataPtr); - } - // end process command line arguments - - // otherwise, assume command line failure - else - { - // show command line argument requirements - // fct: showCommandLineFormat - showCommandLineFormat(); - } - // show program end - // fct: printf - printf("\nSimulator Program End.\n"); - - // return program success - return 0; -} - -/* -Name: clearCmdLineStruct -Process: sets command line structure data to defaults - Booleans to false, fileName to empty string -Function Input/Parameters: pointer to command line structure (CmdLineData *) -Function Output/Parameters: pointer to command line structure (CmdLineData *) - with updated members -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -void clearCmdLineStruct(CmdLineData *clDataPtr) -{ - // set all struct members to default - clDataPtr->programRunFlag = false; - clDataPtr->configDisplayFlag = false; - clDataPtr->mdDisplayFlag = false; - clDataPtr->runSimFlag = false; - clDataPtr->fileName[0] = NULL_CHAR; - // void function, no return. -} - -/* -Name: processCmdLine -Process: checks for at least two arguments, - then sets Booleans depending on command line switches - which can be in any order, - also captures config file name which must be last arugment -Function Input/Parameters: number of arguments (int), - vector of arguments (char **) -Function Output/Parameters: pointer to command line structure (CmdLineData *) - with updated members, - set to default values if failure - to capture arguments -Function Output/Returned: Boolean result of argument capture - true if at least one switch and config file name, - false otherwise -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool processCmdLine(int numArgs, char **strVector, CmdLineData *clDataPtr) -{ - // initialize function and variables - - // initialize structure to defaults - // fct: clearCmdLineStruct - clearCmdLineStruct(clDataPtr); - // initialize success flags to false - bool atLeastOneSwitchFlag = false; - bool correctConfigFileFlag = false; - // initialize first arg index to one - int argIndex = 1; - // iniitialize file variables - int fileStrLen, fileStrSubLoc; - // must have program name, one switch, config file name at minimum - if(numArgs >= MIN_NUM_ARGS) - { - // loop across args (starting at 1) and program run flag - while(argIndex < numArgs) - { - // check for -dc - if(compareString(strVector[argIndex], "-dc") == 0) - { - // set config display flag - clDataPtr->configDisplayFlag = true; - // set at least one switch flag - atLeastOneSwitchFlag = true; - } - // otherwise, check for -dm - else if(compareString(strVector[argIndex], "-dm") == 0) - { - // set metadata display flag - clDataPtr->mdDisplayFlag = true; - // set at least one switch flag - atLeastOneSwitchFlag = true; - } - // otherwise, check for -rs - else if(compareString(strVector[argIndex], "-rs") == 0) - { - // set run simulator flag - clDataPtr->runSimFlag = true; - // set at least one switch flag - atLeastOneSwitchFlag = true; - } - // otherwise, check for file name, ending in .cfg (must be last) - else - { - // find lengths to verify file name - // file name must be last argument, have '.cnf' extension - fileStrLen = getStringLength(strVector[numArgs - 1]); - fileStrSubLoc = findSubString(strVector[numArgs - 1], ".cnf"); - // check for file existence and correct file format - if(fileStrSubLoc != SUBSTRING_NOT_FOUND && - fileStrSubLoc == fileStrLen - LAST_FOUR_LETTERS) - { - // set file name to variable - copyString(clDataPtr->fileName, strVector[numArgs - 1]); - // set success flag to true - correctConfigFileFlag = true; - } - // otherwise, assume bad config file name - else - { - // reset struct, correct config file flag stays false - // fct: clearCmdLineStruct - clearCmdLineStruct(clDataPtr); - } - } - // update arg index - argIndex = argIndex + 1; - } - // end loop across args and program run flag - } - // return verification of at least one switch and file name - return atLeastOneSwitchFlag && correctConfigFileFlag; -} - -/* -Name: showCommandLineFormat -Process: displays command line format as assistance to user -Function Input/Parameters: none -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Monitor: data displayed as spec'd -Dependencies: printf -*/ -void showCommandLineFormat() -{ - // display command line format - // fct: printf - printf("Command Line Format:\n"); - printf(" sim_01 [-dc] [-dm] [-rs] \n"); - printf(" -dc [optional] displays configuration data\n"); - printf(" -dm [optional] displays metadata\n"); - printf(" -rs [optional] runs the simulator\n"); - printf(" required configfile.cnf\n"); - // void function, no return. -} \ No newline at end of file diff --git a/Sim04/OS_SimDriver.h b/Sim04/OS_SimDriver.h deleted file mode 100644 index 27a3529..0000000 --- a/Sim04/OS_SimDriver.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef OS_DRIVER -#define OS_DRIVER - -// header files -#include -#include "StringUtils.h" -#include "configops.h" -#include "metadataops.h" -#include "simulator.h" -// ??? #include "datatypes.h" - -// program constants -typedef enum {SUBSTRING_NOT_FOUND = 0, MIN_NUM_ARGS = 3, LAST_FOUR_LETTERS = 4} PRG_CONSTANTS; - -typedef struct CmdLineDataStruct -{ - bool programRunFlag; - bool configDisplayFlag; - bool mdDisplayFlag; - bool runSimFlag; - char fileName[STD_STR_LEN]; -} CmdLineData; - - -// function prototypes - -/* -Name: clearCmdLineStruct -Process: sets command line structure data to defaults - Booleans to false, fileName to empty string -Function Input/Parameters: pointer to command line structure (CmdLineData *) -Function Output/Parameters: pointer to command line structure (CmdLineData *) - with updated members -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -void clearCmdLineStruct(CmdLineData *clDataPtr); - -/* -Name: processCmdLine -Process: checks for at least two arguments, - then sets Booleans depending on command line switches - which can be in any order, - also captures config file name which must be last arugment -Function Input/Parameters: number of arguments (int), - vector of arguments (char **) -Function Output/Parameters: pointer to command line structure (CmdLineData *) - with updated members, - set to default values if failure - to capture arguments -Function Output/Returned: Boolean result of argument capture - true if at least one switch and config file name, - false otherwise -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool processCmdLine(int numArgs, char **strVector, CmdLineData *clDataPtr); - -/* -Name: showCommandLineFormat -Process: displays command line format as assistance to user -Function Input/Parameters: none -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Monitor: data displayed as spec'd -Dependencies: printf -*/ -void showCommandLineFormat(); - -#endif //OS_DRIVER \ No newline at end of file diff --git a/Sim04/StandardConstants.h b/Sim04/StandardConstants.h deleted file mode 100644 index 7b00d4c..0000000 --- a/Sim04/StandardConstants.h +++ /dev/null @@ -1,79 +0,0 @@ -// Preprocessor directives -#ifndef STANDARD_CONSTANTS_H -#define STANDARD_CONSTANTS_H - -// Include Boolean -#include - -// global constants - -// constant for end of c-string null character -#define CARRIAGE_RETURN_CHAR '\r' - -//constant for a COLON -#define COLON ':' - -//constant for a SEMICOLON -#define SEMICOLON ';' - -//constant for a COMMA -#define COMMA ',' - -//Constant to print a dash -#define DASH '-' - -// constant for equivalent strings -#define EQUIV 0 - -// highest printable character -#define HIGHEST_PRINTABLE_CHAR '~' - -// constant for huge string length -#define HUGE_STR_LEN 256 - -// lowest printable character -#define LOWEST_PRINTABLE_CHAR ' ' - -// constant for small string length -#define MIN_STR_LEN 32 - -// constant for maximum string length -#define MAX_STR_LEN 128 - -// constant for end of c-string null character -#define NEWLINE_CHAR '\n' - -// first non-printable above ASCII -#define DELETE_KEY 127 - -// constant for end of c-string null character -#define NULL_CHAR '\0' - -// columns found in grade sheet before grading columns -#define NUM_BASE_COLS 5 - -// constant for number of grading frequency bins -#define NUM_FREQUENCY_BINS 10 - -//Constant for printing a pipe -#define PIPE '|' - -//Constant for a period -#define PERIOD '.' - -//Constant for PRECISION, 2 digits -#define PRECISION_2 2 - -//Constant for PRECISION, 4 digits -#define PRECISION_4 4 - -// constant for space character -#define SPACE ' ' - -// constant for standard string length -#define STD_STR_LEN 64 - -// constant for smallest string length -#define TINY_STR_LEN 16 - -#endif // STANDARD_CONSTANTS diff --git a/Sim04/StringUtils.c b/Sim04/StringUtils.c deleted file mode 100644 index e0678c2..0000000 --- a/Sim04/StringUtils.c +++ /dev/null @@ -1,454 +0,0 @@ -// header files -#include "StringUtils.h" - -// global constants -const int SUBSTRING_NOT_FOUND = 0; - -// list of utils: - // string length - // getStringLength - // string copy - // copyString - // string concatenate - // catString - // string compare (<, >, =) - // compareString - // string substring get - // getSubString - // string substring find - // findSubString - // string set to lower - // toLowerCase - // string get to delimiter - // stringDelimiter - // string get to end of line - // stringEOL - -// function implementations - -/* -Name: catString -Process: concatenates two strings -Function input/parameters: c-style string (char *) -Function output/parameters: c-style string (char *) -Function output/returned: NONE -Device input/---: NONE -Device output/---: NONE -Dependencies: malloc, free, getStringLength -*/ -void catString(char *outString, const char *inString) -{ - // initialize variables - // set dest index - int destIndex = getStringLength(outString); - // set source str length - int sourceStrLen = getStringLength(inString); - // create temp string pointer - char *tempString; - int sourceIndex = 0; - - // copy source string in case of aliasing - tempString = (char *)malloc(sizeof(char) * sourceStrLen); - copyString(tempString, inString); - - // loop to end of source string - while(tempString[sourceIndex] != NULL_CHAR) - { - // assign characters to end of destination string - outString[destIndex] = inString[sourceIndex]; - // update indices - destIndex = destIndex + 1; - sourceIndex = sourceIndex + 1; - } - // end loop to end of source string - // set temporary end of destination string - outString[destIndex] = NULL_CHAR; - - // release memory used for temp string - free(tempString); - - // no return, void. -} - -/* -Name: compareString -Process: compares two strings as follows: - - if left string is alphabetically greater than the right string, - returns value greater than zero - - if left string is alphabetically less than the right string, - returns value less than zero - - if strings are alphabetically equal but one is longer, - longer one is greater - - otherwise, returns zero -Function input/parameters: c-style strings (char *) [first and second/left&right] -Function output/parameters: NONE -Function output/returned: results as specfifed above (int) -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringLength -*/ -int compareString(const char *firstString, const char *secondString) -{ - // initialize variables - int diff, index = 0; - - // loop to end of string (within bounds) - while(firstString[index] != NULL_CHAR && secondString[index] != NULL_CHAR) - { - // get diff of characters - diff = firstString[index] - secondString[index]; - // check diff of characters - if(diff != 0) - { - // return diff - return diff; - } - // increment index - index = index + 1; - } - // end loop to end of string - - // return difference in length of strings, if needed - return getStringLength(firstString) - getStringLength(secondString); -} - -/* -Name: copyString -Process: copies string into new string variable, overwrites destination. -Function input/parameters: c-style string (char *) -Function output/parameters: c-style string (char *) -Function output/returned: NONE -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringLength -*/ -void copyString(char *outString, const char *inString) -{ - // initialize variables - int index = 0; - - // check to see if outString is not the same as inString. - if(outString != inString) - { - // loop to end of inString - while(inString[index] != NULL_CHAR) - { - // assign characters to end of outString - outString[index] = inString[index]; - // increment index - index = index + 1; - } - // end loop to end of inString - // set end of the outString - outString[index] = NULL_CHAR; - } - - // no return, void. -} - -/* -Name: findSubString -Process: linear search for given substring within another string -Function input/parameters: c-style test string (char *), - c-style source string (char *) -Function output/parameters: NONE -Function output/returned: index of found substring, or - SUBSTRING_NOT_FOUND constant - if string not found -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringLength -*/ -int findSubString(const char *testStr, const char *searchSubStr) -{ - // initialize variables - // initialize test string length - int testStrLength = getStringLength(testStr); - // initialize master index (location of substring start point) - int masterIndex = 0; - int searchIndex, internalIndex; - - // loop across testStr - while(masterIndex < testStrLength) - { - // set internal loop index to current test string index - internalIndex = masterIndex; - // set internal search index to zero - searchIndex = 0; - // loop to end of testStr - // while testStr/searchSubStr characters are the same - while(internalIndex <= testStrLength && - testStr[internalIndex] == searchSubStr[searchIndex]) - { - // increment testStr and substring indices - internalIndex = internalIndex + 1; - searchIndex = searchIndex + 1; - // check for end of substring (search complete) - if(searchSubStr[searchIndex] == NULL_CHAR) - { - // return beginning location of substring - return masterIndex; - } - } - // end while testStr/searchSubStr characters are the same - // increment current location starting index - masterIndex = masterIndex + 1; - } - // end loop across testStr - - // return SUBSTRING_NOT_FOUND - return SUBSTRING_NOT_FOUND; -} - -/* -Name: getStringConstrained -Process: captures a string from the file stream with various constraints -Function input/parameters: input stream (FILE *), - clears leading non printable (bool), - clears leading space (bool), - stops at non printable (bool), - stops at specified delimiter (char) - will consume the delimiter. -Function output/parameters: c-style string (char *) -Function output/returned: success of operation (bool) -Device input/---: NONE -Device output/---: NONE -Dependencies: fgetc -*/ -bool getStringConstrained(FILE *inStream, bool clearLeadingNonPrintable, - bool clearLeadingSpace, bool stopAtNonPrintable, - char delimiter, char *capString) -{ - // initialize variables - int intChar = EOF, index = 0; - - // initialize output string - capString[index] = NULL_CHAR; - // capture first value in stream using fgetc - intChar = fgetc(inStream); - // loop to clear non-printable or space if indicated - while((intChar != EOF) && - ((clearLeadingNonPrintable && intChar < (int)SPACE) - || (clearLeadingSpace && intChar == (int)SPACE))) - { - // get next character in stream using fgetc - intChar = fgetc(inStream); - } - // end loop to clear non-printable or space if indicated - // check for end of file found - if(intChar == EOF) - { - // return false (failed) - return false; - } - // loop to get input from file stream - while((intChar != EOF && index < MAX_STR_LEN - 1) && - ((stopAtNonPrintable && intChar >= (int)SPACE) || (!stopAtNonPrintable)) && - (intChar != (char)delimiter)) - { - // [continues if not at end of file and max string len not reached ] - // [AND continues if not printable flag set and characters printable ] - // [OR continues if not printable flag not set ] - // [AND continues if specified delimited is not found ] - - // place character in array element - capString[index] = (char)intChar; - // increment array index - index = index + 1; - // set next element to null character - capString[index] = NULL_CHAR; - // get next character as integer using fgetc - intChar = fgetc(inStream); - } - // end loop to get input from file stream - // return success - return true; -} - -/* -Name: getStringLength -Process: gets length of string from start to NULL_CHAR ('\0') -Function input/parameters: c-style string (char *) -Function output/parameters: NONE -Function output/returned: length of string (int) -Device input/---: NONE -Device output/---: NONE -Dependencies: included by standard libraries -*/ -int getStringLength(const char *stringIn) -{ - // define variables - int stringLength = 0, currentCharacter = 0; - // get user input (not needed) - // do calculations - while (currentCharacter < STD_STR_LEN && stringIn[currentCharacter] != NULL_CHAR) - { - // increment string length - stringLength = stringLength + 1; - // increment currentCharacter - currentCharacter = currentCharacter + 1; - } - // display results (not needed) - // return success - return stringLength; -} - -/* -Name: getStringToDelimiter -Process: captures a string from the input stream to a specified delimiter. - will consume the delimiter. -Function input/parameters: input stream (FILE *), - stops at specified character -Function output/parameters: c-style string (char *) -Function output/returned: success of operation (bool) -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringConstrained -*/ -bool getStringToDelimiter(FILE *inStream, char delimiter, char *capString) -{ - // use getStringConstrained with delimiter to get string - return getStringConstrained(inStream, true, true, true, delimiter, capString); -} - -/* -Name: getStringToLineEnd -Process: captures a string from the input stream to the end of the line -Function input/parameters: input file stream (FILE *) -Function output/parameters: c-style string (char *) -Function output/returned: success of operation (bool) -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringConstrained -*/ -bool getStringToLineEnd(FILE *inStream, char *capString) -{ - // use getStringConstrained with line end character to get string - return getStringConstrained(inStream, true, true, true, '\n', capString); -} - -/* -Name: getSubString -Process: captures sub string within larger string - between two inclusive indices. - returns empty string if either index is out of range, - assumes enough memory in dest string -Function input/parameters: c-style string (char *) - start and end indices (int) -Function output/parameters: c-style destination string (char *) -Function output/returned: NONE -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringLength, malloc, copyString, free -*/ -void getSubString(char *destStr, const char *sourceStr, - int startIndex, int endIndex) -{ - // initialize variables - // set length of source string using getStringLength - int sourceStrLen = getStringLength(sourceStr); - // initialize the destination index to zero - int destIndex = 0; - // initialize source index to start index (parameter) - int sourceIndex = startIndex; - // create pointer for temp string - char *tempStr; - - // check for indices within limits - if(startIndex >= 0 && startIndex <= endIndex && endIndex < sourceStrLen) - { - // create temp string using malloc and copyString - tempStr = (char *)malloc(sourceStrLen + 1); - copyString(tempStr, sourceStr); - // loop across requested substring indices - while(sourceIndex <= endIndex) - { - // assign source character to destination element - destStr[destIndex] = tempStr[sourceIndex]; - // increment indices - destIndex = destIndex + 1; - sourceIndex = sourceIndex + 1; - // set temporary end of destination string - destStr[destIndex] = NULL_CHAR; - } - // end loop across requested substring indices - // free temp string - free(tempStr); - } - - // no return, void. -} - -/* -Name: strToLowerCase -Process: iterates through string, sets any uppercase letter to lowercase - equivalent, does not affect any letter with an upper/lower diff. -Function input/parameters: c-style source string (char *) -Function output/parameters: c-style dest string (char *) -Function output/returned: NONE -Device input/---: NONE -Device output/---: NONE -Dependencies: toLowerCase -*/ -void strToLowerCase(char *outString, const char *inString) -{ - // initialize variables - // get source string length - int sourceStrLen = getStringLength(inString); - // create temporary string pointer - char *tempStr; - int index = 0; - - // copy source string in case of aliasing using malloc and copyString - tempStr = (char *)malloc((sizeof(char) * (sourceStrLen + 1))); - copyString(tempStr, inString); - // loop across source string - while(tempStr[index] != NULL_CHAR && index < MAX_STR_LEN) - { - // set individual character to lowercase as needed, assigning back - outString[index] = toLowerCase(tempStr[index]); - // update index - index = index + 1; - // set temporary end of destination string - outString[index] = NULL_CHAR; - } - // end loop across source string - // free temporary string - free(tempStr); - - // no return, void. -} - -/* -Name: toLowerCase -Process: sets character to lowercase letter if uppercase letter, - returns character -Function input/parameters: character input (char) -Function output/parameters: NONE -Function output/returned: character output (char) -Device input/---: NONE -Device output/---: NONE -Dependencies: none -*/ -char toLowerCase(char testChar) -{ - // check for uppercase letter - if(testChar >= 'A' && testChar <= 'Z') - { - // return lowercase letter - return testChar - 'A' + 'a'; - } - // otherwise, assume not uppercase letter, return unchanged - return testChar; -} - -/* -Name: ??? -Process: ??? -Function input/parameters: ??? -Function output/parameters: NONE -Function output/returned: ??? -Device input/---: NONE -Device output/---: NONE -Dependencies: included by standard libraries -*/ \ No newline at end of file diff --git a/Sim04/StringUtils.h b/Sim04/StringUtils.h deleted file mode 100644 index 0ff4f49..0000000 --- a/Sim04/StringUtils.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef STRINGUTILS -#define STRINGUTILS - -// header files -#include -#include -#include -#include -#include -#include "StandardConstants.h" - -// data structures - -// program constants - -// function prototypes - -/* -Name: catString -Process: concatenates two strings -Function input/parameters: c-style string (char *) -Function output/parameters: c-style string (char *) -Function output/returned: NONE -Device input/---: NONE -Device output/---: NONE -Dependencies: malloc, free, getStringLength -*/ -void catString(char *outString, const char *inString); - -/* -Name: compareString -Process: compares two strings as follows: - - if left string is alphabetically greater than the right string, - returns value greater than zero - - if left string is alphabetically less than the right string, - returns value less than zero - - if strings are alphabetically equal but one is longer, - longer one is greater - - otherwise, returns zero -Function input/parameters: c-style strings (char *) [first and second/left&right] -Function output/parameters: NONE -Function output/returned: results as specfifed above (int) -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringLength -*/ -int compareString(const char *firstString, const char *secondString); - -/* -Name: copyString -Process: copies string into new string variable, overwrites destination. -Function input/parameters: c-style string (char *) -Function output/parameters: c-style string (char *) -Function output/returned: NONE -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringLength -*/ -void copyString(char *outString, const char *inString); - -/* -Name: findSubString -Process: linear search for given substring within another string -Function input/parameters: c-style test string (char *), - c-style source string (char *) -Function output/parameters: NONE -Function output/returned: index of found substring, or - SUBSTRING_NOT_FOUND constant - if string not found -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringLength -*/ -int findSubString(const char *testStr, const char *searchSubStr); - -/* -Name: getStringConstrained -Process: captures a string from the file stream with various constraints -Function input/parameters: input stream (FILE *), - clears leading non printable (bool), - clears leading space (bool), - stops at non printable (bool), - stops at specified delimiter (char) - will consume the delimiter. -Function output/parameters: c-style string (char *) -Function output/returned: success of operation (bool) -Device input/---: NONE -Device output/---: NONE -Dependencies: fgetc -*/ -bool getStringConstrained(FILE *inStream, bool clearLeadingNonPrintable, - bool clearLeadingSpace, bool stopAtNonPrintable, - char delimiter, char *capString); - -/* -Name: getStringLength -Process: gets length of string from start to NULL_CHAR ('\0') -Function input/parameters: c-style string (char *) -Function output/parameters: NONE -Function output/returned: length of string (int) -Device input/---: NONE -Device output/---: NONE -Dependencies: included by standard libraries -*/ -int getStringLength(const char *stringIn); - -/* -Name: getStringToDelimiter -Process: captures a string from the input stream to a specified delimiter. - will consume the delimiter. -Function input/parameters: input stream (FILE *), - stops at specified character -Function output/parameters: c-style string (char *) -Function output/returned: success of operation (bool) -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringConstrained -*/ -bool getStringToDelimiter(FILE *inStream, char delimiter, char *capString); - -/* -Name: getStringToLineEnd -Process: captures a string from the input stream to the end of the line -Function input/parameters: input file stream (FILE *) -Function output/parameters: c-style string (char *) -Function output/returned: success of operation (bool) -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringConstrained -*/ -bool getStringToLineEnd(FILE *inStream, char *capString); - -/* -Name: getSubString -Process: captures sub string within larger string - between two inclusive indices. - returns empty string if either index is out of range, - assumes enough memory in dest string -Function input/parameters: c-style string (char *) - start and end indices (int) -Function output/parameters: c-style destination string (char *) -Function output/returned: NONE -Device input/---: NONE -Device output/---: NONE -Dependencies: getStringLength, malloc, copyString, free -*/ -void getSubString(char *destStr, const char *sourceStr, - int startIndex, int endIndex); - -/* -Name: strToLowerCase -Process: iterates through string, sets any uppercase letter to lowercase - equivalent, does not affect any letter with an upper/lower diff. -Function input/parameters: c-style source string (char *) -Function output/parameters: c-style dest string (char *) -Function output/returned: NONE -Device input/---: NONE -Device output/---: NONE -Dependencies: toLowerCase -*/ -void strToLowerCase(char *outString, const char *inString); - -/* -Name: toLowerCase -Process: sets character to lowercase letter if uppercase letter, - returns character -Function input/parameters: character input (char) -Function output/parameters: NONE -Function output/returned: character output (char) -Device input/---: NONE -Device output/---: NONE -Dependencies: none -*/ -char toLowerCase(char testChar); - -#endif // STRINGUTILS \ No newline at end of file diff --git a/Sim04/config0.cnf b/Sim04/config0.cnf deleted file mode 100644 index 9404729..0000000 --- a/Sim04/config0.cnf +++ /dev/null @@ -1,13 +0,0 @@ -Start Simulator Configuration File: -Version/Phase : 1.05 -File Path : metadata5.mdf -CPU Scheduling Code : SJF-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/Sim04/configops.c b/Sim04/configops.c deleted file mode 100644 index ad604d7..0000000 --- a/Sim04/configops.c +++ /dev/null @@ -1,608 +0,0 @@ -#include "configops.h" -#include "StandardConstants.h" -#include "StringUtils.h" - -/* -Name: clearConfigData -Process: frees dynamically allocated config data structure - if it has not already been freed -Function Input/Parameters: pointer to config data structure (ConfigDataType *) -Function Output/Parameters: none -Function Output/Returned: NULL (ConfigDataType *) -Device Input/Device: none -Device Output/Device: none -Dependencies: free -*/ -ConfigDataType *clearConfigData(ConfigDataType *configData) -{ - // initialize function and variables - // check that config data pointer is not null - if(configData != NULL) - { - // free data structure memory - // fct: free - free(configData); - // set config pointer to NULL - configData = NULL; - } - // set config data pointer to null - return NULL; -} - -/* -Name: configCodeToString -Process: utility fct converts configuration code numbers to string they represent -Function Input/Parameters: configuration code (int) -Function Output/Parameters: resulting output string (char *) -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: copyString -*/ -void configCodeToString(int code, char *outString) -{ - // define array with eight items, and short (10) lengths - char displayStrings[8][10] = {"SJF-N","SRTF-P","FCFS-P","RR-P", - "FCFS-N","Monitor", "File", "Both"}; - // copy string to return parameter - // fct: copyString - copyString(outString, displayStrings[code]); - // void function, no return. -} - -/* -Name: displayConfigData -Process: screen dump/display of all config data -Function Input/Parameters: pointer to config data structure (ConfigDataType *) -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Monitor: displayed as spec'd -Dependencies: configCodeToString, printf -*/ -void displayConfigData(ConfigDataType *configData) -{ - // initialize function and variables - char displayString[STD_STR_LEN]; - // print lines of display for all member values - // fct: printf, codeToString - printf("Config File Display\n"); - printf("-------------------\n"); - printf("Version : %3.2f\n", configData->version); - printf("Program File Name : %s\n", configData->metaDataFileName); - configCodeToString(configData->cpuSchedCode, displayString); - printf("CPU Schedule Selection: %s\n", displayString); - printf("Quantum Time : %d\n", configData->quantumCycles); - printf("Memory Display : "); - if(configData->memDisplay) - { - printf("On\n"); - } - else - { - printf("Off\n"); - } - printf("Memory Available : %d\n", configData->memAvailable); - printf("Process Cycle Rate : %d\n", configData->procCycleRate); - printf("I/O Cycle Rate : %d\n", configData->ioCycleRate); - configCodeToString(configData->logToCode, displayString); - printf("Log to Selection : %s\n", displayString); - printf("Log File Name : %s\n\n", configData->logToFileName); - // void function, no return. -} - -/* -Name: getConfigData -Process: driver function for capturing config data from config file -Function Input/Parameters: file name (const char *) -Function Output/Parameters: pointer to config data pointer (ConfigDataType **) - end/result state message pointer (char *) -Function Output/Returned: Boolean result of data access operation (bool) -Device Input/File: config data uploaded -Device Output/Device: none -Dependencies: copyString, fopen, getStringToDelimiter, compareString, fclose, - malloc, free, stripTrailingSpaces, getDataLineCode, fscanf, - strToLowerCase, valueInRange, getCpuSchedCode, getLogToCode -*/ -bool getConfigData(const char *fileName, - ConfigDataType **configData, char *endStateMsg) -{ - // initialize function and variables - // set constant number of data lines - const int NUM_DATA_LINES = 10; - // set read only constant - const char READ_ONLY_FLAG[] = "r"; - // create pointer for data input - ConfigDataType *tempData; - // declare other variables - FILE *fileAccessPtr; - char dataBuffer[MAX_STR_LEN], lowerCaseDataBuffer[MAX_STR_LEN]; - int intData, dataLineCode, lineCtr = 0; - double doubleData; - // set endStateMsg to success - // fct: copyString - char testMsg[] = "Configuration file upload successful"; - copyString(endStateMsg, testMsg); - // initialize config data pointer in case of return error - *configData = NULL; - // open file - // fct: fopen - fileAccessPtr = fopen(fileName, READ_ONLY_FLAG); - // check for file open failure - if(fileAccessPtr == NULL) - { - // set end state message to config file access error - // fct: copyString - char testMsg[] = "Configuration file access error"; - copyString(endStateMsg, testMsg); - // return file access error - return false; - } - // get first line, check for failure - // fct: getStringToDelimiter, compareString - if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer) - || compareString(dataBuffer, "Start Simulator Configuration File") != 0) - { - // close file access - // fct: fclose - fclose(fileAccessPtr); - // set end state message to corrupt leader line error - // fct: copyString - copyString(endStateMsg, "Corrupt configuration leader line error"); - // return corrupt file data - return false; - } - // create temporary pointer to configuration data structure - // fct: malloc - tempData = (ConfigDataType *) malloc(sizeof(ConfigDataType)); - // loop to end of config data items - while(lineCtr < NUM_DATA_LINES) - { - // get line leader, check for failure - // fct: getStringToDelimiter - if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer)) - { - // free temp struct memory - // fct: free - free(tempData); - // close file access - // fct: fclose - fclose(fileAccessPtr); - // set end state message to line capture failure - // fct: copyString - copyString(endStateMsg, - "Configuration data leader line capture error"); - // return incomplete file error - return false; - } - // strip trailing spaces of config leader lines - // for use in other fcts - // fct: stripTrailingSpaces - stripTrailingSpaces(dataBuffer); - // find correct data line code number from string - // fct: getDataLineCode - dataLineCode = getDataLineCode(dataBuffer); - // check for data line found - if(dataLineCode != CFG_CORRUPT_PROMPT_ERR) - { - // get data value - // check for version number (double value) - if(dataLineCode == CFG_VERSION_CODE) - { - // get version number - // fct: fscanf - fscanf(fileAccessPtr, "%lf", &doubleData); - } - // otherwise, check for metaData, fileNames, - // CPU Scheduling names, or memory display setting (strings) - else if(dataLineCode == CFG_MD_FILE_NAME_CODE || - dataLineCode == CFG_LOG_FILE_NAME_CODE || - dataLineCode == CFG_CPU_SCHED_CODE || - dataLineCode == CFG_LOG_TO_CODE || - dataLineCode == CFG_MEM_DISPLAY_CODE) - { - // get string input - // fct: fscanf - fscanf(fileAccessPtr, "%s", dataBuffer); - // set string to lower case for testing in valueInRange - // fct: strToLowerCase - strToLowerCase(lowerCaseDataBuffer, dataBuffer); - } - // otherwise, assume integer data - else - { - // get integer input - // fct: fscanf - fscanf(fileAccessPtr, "%d", &intData); - } - // check for data value in range - // fct: valueInRange - if(valueInRange(dataLineCode, intData, - doubleData, lowerCaseDataBuffer)) - { - // assign to data pointer depending on config item - // (all config line possibilities) - // fct: copyString, getCpuSchedCode, - // compareString, getLogToCode, as needed - switch(dataLineCode) - { - case CFG_VERSION_CODE: - tempData->version = doubleData; - break; - case CFG_MD_FILE_NAME_CODE: - copyString(tempData->metaDataFileName, dataBuffer); - break; - case CFG_CPU_SCHED_CODE: - tempData->cpuSchedCode = - getCpuSchedCode(lowerCaseDataBuffer); - break; - case CFG_QUANT_CYCLES_CODE: - tempData->quantumCycles = intData; - break; - case CFG_MEM_DISPLAY_CODE: - tempData->memDisplay = - compareString(lowerCaseDataBuffer, "on") == 0; - break; - case CFG_MEM_AVAILABLE_CODE: - tempData->memAvailable = intData; - break; - case CFG_PROC_CYCLES_CODE: - tempData->procCycleRate = intData; - break; - case CFG_IO_CYCLES_CODE: - tempData->ioCycleRate = intData; - break; - case CFG_LOG_TO_CODE: - tempData->logToCode = getLogToCode(lowerCaseDataBuffer); - break; - case CFG_LOG_FILE_NAME_CODE: - copyString(tempData->logToFileName, dataBuffer); - break; - } - } - // otherwise, assume data value not in range - else - { - // free temp struct memory - // fct: free - free(tempData); - // close file access - // fct: fclose - fclose(fileAccessPtr); - // set end state message to configuration data out of range - // fct: copyString - copyString(endStateMsg, "Configuration item out of range"); - // return data out of range - return false; - } - } - // otherwise, check for data line not found - else - { - // free temp struct memory - // fct: free - free(tempData); - // close file access - // fct: fclose - fclose(fileAccessPtr); - // set end state message to configuration corrupt prompt error - // fct: copyString - copyString(endStateMsg, "Corrupted configuration prompt"); - // return corrupt config file code - return false; - } - // increment line counter - lineCtr = lineCtr + 1; - } - // end loop to end of config data items - // acquire end of sim config string - // fct: getStringToDelimiter, compareString - if(!getStringToDelimiter(fileAccessPtr, PERIOD, dataBuffer) || - compareString(dataBuffer, "End Simulator Configuration File") != 0) - { - // free temp struct memory - // fct: free - free(tempData); - // close file access - // fct: fclose - fclose(fileAccessPtr); - // set end state message to corrupt configuration end line - // fct: copyString - copyString(endStateMsg, "Configuration end line capture error"); - // return corrupt file data - return false; - } - // test for "file only" output so memory diagnostics do not display - tempData->memDisplay = tempData->memDisplay && - tempData->logToCode != LOGTO_FILE_CODE; - // assign temp ptr to parameter return ptr - *configData = tempData; - // close file access - // fct: fclose - fclose(fileAccessPtr); - // return no error code - return true; -} - -/* -Name: getCpuSchedCode -Process: converts cpu schedule string to code (all scheduling possibilities) -Function Input/Parameters: lower case code string (const char *) -Function Output/Parameters: none -Function Output/Returned: cpu schedule code (ConfigDataCodes) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -ConfigDataCodes getCpuSchedCode(const char *lowerCaseCodeStr) -{ - // iniitalize function and variables - // set default return to FCFS-N - ConfigDataCodes returnVal = CPU_SCHED_FCFS_N_CODE; - // check for SJF-N - // fct: compareString - if(compareString(lowerCaseCodeStr, "sjf-n") == 0) - { - // set SJF-N code - returnVal = CPU_SCHED_SJF_N_CODE; - } - // check for SRTF-P - // fct: compareString - if(compareString(lowerCaseCodeStr, "srtf-p") == 0) - { - // set SRTF-P code - returnVal = CPU_SCHED_SRTF_P_CODE; - } - // check for FCFS-P - // fct: compareString - if(compareString(lowerCaseCodeStr, "fcfs-p") == 0) - { - // set FCFS-P code - returnVal = CPU_SCHED_FCFS_P_CODE; - } - // check for RR-P - // fct: compareString - if(compareString(lowerCaseCodeStr, "rr-p") == 0) - { - // set RR-P code - returnVal = CPU_SCHED_RR_P_CODE; - } - return returnVal; -} - -/* -Name: getDataLineCode -Process: converts leader line string to configuration code value - (processes all config file leader lines) -Function Input/Parameters: config leader line string (const char *) -Function Output/Parameters: none -Function Output/Returned: configuration code value (ConfigCodeMessages) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -ConfigCodeMessages getDataLineCode(const char *dataBuffer) -{ - // iniitalize function and variables - // return appropriate code depending on prompt string provided - // fct: compareString - if(compareString(dataBuffer, "Version/Phase") == 0) - { - return CFG_VERSION_CODE; - } - if(compareString(dataBuffer, "File Path") == 0) - { - return CFG_MD_FILE_NAME_CODE; - } - if(compareString(dataBuffer, "CPU Scheduling Code") == 0) - { - return CFG_CPU_SCHED_CODE; - } - if(compareString(dataBuffer, "Quantum Time (cycles)") == 0) - { - return CFG_QUANT_CYCLES_CODE; - } - if(compareString(dataBuffer, "Memory Display (On/Off)") == 0) - { - return CFG_MEM_DISPLAY_CODE; - } - if(compareString(dataBuffer, "Memory Available (KB)") == 0) - { - return CFG_MEM_AVAILABLE_CODE; - } - if(compareString(dataBuffer, "Processor Cycle Time (msec)") == 0) - { - return CFG_PROC_CYCLES_CODE; - } - if(compareString(dataBuffer, "I/O Cycle Time (msec)") == 0) - { - return CFG_IO_CYCLES_CODE; - } - if(compareString(dataBuffer, "Log To") == 0) - { - return CFG_LOG_TO_CODE; - } - if(compareString(dataBuffer, "Log File Path") == 0) - { - return CFG_LOG_FILE_NAME_CODE; - } - // return corrupt leader line error code - return CFG_CORRUPT_PROMPT_ERR; -} - -/* -Name: getLogToCode -Process: converts "log to" text to - configuration data code (three log to strings) -Function Input/Parameters: lower case log to string (const char *) -Function Output/Parameters: none -Function Output/Returned: configuration data code value -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -ConfigDataCodes getLogToCode(const char *lowerCaseLogToStr) -{ - // initialize function and variables - // set default to log to monitor - ConfigDataCodes returnVal = LOGTO_MONITOR_CODE; - // check for BOTH - // fct: compareString - if(compareString(lowerCaseLogToStr, "both") == 0) - { - // set return value to both code - returnVal = LOGTO_BOTH_CODE; - } - // check for FILE - // fct: compareString - if(compareString(lowerCaseLogToStr, "file") == 0) - { - // set return value to file code - returnVal = LOGTO_FILE_CODE; - } - // return selected code - return returnVal; -} - -/* -Name: stripTrailingSpaces -Process: removes trailing spaces from input config leader lines -Function Input/Parameters: config leader line string (char *) -Function Output/Parameters: updates config leader line string (char *) -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: getStringLength -*/ -void stripTrailingSpaces(char *str) -{ - // initialize index to length of string - 1 to get highest array index - int index = getStringLength(str) - 1; - // loop while space is found at the end of string - while(str[index] == SPACE) - { - // set element to NULL_CHAR - str[index] = NULL_CHAR; - // decrement index - index = index - 1; - } - // end loop from end of string - // void function, no return. -} - -/* -Name: valueInRange -Process: checks for config data values in range, including str values -Function Input/Parameters: line code number for specific config value (int), - integer value, as needed (int), - double value, as needed (double), - string value, as needed (const char *) -Function Output/Parameters: none -Function Output/Returned: Boolean result of the range test (bool) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -bool valueInRange(int lineCode, int intVal, double doubleVal, - const char *lowerCaseStringVal) -{ - // initialize function and variables - // set result to true, all tests are to find false - bool result = true; - // use line code to identify prompt line - switch(lineCode) - { - // for version code - case CFG_VERSION_CODE: - // check if limits of version code are exceeded - if(doubleVal < 0.00 || doubleVal > 10.00) - { - // set bool to false - result = false; - } - // break - break; - // for cpu scheduling code - case CFG_CPU_SCHED_CODE: - // check for not finding one of the scheduling strings - // fct: compareString - if(compareString(lowerCaseStringVal, "fcfs-n") != 0 && - compareString(lowerCaseStringVal, "sjf-n") != 0 && - compareString(lowerCaseStringVal, "srtf-p") != 0 && - compareString(lowerCaseStringVal, "fcfs-p") != 0 && - compareString(lowerCaseStringVal, "rr-p") != 0) - { - // set bool to false - result = false; - } - // break - break; - // for quantum cycles - case CFG_QUANT_CYCLES_CODE: - // check for quantum cycles limits exceeded - if(intVal < 0 || intVal > 100) - { - // set bool to false - result = false; - } - // break - break; - // for memory display - case CFG_MEM_DISPLAY_CODE: - // check for not finding either on or off - // fct: compareString - if(compareString(lowerCaseStringVal, "on") != 0 && - compareString(lowerCaseStringVal, "off") != 0) - { - // set bool to false - result = false; - } - // break - break; - // for memory available - case CFG_MEM_AVAILABLE_CODE: - // check for memory limits exceeded - if(intVal < 1024 || intVal > 102400) - { - // set bool to false - result = false; - } - // break - break; - // check for process cycles - case CFG_PROC_CYCLES_CODE: - // check for process cycles limits exceeded - if(intVal < 1 || intVal > 100) - { - // set bool to false - result = false; - } - // break - break; - // check for process cycles - case CFG_IO_CYCLES_CODE: - // check for process cycles limits exceeded - if(intVal < 1 || intVal > 1000) - { - // set bool to false - result = false; - } - // break - break; - // check for log to operation - case CFG_LOG_TO_CODE: - // check for not finding one of the log to strings - // fct: compareString - if(compareString(lowerCaseStringVal, "both") != 0 && - compareString(lowerCaseStringVal, "monitor") != 0 && - compareString(lowerCaseStringVal, "file") != 0) - { - // set bool to false - result = false; - } - // break - break; - } - // return result of limits analysis - return result; -} \ No newline at end of file diff --git a/Sim04/configops.h b/Sim04/configops.h deleted file mode 100644 index c8d0ee9..0000000 --- a/Sim04/configops.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef CONFIGOPS -#define CONFIGOPS - -#include "StandardConstants.h" -#include "StringUtils.h" - -typedef enum {CFG_FILE_ACCESS_ERR, - CFG_CORRUPT_DESCRIPTOR_ERR, - CFG_DATA_OUT_OF_RANGE_ERR, - CFG_CORRUPT_PROMPT_ERR, - CFG_VERSION_CODE, - CFG_MD_FILE_NAME_CODE, - CFG_CPU_SCHED_CODE, - CFG_QUANT_CYCLES_CODE, - CFG_MEM_DISPLAY_CODE, - CFG_MEM_AVAILABLE_CODE, - CFG_PROC_CYCLES_CODE, - CFG_IO_CYCLES_CODE, - CFG_LOG_TO_CODE, - CFG_LOG_FILE_NAME_CODE - } ConfigCodeMessages; - -typedef enum {CPU_SCHED_SJF_N_CODE, - CPU_SCHED_SRTF_P_CODE, - CPU_SCHED_FCFS_P_CODE, - CPU_SCHED_RR_P_CODE, - CPU_SCHED_FCFS_N_CODE, - LOGTO_MONITOR_CODE, - LOGTO_FILE_CODE, - LOGTO_BOTH_CODE, - NON_PREEMPTIVE_CODE, - PREEMPTIVE_CODE - } ConfigDataCodes; - -typedef struct ConfigDataTypeStruct -{ - double version; - char metaDataFileName[MAX_STR_LEN]; - int cpuSchedCode; - int quantumCycles; - bool memDisplay; - int memAvailable; - int procCycleRate; - int ioCycleRate; - int logToCode; - char logToFileName[MAX_STR_LEN]; -} ConfigDataType; - -/* -Name: clearConfigData -Process: frees dynamically allocated config data structure - if it has not already been freed -Function Input/Parameters: pointer to config data structure (ConfigDataType *) -Function Output/Parameters: none -Function Output/Returned: NULL (ConfigDataType *) -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -ConfigDataType *clearConfigData(ConfigDataType *configData); - -/* -Name: configCodeToString -Process: utility fct converts configuration code numbers to string they represent -Function Input/Parameters: configuration code (int) -Function Output/Parameters: resulting output string (char *) -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: copyString -*/ -void configCodeToString(int code, char *outString); - -/* -Name: displayConfigData -Process: screen dump/display of all config data -Function Input/Parameters: pointer to config data structure (ConfigDataType *) -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Monitor: displayed as spec'd -Dependencies: ??? -*/ -void displayConfigData(ConfigDataType *configData); - -/* -Name: getConfigData -Process: driver function for capturing config data from config file -Function Input/Parameters: file name (const char *) -Function Output/Parameters: pointer to config data pointer (ConfigDataType **) - end/result state message pointer (char *) -Function Output/Returned: Boolean result of data access operation (bool) -Device Input/File: config data uploaded -Device Output/Device: none -Dependencies: copyString, fopen, getStringToDelimiter, compareString, fclose, - malloc, free, stripTrailingSpaces, getDataLineCode, fscanf, - setStrToLowerCase, valueInRange, getCpuSchedCode, getLogToCode -*/ -bool getConfigData(const char *fileName, - ConfigDataType **configData, char *endStateMsg); - -/* -Name: getCpuSchedCode -Process: converts cpu schedule string to code (all scheduling possibilities) -Function Input/Parameters: lower case code string (const char *) -Function Output/Parameters: none -Function Output/Returned: cpu schedule code (ConfigDataCodes) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -ConfigDataCodes getCpuSchedCode(const char *lowerCaseCodeStr); - -/* -Name: getDataLineCode -Process: converts leader line string to configuration code value - (processes all config file leader lines) -Function Input/Parameters: config leader line string (const char *) -Function Output/Parameters: none -Function Output/Returned: configuration code value (ConfigCodeMessages) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -ConfigCodeMessages getDataLineCode(const char *dataBuffer); - -/* -Name: getLogToCode -Process: converts "log to" text to - configuration data code (three log to strings) -Function Input/Parameters: lower case log to string (const char *) -Function Output/Parameters: none -Function Output/Returned: configuration data code value -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -ConfigDataCodes getLogToCode(const char *lowerCaseLogToStr); - -/* -Name: stripTrailingSpaces -Process: removes trailing spaces from input config leader lines -Function Input/Parameters: config leader line string (char *) -Function Output/Parameters: updates config leader line string (char *) -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: getStringLength -*/ -void stripTrailingSpaces(char *str); - -/* -Name: valueInRange -Process: checks for config data values in range, including str values -Function Input/Parameters: line code number for specific config value (int), - integer value, as needed (int), - double value, as needed (double), - string value, as needed (const char *) -Function Output/Parameters: none -Function Output/Returned: Boolean result of the range test (bool) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -bool valueInRange(int lineCode, int intVal, double doubleVal, - const char *lowerCaseStringVal); - -#endif // CONFIGOPS \ No newline at end of file diff --git a/Sim04/logfile_1.lgf b/Sim04/logfile_1.lgf deleted file mode 100644 index e69de29..0000000 diff --git a/Sim04/metadata5.mdf b/Sim04/metadata5.mdf deleted file mode 100644 index 3225e59..0000000 --- a/Sim04/metadata5.mdf +++ /dev/null @@ -1,75 +0,0 @@ -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 -mem allocate, 4000, 2000 -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 -mem allocate, 1000, 3000 -dev out, sound signal, 45 -dev out, hard drive, 15 -dev in, video signal, 49 -dev out, serial, 20 -mem access, 2000, 1000 -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 -mem allocate, 1500, 2000 -cpu process, 9 -dev in, keyboard, 70 -dev in, video signal, 42 -mem access, 2800, 1000 -cpu process, 5 -cpu process, 6 -app end -app start, 0 -dev in, hard drive, 21 -dev out, sound signal, 30 -cpu process, 7 -mem allocate, 2500, 3000 -dev in, keyboard, 80 -dev in, hard drive, 30 -dev out, video signal, 63 -mem access, 2600, 1500 -dev in, serial, 28 -dev out, sound signal, 25 -cpu process, 9 -mem allocate, 2500, 1000 -dev out, sound signal, 45 -app end -app start, 0 -dev in, serial, 24 -dev out, video signal, 42 -mem allocate, 3000, 3000 -cpu process, 5 -dev in, usb, 10 -cpu process, 8 -cpu process, 9 -mem access, 3500, 2000 -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/Sim04/metadataops.c b/Sim04/metadataops.c deleted file mode 100644 index f2b2256..0000000 --- a/Sim04/metadataops.c +++ /dev/null @@ -1,729 +0,0 @@ -#include "metadataops.h" -#include "StandardConstants.h" -#include "StringUtils.h" - -/* -Name: addNode -Process: adds metadata node to linked list recursively, handles empty list -Function Input/Parameters: ptr to head or next linked node (OpCodeType *), - ptr to new node (OpCodeType *) -Function Output/Parameters: none -Function Output/Returned: pointer to previous node, or head node (OpCodeType *) -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, copyString -*/ -OpCodeType *addNode(OpCodeType *localPtr, OpCodeType *newNode) -{ - // initialize function and variables - // check for local pointer assigned to null - if(localPtr == NULL) - { - // access memory for new link/node - // fct: malloc - localPtr = (OpCodeType *) malloc(sizeof(OpCodeType)); - // assign all three values to newly created node - // assign next pointer to null - // fct: copyString - localPtr->pid = newNode->pid; - copyString(localPtr->command, newNode->command); - copyString(localPtr->inOutArg, newNode->inOutArg); - copyString(localPtr->strArg1, newNode->strArg1); - localPtr->intArg2 = newNode->intArg2; - localPtr->intArg3 = newNode->intArg3; - localPtr->opEndTime = newNode->opEndTime; - localPtr->nextNode = NULL; - // return current local pointer - return localPtr; - } - // assume end of list not found - // assign recursive fct to current node's next link - // fct: addNode - localPtr->nextNode = addNode(localPtr->nextNode, newNode); - // return current local ptr - return localPtr; -} - -/* -Name: clearMetaDataList -Process: recursively traverses list, frees dynamically allocated nodes -Function Input/Parameters: node opcode (const OpCodeType *) -Function Output/Parameters: none -Function Output/Returned: NULL (OpCodeType *) -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -OpCodeType *clearMetaDataList(OpCodeType *localPtr) -{ - // initialize function and variables - // check for local pointer not set to null (list not empty) - if(localPtr != NULL) - { - // call recursive function with next pointer - // fct: clearMetaDataList - clearMetaDataList(localPtr->nextNode); - // after recursive call, release mem to OS - // fct: free - free(localPtr); - // set given pointer to NULL - localPtr = NULL; - } - // return NULL to calling fct - return NULL; -} - -/* -Name: displayMetaData -Process: data dump/display of all opcode items -Function Input/Parameters: pointer to - head of opcode/metadata list (const OpCodeType *) -Function Output/Parameters: none -Function Output/Returned: calculated time (int) -Device Input/Device: none -Device Output/Device: none -Dependencies: printf, compareString -*/ -void displayMetaData(const OpCodeType *localPtr) -{ - // initialize function and variables - // display title, with underline - // fct: printf - printf("Metadata File Display\n"); - printf("---------------------\n\n"); - // loop to end of linked list - while(localPtr != NULL) - { - // print leader - // fct: printf - printf("Opcode: "); - // print opcode pid - // fct: printf - printf("/pid: %d", localPtr->pid); - // print opcode command - // fct: printf - printf("/cmd: %s", localPtr->command); - // check for dev op - if(compareString(localPtr->command, "dev") == 0) - { - // print in/out parameter - // fct: printf - printf("/io: %s", localPtr->inOutArg); - } - // otherwise, assume other than dev - else - { - // print NA - // fct: printf - printf("/io: NA"); - } - // print first string argument - // fct: printf - printf("\n\t/arg 1: %s", localPtr->strArg1); - // print first int argument - // fct: printf - printf("/arg 2: %d", localPtr->intArg2); - // print second int argument - // fct: printf - printf("/arg 3: %d", localPtr->intArg3); - // print op end time - printf("/op end time: %8.6f", localPtr->opEndTime); - // endline print - // fct: printf - printf("\n\n"); - // assign local pointer to next node - localPtr = localPtr->nextNode; - } - // void function, no return. -} - -/* -Name: getCommand -Process: parses thre letter command part of opcode str -Function Input/Parameters: input opcode str (const char *), - starting index (int) -Function Output/Parameters: parsed command (char *) -Function Output/Returned: updated starting index for use by calling fct (int) -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -int getCommand(char *cmd, const char *inputStr, int index) -{ - // initialize function and variables - int lengthOfCommand = 3; - // loop across command length - while(index < lengthOfCommand) - { - // assign character from input string to buffer string - cmd[index] = inputStr[index]; - // increment index - index = index + 1; - // set next character to null character - cmd[index] = NULL_CHAR; - } - // return current index - return index; -} - -/* -Name: getMetaData -Process: main driver function to upload, parse, and store list - of op code commands in a linked list -Function Input/Parameters: file name (const char *) -Function Output/Parameters: ptr to opcode linked list head ptr (OpCodeType **), - result msg of fct state after completion (char *) -Function Output/Returned: Boolean result of operation (bool) -Device Input/File: op code list uploaded -Device Output/Device: none -Dependencies: copyString, fopen, getStringToDelimiter, compareString, fclose, - malloc, getOpCommand, updateStartCount, updateEndCount, - clearMetaDataList, free, addNode -*/ -bool getMetaData(const char *fileName, - OpCodeType **opCodeDataHead, char *endStateMsg) -{ - // initialize function and variables - // iniitialize read only constant - const char READ_ONLY_FLAG[] = "r"; - // initialize variables - int accessResult, startCount = 0, endCount = 0; - char dataBuffer[MAX_STR_LEN]; - bool returnState = true; - OpCodeType *newNodePtr; - OpCodeType *localHeadPtr = NULL; - FILE *fileAccessPtr; - // initialize opcode data pointer in case of return error - *opCodeDataHead = NULL; - // initialize end state message - // fct: copyString - copyString(endStateMsg, "Metadata file upload successful"); - // open file for reading - // fct: fopen - fileAccessPtr = fopen(fileName, READ_ONLY_FLAG); - // check for file open failure - if(fileAccessPtr == NULL) - { - // set end state message - // fct: copyString - copyString(endStateMsg, "Metadata file access error"); - // return file access error - return false; - } - // check first line for correct leader - // fct: getStringToDelimiter, compareString - if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer) || - compareString(dataBuffer, "Start Program Meta-Data Code") != 0) - { - // close file - // fct: fclose - fclose(fileAccessPtr); - // set end state message - // fct: copyString - copyString(endStateMsg, "Corrupt metadata leader line error"); - // return corrupt descriptor error - return false; - } - // allocate memory for the temporary data structure - // fct: malloc - newNodePtr = (OpCodeType *) malloc(sizeof(OpCodeType)); - // get the first op command - // fct: getOpCommand - accessResult = getOpCommand(fileAccessPtr, newNodePtr); - // get start and end counts for later comparison - // fct: updateStartCount, updateEndCount - startCount = updateStartCount(startCount, newNodePtr->strArg1); - endCount = updateEndCount(endCount, newNodePtr->strArg1); - // check for failure of first complete op command - if(accessResult != COMPLETE_OPCMD_FOUND_MSG) - { - // close file - // fct: fclose - fclose(fileAccessPtr); - // clear data from the structure list - // fct: clearMetaDataList - *opCodeDataHead = clearMetaDataList(localHeadPtr); - // free temporary structure memory - // fct: free - free(newNodePtr); - // set end state message - // fct: copyString - copyString(endStateMsg, "Metadata incomplete first op command found"); - // return result of operation - return false; - } - // loop across all remaining op commands - // (while complete op commands are found) - while(accessResult == COMPLETE_OPCMD_FOUND_MSG) - { - // add the new op command to the linked list - // fct: addNode - localHeadPtr = addNode(localHeadPtr, newNodePtr); - // get a new op command - // fct: getOpCommand - accessResult = getOpCommand(fileAccessPtr, newNodePtr); - // update start and end counts for later comparison - // fct: updateStartCount, updateEndCount - startCount = updateStartCount(startCount, newNodePtr->strArg1); - endCount = updateEndCount(endCount, newNodePtr->strArg1); - } - // end loop across all remaining op commands - // check for last op command found - if(accessResult == LAST_OPCMD_FOUND_MSG) - { - // check for start and end opcode counts equal - if(startCount == endCount) - { - // add the last node to the linked list - // fct: addNode - localHeadPtr = addNode(localHeadPtr, newNodePtr); - // set access result to no error for later operation - accessResult = NO_ACCESS_ERR; - // check last line for incorrect end descriptor - // fct: getStringToDelimiter, compareString - if(!getStringToDelimiter(fileAccessPtr, PERIOD, dataBuffer) || - compareString(dataBuffer, "End Program Meta-Data Code") != 0) - { - // set access result to corrupted descriptor error - accessResult = MD_CORRUPT_DESCRIPTOR_ERR; - // set end state message - // fct: copyString - copyString(endStateMsg, "Metadata corrupted descriptor error"); - } - } - // otherwise, assume start/end counts not equal - else - { - // close file - // fct: fclose - fclose(fileAccessPtr); - // clear data from the structure list - // fct: clearMetaDataList - *opCodeDataHead = clearMetaDataList(localHeadPtr); - // free temporary structure memory - // fct: free - free(newNodePtr); - // set access result to error - accessResult = UNBALANCED_START_END_ERR; - // set end state message - // fct: copyString - copyString(endStateMsg, - "Unbalanced start and end arguments in metadata"); - // return result of operation - return false; - } - } - // otherwise, assume didn't find end - else - { - // set end state message - // fct: copyString - copyString(endStateMsg, "Corrupted metadata opcode"); - // unset return state - returnState = false; - } - // check for any errors found (not no error) - if(accessResult != NO_ACCESS_ERR) - { - // clear the op command list - // fct: clearMetaDataList - localHeadPtr = clearMetaDataList(localHeadPtr); - } - // close access file - // fct: fclose - fclose(fileAccessPtr); - // release temporary structure memory - // fct: free - free(newNodePtr); - // assign temporary local head ptr to parameter return ptr - *opCodeDataHead = localHeadPtr; - // return access result - return returnState; -} - -/* -Name: getOpCommand -Process: acquires one op command line from a previously opened file, - parses it, and sets various struct members according to the - three letter command -Function Input/Parameters: ptr to open file handle (FILE *) -Function Output/Parameters: ptr to one opcode struct (OpCodeType *) -Function Output/Returned: coded result of operation (OpCodeMessages) -Device Input/File: opcode line uploaded -Device Output/Device: none -Dependencies: getStringToDelimiter, getCommand, copyString, verifyValidCommand, - compareString, getStringArg, verifyFirstStringArg, getNumberArg -*/ -OpCodeMessages getOpCommand(FILE *filePtr, OpCodeType *inData) -{ - // initialize function and variables - // initialize local constants - const int MAX_CMD_LENGTH = 5; - const int MAX_ARG_STR_LENGTH = 15; - // initialize other variables - int numBuffer = 0; - char strBuffer[STD_STR_LEN]; - char cmdBuffer[MAX_CMD_LENGTH]; - char argStrBuffer[MAX_ARG_STR_LENGTH]; - int runningStringIndex = 0; - bool arg2FailureFlag = false; - bool arg3FailureFlag = false; - // get whole op command as string, check for successful access - // fct: getStringToDelimiter - if(getStringToDelimiter(filePtr, SEMICOLON, strBuffer)) - { - // get three-letter command - // fct: getCommand - runningStringIndex = getCommand(cmdBuffer, - strBuffer, runningStringIndex); - // assign op command to node - // fct: copyString - copyString(inData->command, cmdBuffer); - } - // otherwise, assume unsuccessful access - else - { - // set ptr to data structure to null - inData = NULL; - // return op command access failure - return OPCMD_ACCESS_ERR; - } - // verify op command - if(!verifyValidCommand(cmdBuffer)) - { - // return op command error - return CORRUPT_OPCMD_ERR; - } - // set all struct values that may not be initialized to defaults - inData->pid = 0; - inData->inOutArg[0] = NULL_CHAR; - inData->intArg2 = 0; - inData->intArg3 = 0; - inData->opEndTime = 0.0; - inData->nextNode = NULL; - // check for device command - if(compareString(cmdBuffer, "dev") == 0) - { - // get in/out arg - runningStringIndex = getStringArg(argStrBuffer, - strBuffer, runningStringIndex); - // set device in/out arg - copyString(inData->inOutArg, argStrBuffer); - // check correct argument - if(compareString(argStrBuffer, "in") != 0 && - compareString(argStrBuffer, "out") != 0) - { - // return argument error - return CORRUPT_OPCMD_ARG_ERR; - } - } - // get first string arg - runningStringIndex = getStringArg(argStrBuffer, - strBuffer, runningStringIndex); - // set device in/out arg - copyString(inData->strArg1, argStrBuffer); - // check for legit first string arg - if(!verifyFirstStringArg(argStrBuffer)) - { - // return arg error - return CORRUPT_OPCMD_ARG_ERR; - } - // check for last op command found - if(compareString(inData->command, "sys") == 0 && - compareString(inData->strArg1, "end") == 0) - { - // return last op command found message - return LAST_OPCMD_FOUND_MSG; - } - // check for app start seconds argument - if(compareString(inData->command, "app") == 0 && - compareString(inData->strArg1, "start") == 0) - { - // get number argument - // fct: getNumberArg - runningStringIndex = getNumberArg(&numBuffer, - strBuffer, runningStringIndex); - // check for failed number access - if(numBuffer <= BAD_ARG_VAL) - { - // set failure flag - arg2FailureFlag = true; - } - // set first int argument to number - inData->intArg2 = numBuffer; - } - // check for cpu cycle time - else if(compareString(inData->command, "cpu") == 0) - { - // get number argument - // fct: getNumberArg - runningStringIndex = getNumberArg(&numBuffer, - strBuffer, runningStringIndex); - // check for failed number access - if(numBuffer <= BAD_ARG_VAL) - { - // set failure flag - arg2FailureFlag = true; - } - // set first int argument to number - inData->intArg2 = numBuffer; - } - // check for device cycle time - else if(compareString(inData->command, "dev") == 0) - { - // get number argument - // fct: getNumberArg - runningStringIndex = getNumberArg(&numBuffer, - strBuffer, runningStringIndex); - // check for failed number access - if(numBuffer <= BAD_ARG_VAL) - { - // set failure flag - arg2FailureFlag = true; - } - // set first int argument to number - inData->intArg2 = numBuffer; - } - // check for memory base and offset - else if(compareString(inData->command, "mem") == 0) - { - // get number argument - // fct: getNumberArg - runningStringIndex = getNumberArg(&numBuffer, - strBuffer, runningStringIndex); - // check for failed number access - if(numBuffer <= BAD_ARG_VAL) - { - // set failure flag - arg2FailureFlag = true; - } - // set first int argument to number - inData->intArg2 = numBuffer; - // get number argument for offset - // fct: getNumberArg - runningStringIndex = getNumberArg(&numBuffer, - strBuffer, runningStringIndex); - if(numBuffer <= BAD_ARG_VAL) - { - // set failure flag - arg3FailureFlag = true; - } - // set second int argument to number - inData->intArg3 = numBuffer; - } - // check int args for upload failure - if(arg2FailureFlag || arg3FailureFlag) - { - // return corrupt op command found message - return CORRUPT_OPCMD_ARG_ERR; - } - // return complete op command found message - return COMPLETE_OPCMD_FOUND_MSG; -} - -/* -Name: getNumberArg -Process: starts at given index, captures - and assembles int arg, returns as parameter -Function Input/Parameters: input str (const char *), starting index (int) -Function Output/Parameters: pointer to captured integer value -Function Output/Returned: updated index for next function start -Device Input/Device: none -Device Output/Device: none -Dependencies: isDigit -*/ -int getNumberArg(int *number, const char *inputStr, int index) -{ - // initialize function and variables - bool foundDigit = false; - *number = 0; - int multiplier = 1; - // loop to skip whitespace - while(inputStr[index] <= SPACE || inputStr[index] == COMMA) - { - // increment the index - index = index + 1; - } - // loop across string length - while(isDigit(inputStr[index]) && - inputStr[index] != NULL_CHAR) - { - // set digit found flag - foundDigit = true; - // assign digit to output - (*number) = (*number) * multiplier + (inputStr[index] - '0'); - // increment index and multiplier - index = index + 1; - multiplier = 10; - } - // check for digit not found - if(!foundDigit) - { - // set number to BAD_ARG_VAL, use dereference for ptr - *number = BAD_ARG_VAL; - } - // return current index - return index; -} - -/* -Name: getStringArg -Process: starts at given index, captures - and assembles str arg, returns as parameter -Function Input/Parameters: input str (const char *), starting index (int) -Function Output/Parameters: ptr to captured string argument (char *) -Function Output/Returned: updated index for next fct start -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -int getStringArg(char *strArg, const char *inputStr, int index) -{ - // initialize function and variables - int localIndex = 0; - // loop to skip whitespace - while(inputStr[index] <= SPACE || inputStr[index] == COMMA) - { - // increment the index - index = index + 1; - } - // loop across string length - while(inputStr[index] != COMMA && inputStr[index] != NULL_CHAR) - { - // assign character from input string to buffer string - strArg[localIndex] = inputStr[index]; - // increment index - index = index + 1; - localIndex = localIndex + 1; - // set next character to null character - strArg[localIndex] = NULL_CHAR; - } - // return current index - return index; -} - -/* -Name: isDigit -Process: tests character parameter for digit, - returns true if is digit, false otherwise -Function Input/Parameters: test character (char) -Function Output/Parameters: none -Function Output/Returned: bool result of test (bool) -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -bool isDigit(char testChar) -{ - // check for test character between characters '0' - '9' - // return true - // otherwise, assume character if not digit, return false - return testChar >= '0' && testChar <= '9'; -} - -/* -Name: updateEndCount -Process: manages count of "end" arguments - to be compared at end of process input -Function Input/Parameters: initial count (int), - test string for "end" (const char *) -Function Output/Parameters: none -Function Output/Returned: updated count, if "end" string found, - otherwise no change -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -int updateEndCount(int count, const char *opString) -{ - // check for "end" in op string - // fct: compareString - if(compareString(opString, "end") == 0) - { - // return incremented end count - return count + 1; - } - // return unchanged end count - return count; -} - -/* -Name: updateStartCount -Process: manages count of "start" arguments - to be compared at start of process input -Function Input/Parameters: initial count (int), - test string for "start" (const char *) -Function Output/Parameters: none -Function Output/Returned: updated count, if "start" string found, - otherwise no change -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -int updateStartCount(int count, const char *opString) -{ - // check for "start" in op string - // fct: compareString - if (compareString(opString, "start") == 0) - { - // return incremented start count - return count + 1; - } - // return unchanged start count - return count; -} - -/* -Name: verifyFirstStringArg -Process: checks for all possibilities of first argument string of op command -Function Input/Parameters: test string (const char *) -Function Output/Parameters: none -Function Output/Returned: bool result of test (bool) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -bool verifyFirstStringArg(const char *strArg) -{ - // check for string holding correct first argument - // fct: compareString - // return true - // otherwise, assume test fail, return false - return compareString(strArg, "access") == 0 || - compareString(strArg, "allocate") == 0 || - compareString(strArg, "end") == 0 || - compareString(strArg, "ethernet") == 0 || - compareString(strArg, "hard drive") == 0 || - compareString(strArg, "keyboard") == 0 || - compareString(strArg, "monitor") == 0 || - compareString(strArg, "printer") == 0 || - compareString(strArg, "process") == 0 || - compareString(strArg, "serial") == 0 || - compareString(strArg, "sound signal") == 0 || - compareString(strArg, "start") == 0 || - compareString(strArg, "usb") == 0 || - compareString(strArg, "video signal") == 0; -} - -/* -Name: verifyValidCommand -Process: checks for all possibilities of three-letter opcode command -Function Input/Parameters: test string for command (const char *) -Function Output/Parameters: none -Function Output/Returned: bool result of test (bool) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -bool verifyValidCommand(char *testCmd) -{ - // check for string holding three-letter opcode command - // fct: compareString - // return true - // otherwise, assume test failure, return false - return compareString(testCmd, "sys") == 0 || - compareString(testCmd, "app") == 0 || - compareString(testCmd, "cpu") == 0 || - compareString(testCmd, "mem") == 0 || - compareString(testCmd, "dev") == 0; -} \ No newline at end of file diff --git a/Sim04/metadataops.h b/Sim04/metadataops.h deleted file mode 100644 index 162c36a..0000000 --- a/Sim04/metadataops.h +++ /dev/null @@ -1,207 +0,0 @@ -#ifndef METADATAOPS -#define METADATAOPS - -#include "StandardConstants.h" -#include "StringUtils.h" - -typedef enum {BAD_ARG_VAL = -1, - NO_ACCESS_ERR, - MD_FILE_ACCESS_ERR, - MD_CORRUPT_DESCRIPTOR_ERR, - OPCMD_ACCESS_ERR, - CORRUPT_OPCMD_ERR, - CORRUPT_OPCMD_ARG_ERR, - UNBALANCED_START_END_ERR, - COMPLETE_OPCMD_FOUND_MSG, - LAST_OPCMD_FOUND_MSG - } OpCodeMessages; - -typedef struct OpCodeTypeStruct -{ - int pid; - char command[MAX_STR_LEN]; - char inOutArg[MAX_STR_LEN]; - char strArg1[MAX_STR_LEN]; - int intArg2; - int intArg3; - double opEndTime; - struct OpCodeTypeStruct *nextNode; -} OpCodeType; - -/* -Name: addNode -Process: adds metadata node to linked list recursively, handles empty list -Function Input/Parameters: ptr to head or next linked node (OpCodeType *), - ptr to new node (OpCodeType *) -Function Output/Parameters: none -Function Output/Returned: pointer to previous node, or head node (OpCodeType *) -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, copyString -*/ -OpCodeType *addNode(OpCodeType *localPtr, OpCodeType *newNode); - -/* -Name: clearMetaDataList -Process: recursively traverses list, frees dynamically allocated nodes -Function Input/Parameters: node opcode (const OpCodeType *) -Function Output/Parameters: none -Function Output/Returned: NULL (OpCodeType *) -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -OpCodeType *clearMetaDataList(OpCodeType *localPtr); - -/* -Name: displayMetaData -Process: data dump/display of all opcode items -Function Input/Parameters: pointer to - head of opcode/metadata list (const OpCodeType *) -Function Output/Parameters: none -Function Output/Returned: calculated time (int) -Device Input/Device: none -Device Output/Device: none -Dependencies: printf, compareString -*/ -void displayMetaData(const OpCodeType *localPtr); - -/* -Name: getCommand -Process: parses thre letter command part of opcode str -Function Input/Parameters: input opcode str (const char *), - starting index (int) -Function Output/Parameters: parsed command (char *) -Function Output/Returned: updated starting index for use by calling fct (int) -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -int getCommand(char *cmd, const char *inputStr, int index); - -/* -Name: getMetaData -Process: main driver function to upload, parse, and store list - of op code commands in a linked list -Function Input/Parameters: file name (const char *) -Function Output/Parameters: ptr to opcode linked list head ptr (OpCodeType **), - result msg of fct state after completion (char *) -Function Output/Returned: Boolean result of operation (bool) -Device Input/File: op code list uploaded -Device Output/Device: none -Dependencies: copyString, fopen, getStringToDelimiter, compareString, fclose, - malloc, getOpCommand, updateStartCount, updateEndCount, - clearMetaDataList, free, addNode -*/ -bool getMetaData(const char *fileName, - OpCodeType **opCodeDataHead, char *endStateMsg); - -/* -Name: getOpCommand -Process: acquires one op command line from a previously opened file, - parses it, and sets various struct members according to the - three letter command -Function Input/Parameters: ptr to open file handle (FILE *) -Function Output/Parameters: ptr to one opcode struct (OpCodeType *) -Function Output/Returned: coded result of operation (OpCodeMessages) -Device Input/File: opcode line uploaded -Device Output/Device: none -Dependencies: getStringToDelimiter, getCommand, copyString, verifyValidCommand, - compareString, getStringArg, verifyFirstStringArg, getNumberArg -*/ -OpCodeMessages getOpCommand(FILE *filePtr, OpCodeType *inData); - -/* -Name: getNumberArg -Process: starts at given index, captures - and assembles int arg, returns as parameter -Function Input/Parameters: input str (const char *), starting index (int) -Function Output/Parameters: pointer to captured integer value -Function Output/Returned: updated index for next function start -Device Input/Device: none -Device Output/Device: none -Dependencies: isDigit -*/ -int getNumberArg(int *number, const char *inputStr, int index); - -/* -Name: getStringArg -Process: starts at given index, captures - and assembles str arg, returns as parameter -Function Input/Parameters: input str (const char *), starting index (int) -Function Output/Parameters: ptr to captured string argument (char *) -Function Output/Returned: updated index for next fct start -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -int getStringArg(char *strArg, const char *inputStr, int index); - -/* -Name: isDigit -Process: tests character parameter for digit, - returns true if is digit, false otherwise -Function Input/Parameters: test character (char) -Function Output/Parameters: none -Function Output/Returned: bool result of test (bool) -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -bool isDigit(char testChar); - -/* -Name: updateEndCount -Process: manages count of "end" arguments - to be compared at end of process input -Function Input/Parameters: initial count (int), - test string for "end" (const char *) -Function Output/Parameters: none -Function Output/Returned: updated count, if "end" string found, - otherwise no change -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -int updateEndCount(int count, const char *opString); - -/* -Name: updateStartCount -Process: manages count of "start" arguments - to be compared at start of process input -Function Input/Parameters: initial count (int), - test string for "start" (const char *) -Function Output/Parameters: none -Function Output/Returned: updated count, if "start" string found, - otherwise no change -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -int updateStartCount(int count, const char *opString); - -/* -Name: verifyFirstStringArg -Process: checks for all possibilities of first argument string of op command -Function Input/Parameters: test string (const char *) -Function Output/Parameters: none -Function Output/Returned: bool result of test (bool) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -bool verifyFirstStringArg(const char *strArg); - -/* -Name: verifyValidCommand -Process: checks for all possibilities of three-letter opcode command -Function Input/Parameters: test string for command (const char *) -Function Output/Parameters: none -Function Output/Returned: bool result of test (bool) -Device Input/Device: none -Device Output/Device: none -Dependencies: compareString -*/ -bool verifyValidCommand(char *testCmd); - -#endif // METADATAOPS \ No newline at end of file diff --git a/Sim04/sim04 b/Sim04/sim04 deleted file mode 100755 index 52d566410c0ce6b0efe5cc02c0b61ae27c4f8967..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73944 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 0 ) - { - timeStr[ index ] = (char) ( uSecTime % 10 + '0' ); - uSecTime /= 10; - - index++; - - } - - while( index < 6 ) - { - timeStr[ index ] = '0'; - - index++; - } - - timeStr[ index ] = RADIX_POINT; - - index++; - - if( secTime < 10 ) // single digit in display - { - timeStr[ index ] = (char) ( secTime % 10 + '0' ); - - index++; - - timeStr[ index ] = SPACE; - - index++; - - secTime = 0; - } -/* - if( secTime == 0 ) - { - timeStr[ index ] = '0'; - - index++; - } -*/ - while( secTime > 0 ) - { - timeStr[ index ] = (char) ( secTime % 10 + '0' ); - - secTime /= 10; - - index++; - } - - timeStr[ index ] = NULL_CHAR; - - low = 0; high = index - 1; - - while( low < high ) - { - temp = timeStr[ low ]; - timeStr[ low ] = timeStr[ high ]; - timeStr[ high ] = temp; - - low++; high--; - } - } - -#endif // ifndef SIMTIMER_C - - - - - diff --git a/Sim04/simtimer.h b/Sim04/simtimer.h deleted file mode 100644 index f57ae94..0000000 --- a/Sim04/simtimer.h +++ /dev/null @@ -1,49 +0,0 @@ -// Program Information //////////////////////////////////////////////////////// -/** - * @file SimpleTimer.h - * - * @brief Header file for micro-second precision timer - * - * @author Michael Leverington - * - * @details Specifies all member methods of the SimpleTimer - * - * @version 2.00 (13 January 2017) - * 1.00 (11 September 2015) - * - * @Note None - */ - -// Precompiler directives ///////////////////////////////////////////////////// - -#ifndef SIMTIMER_H -#define SIMTIMER_H - -// Header files /////////////////////////////////////////////////////////////// - -#include -#include -#include -#include "OS_SimDriver.h" - -// Global Constants ////////////////////////////////////////////////////////// - -enum TIMER_CTRL_CODES { ZERO_TIMER, LAP_TIMER, STOP_TIMER }; - -extern const char RADIX_POINT; -extern const char SPACED; - -// Function Prototyp ///////////////////////////////////////////////////////// - -void *runTimer(void *mSecVoidPtr); -// will run a timer for the amount of ms specified -double accessTimer( int controlCode, char *timeStr ); -// returns the actual time as a double AND as a time string - -// no more access needed beyond this point (supporting functions) -double processTime( double startSec, double endSec, - double startUSec, double endUSec, char *timeStr ); -void timeToString( int secTime, int uSecTime, char *timeStr ); - -#endif // ifndef SIMTIMER_H - diff --git a/Sim04/simulator.c b/Sim04/simulator.c deleted file mode 100644 index 4867aca..0000000 --- a/Sim04/simulator.c +++ /dev/null @@ -1,1293 +0,0 @@ -#include "simulator.h" - -/* -Name: accessMemory -Process: checks that the memory is between the offset and the size. - checks that the memory is ??? -Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int) -Function Output/Parameters: none -Function Output/Returned: boolean to indicate success or failure of accessed memory -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool accessMemory(ProcessControlBlock *singlePCB, int offset, int size) -{ - // return true (temp) - return true; -} - -/* -Name: addProcess -Process: allocates the memory for the pcb, grabs the data from the created PCB, - dumps the data so that the node can be linked correctly. -Function Input/Parameters: source PCB (ProcessControlBlock) -Function Output/Parameters: none -Function Output/Returned: filled PCB (ProcessControlBlock *) -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, sizeof, ??? -*/ -ProcessControlBlock *addProcess(const ProcessControlBlock source) -{ - // declare a pointer to working node - ProcessControlBlock *workingNode; - // make some space that the pointer is pointing to - workingNode = malloc(sizeof(ProcessControlBlock)); - // get each value from the source, and set their values - workingNode->uniquePid = source.uniquePid; - workingNode->cpuCycles = source.cpuCycles; - workingNode->ioCycles = source.ioCycles; - workingNode->nextOpCode = source.nextOpCode; - workingNode->process_state = source.process_state; - workingNode->timeLeft = source.timeLeft; - workingNode->totalCycles = source.totalCycles; - workingNode->allocatedMemOffsets = (int *) malloc(sizeof(int) * source.memArraySize); - workingNode->allocatedMemSizes = (int *) malloc(sizeof(int) * source.memArraySize); - workingNode->memArraySize = source.memArraySize; - // make sure to set the next pointer to NULL! - workingNode->nextPtr = NULL; - // return workingNode - return workingNode; -} - -/* -Name: allocMemory -Process: 'allocates' memory within the PCB, stores offset and size within it's PCB -Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int) -Function Output/Parameters: none -Function Output/Returned: boolean to indicate success or failure of allocated memory -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool allocMemory(ProcessControlBlock *singlePCB, int offset, int size, int arraySize) -{ - int allocateIterator = 0; - // while until a '-1' is hit, then store the value. - while(singlePCB->allocatedMemSizes[allocateIterator] != -1 && allocateIterator < arraySize) - { - // - singlePCB->allocatedMemOffsets[allocateIterator] = offset; - singlePCB->allocatedMemSizes[allocateIterator] = size; - allocateIterator = allocateIterator + 1; - // printf("Alloc Iter: %d\n", allocateIterator); - } - // return true (temp) - return true; -} - -/* -Name: createProcessList -Process: reads through the opcode struct to fill out the linked list of PCBs -Function Input/Parameters: none -Function Output/Parameters: none -Function Output/Returned: head pointer to the PCBs -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, sizeof, ??? -*/ -ProcessControlBlockLL *createProcessList() -{ - // allocate and create the ProcessControlBlockLL using malloc and size of - ProcessControlBlockLL *headBlock; - headBlock = malloc(sizeof(ProcessControlBlockLL)); - // set the head pointer to NULL - headBlock->headPtr = NULL; - // return headBlock - return headBlock; -} - -/* -Name: deallocMemory -Process: 'deallocates' memory within the PCB, removes every offset and size within it's PCB -Function Input/Parameters: source PCB (ProcessControlBlock *) -Function Output/Parameters: none -Function Output/Returned: boolean to indicate success or failure of allocated memory -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool deallocMemory(ProcessControlBlock *singlePCB, int arraySize) -{ - int deallocateIterator; - // while until a '-1' is hit, then store the value. - for (deallocateIterator = 0; deallocateIterator < arraySize; deallocateIterator++) - { - // - singlePCB->allocatedMemOffsets[deallocateIterator] = -1; - singlePCB->allocatedMemSizes[deallocateIterator] = -1; - } - // return true (temp) - return true; -} - -/* -Name: destroyProcessList -Process: deallocates memory used for the linked list struct -Function Input/Parameters: head pointer to linked list (ProcessControlBlockLL *) -Function Output/Parameters: none -Function Output/Returned: NULL -Device Input/Device: none -Device Output/Device: none -Dependencies: free, destroyProcessListHelper, ??? -*/ -ProcessControlBlockLL *destroyProcessList(ProcessControlBlockLL *linkedListPtr) -{ - // call the first destroyProcessListHelper - destroyProcessListHelper(linkedListPtr->headPtr); - // free the rest of the struct - free(linkedListPtr); - // return null - return NULL; -} - -/* -Name: destroyProcessListHelper -Process: recursively clears the PCB linked list struct, freeing the struct -Function Input/Parameters: head pointer to linked list (ProcessControlBlockLL *) -Function Output/Parameters: none -Function Output/Returned: NULL -Device Input/Device: none -Device Output/Device: none -Dependencies: free, destroyProcessListHelper(recursively), ??? -*/ -ProcessControlBlock *destroyProcessListHelper(ProcessControlBlock *nodePtr) -{ - // check to see if the pointer is NOT null - if(nodePtr != NULL) - { - free(nodePtr->allocatedMemOffsets); - free(nodePtr->allocatedMemSizes); - // if not null, move to the next pointer (recurse) - nodePtr->nextPtr = destroyProcessListHelper(nodePtr->nextPtr); - } - // free the 'parent' node - free(nodePtr); - // return null - return NULL; -} - -/* -Name: fillProcessList -Process: iterates through the metadata LL, fills out each process as needed. -Function Input/Parameters: metadata (OpCodeType *), - headPointer (ProcessControlBlockLL *) -Function Output/Parameters: none -Function Output/Returned: pointer to filled PCB (ProcessControlBlockLL *) -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *metadataPtr, ProcessControlBlockLL *headPointer) -{ - // initialize function/variables - // need a working pointer for the metadata - OpCodeType *wkgMetaPtr; - ProcessControlBlock currentPCB; - ProcessControlBlock *wkgPCBPtr; - OpCodeType *wkgInsPtr; - // need a variable to count how many IO cycles are in the process - int ioCycleCount = 0; - // 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 - double timeLeftCount = 0.0; - // need a variable that fills PIDs, starting at 0 - int processId = 0; - // need a variable that checks how many allocate statements there are. - int memAllocation = 0; - // process variables? - char *command; - char *argument; - char *inOutArg; - int integerArgumentOne; - // unused as of current - //int integerArgumentTwo; - - // set the working pointer to the first part of the metadata pointer - wkgMetaPtr = metadataPtr; - wkgInsPtr = metadataPtr; - // set another working pointer to the first part of the PCB list - wkgPCBPtr = headPointer->headPtr; - - // 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 != NULL && !(compareString(argument, "end") == EQUIV && compareString(command, "sys") == EQUIV)) - { - currentPCB.nextOpCode = wkgInsPtr->nextNode; - integerArgumentOne = wkgMetaPtr->intArg2; - // if app start, - if (compareString(command, "app") && compareString(argument, "start")) - { - // set the unique ID for both PCB and Metadata - wkgMetaPtr->pid = processId; - currentPCB.uniquePid = processId; - // set the process state to PROCESS_STATE_NEW - currentPCB.process_state = PROCESS_STATE_NEW; - } - // count number of io cycles - if(compareString(command, "dev") == EQUIV) - { - integerArgumentOne = wkgMetaPtr->intArg2; - if(compareString(inOutArg, "in") == EQUIV) - { - // add up the IO cycle - ioCycleCount = ioCycleCount + integerArgumentOne; - } - else - { - // add up the IO cycle - ioCycleCount = ioCycleCount + integerArgumentOne; - } - } - // count number of cpu cycles - if ((compareString(argument, "process") == EQUIV && compareString(command, "cpu") == EQUIV)) - { - integerArgumentOne = wkgMetaPtr->intArg2; - cpuCycleCount = cpuCycleCount + integerArgumentOne; - - } - // count number of times memory is done, sub checks for how many allocates, accesses, etc. - if ((compareString(argument, "allocate") == EQUIV && compareString(command, "mem") == EQUIV)) - { - // allocate the memory - memAllocation = memAllocation + 1; - } - if ((compareString(argument, "end") == EQUIV && compareString(command, "app") == EQUIV)) - { - // set the ioCycles from variable - currentPCB.ioCycles = ioCycleCount; - // set the cpuCycles from variable - currentPCB.cpuCycles = cpuCycleCount; - // set totalCycles from adding both IO/CPU - currentPCB.totalCycles = ioCycleCount + cpuCycleCount; - // set number of allocations from variable, then reset. - currentPCB.memArraySize = memAllocation; - memAllocation = 0; - - // currentPCB must have the starting instruction from wkgInsPtr - wkgInsPtr = wkgMetaPtr; - - // set the time left from (ioCycles * ioCycleRate) + (cpuCycles * procCyclesRate) - // this gets the number of ms in the process. - timeLeftCount = (ioCycleCount * configPtr->ioCycleRate) + (cpuCycleCount * configPtr->procCycleRate); - currentPCB.timeLeft = timeLeftCount; - // increment the PID counter - processId = processId + 1; - - 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; - - } - // return headPointer - return headPointer; -} - -/* -Name: findMin -Process: compares two values, returns the smaller of the two. -Function Input/Parameters: two integer values (int) -Function Output/Parameters: none -Function Output/Returned: minimum of the two input integer values (int) -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -int findMin(int one, int another) -{ - int minimumVal = one; - if(another < minimumVal) - { - minimumVal = another; - } - // return zero(temp) - return minimumVal; -} - -/* -Name: interruptManager -Process: does the managing of interrupts for the program -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: ??? -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -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; -} - -/* -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: fprintf, ??? -*/ -void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd) -{ - if(configPtr->logToCode == LOGTO_BOTH_CODE) - { - // - FILE *fileWritePtr; - fileWritePtr = fopen(configPtr->logToFileName, "w+"); - if (fileWritePtr != NULL) - { - fprintf(fileWritePtr, "%s", logStr); - fprintf(stdout, "%s", logStr); - } - // no return, void - // close the file, if at the end. - if (isEnd) - { - fclose(fileWritePtr); - } - // fclose(fileWritePtr); - } - else if(configPtr->logToCode == LOGTO_FILE_CODE) - { - // - printf("\nSimulator will output to a file.\n"); - FILE *fileWritePtr; - fileWritePtr = fopen(configPtr->logToFileName, "w+"); - if (fileWritePtr != NULL) - { - fprintf(fileWritePtr, "%s", logStr); - } - // no return, void - // close the file, if at the end. - if (isEnd) - { - fclose(fileWritePtr); - } - // fclose(fileWritePtr); - } - else - { - fprintf(stdout, "%s", logStr); - } -} - -/* -Name: memManager -Process: checks to make sure an allocate will be successful, - makes sure that an access will not segfault (or return segfault if it does), - and initializes memory and deallocates memory -Function Input/Parameters: PCBList (ProcessControlBlockLL *), memory code (MEMORY_SIGNALS), - offset (int), size (int), configuration data (ConfigDataType *) -Function Output/Parameters: none -Function Output/Returned: boolean for success or failure of memory management -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -bool memManager(ProcessControlBlockLL *pcbList, MEMORY_SIGNALS memCode, int offset, int size, ConfigDataType *configPtr, - ProcessControlBlock *singlePCB) -{ - bool memDisplay = configPtr->memDisplay; - ProcessControlBlock *wkgPtr; - int availableMem = configPtr->memAvailable; - int usedMem = 0; - int currentOffset = 0; - int currentSize = 0; - int memIterator; - int *memorySizeArray; - int totalArraySize = 0; - bool subFunctionSuccess = true; - wkgPtr = pcbList->headPtr; - - // grab how much memory is being used total, then count how big the total memory array should be - while(wkgPtr != NULL) - { - // count up the total used memory within each process control block. - for(memIterator = 0; memIterator < wkgPtr->memArraySize; memIterator++) - { - if(wkgPtr->allocatedMemSizes[memIterator] != -1) - { - // grab how much memory is used by that process - usedMem = usedMem + wkgPtr->allocatedMemSizes[memIterator]; - } - totalArraySize = totalArraySize + 1; - } - // move to the next pointer - wkgPtr = wkgPtr->nextPtr; - } - - // reset the working pointer - wkgPtr = pcbList->headPtr; - - // declare the array for the memory - memorySizeArray = malloc(sizeof(int) * totalArraySize); - - // grab the entire memory structure, so that the memory can be contiguous - while (wkgPtr != NULL) - { - // count up the total used memory within each process control block. - for (memIterator = 0; memIterator < totalArraySize; memIterator++) - { - // grab how much memory is used by that process - memorySizeArray[memIterator] = wkgPtr->allocatedMemSizes[memIterator]; - } - // move to the next pointer - wkgPtr = wkgPtr->nextPtr; - } - - // grab the size of the - // while() - // { - // // - // } - - // switch case for each memory code - switch (memCode) - { - case MEMORY_INITIALIZE: - for(memIterator = 0; memIterator < singlePCB->memArraySize; memIterator++) - { - // initialize the arrays with all '-1' to 'nullify' the memory, make it easier to iterate through later - singlePCB->allocatedMemOffsets[memIterator] = -1; - singlePCB->allocatedMemSizes[memIterator] = -1; - } - if(memDisplay) - { - // - printf("--------------------------------------------------\n"); - printf("After memory initialization\n"); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - break; - - case MEMORY_ALLOCATE: - // check if the memory allocation can happen before storing it. - if(size <= availableMem - usedMem + 1) - { - // grab the offset and size, store it, using the allocate memory function. - subFunctionSuccess = allocMemory(singlePCB, offset, size, singlePCB->memArraySize); - usedMem = usedMem + size; - } - else - { - // set the subfunction success to false. - subFunctionSuccess = false; - } - // if the function returns true, then it successfully did the operation, display as such. - if (memDisplay) - { - if(subFunctionSuccess) - { - // - printf("--------------------------------------------------\n"); - printf("After memory allocation\n"); - printf("%d [ Used, P#: %d, %d-%d ] %d\n", offset - offset, singlePCB->uniquePid, offset, - offset + size - 1, size - 1); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - else - { - // - printf("--------------------------------------------------\n"); - printf("After memory allocation failure\n"); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - } - break; - - case MEMORY_ACCESS: - // printf("Used memory at current: %d\n", usedMem); - subFunctionSuccess = accessMemory(singlePCB, offset, size); - if (memDisplay) - { - if (subFunctionSuccess) - { - // - printf("--------------------------------------------------\n"); - printf("After access success\n"); - printf("%d [ Used, P#: %d, %d-%d ] %d\n", offset - offset, singlePCB->uniquePid, offset, - offset + size - 1, size - 1); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - else - { - // - printf("--------------------------------------------------\n"); - printf("After access failure\n"); - printf("%d [ Used, P#: %d, %d-%d ] %d\n", offset - offset, singlePCB->uniquePid, offset, - offset + size - 1, size - 1); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - } - break; - - case MEMORY_DEALLOCATE: - subFunctionSuccess = deallocMemory(singlePCB, singlePCB->memArraySize); - if (memDisplay) - { - if (subFunctionSuccess) - { - // THIS SHOULD ALWAYS HAPPEN. - printf("--------------------------------------------------\n"); - printf("After clear process %d success\n", singlePCB->uniquePid); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem - usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - else - { - // THIS SHOULD NEVER HAPPEN. - printf("--------------------------------------------------\n"); - printf("After clear process %d failure\n", singlePCB->uniquePid); - printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem - usedMem, currentOffset, currentSize, availableMem - 1); - printf("--------------------------------------------------\n"); - } - } - break; - - case MEMORY_CLEAR: - if (memDisplay) - { - // this will happen regardless. Will always be cleaning up memory with dealloc. - printf("--------------------------------------------------\n"); - printf("After memory clear\n"); - printf("No memory configured\n"); - printf("--------------------------------------------------\n"); - } - break; - - default: - break; - } - // clear out the dynamic array - free(memorySizeArray); - // return if the subfunction succeeded, if applicable - return subFunctionSuccess; -} - -/* -Name: runCPU -Process: runs the CPU operations for however long it takes -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: pthreads, sprintf, logOutput, ??? -*/ -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 * 4]; - int cpuTime = 0; - int *cpuTimePtr = &cpuTime; - pthread_t cpuThread; - - 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; - } -} - -/* -Name: runIO -Process: runs the IO operations for however long it takes -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: pthreads, sprintf, logOutput, ??? -*/ -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 * 4]; - int ioTime = 0; - int *ioTimePtr = &ioTime; - pthread_t ioThread; - - 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; - } -} - -/* -Name: runProcess -Process: runs the process that was selected -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: accessTimer, compareString, runCPU, runIO, ??? -*/ -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 * 4]; - // grab the next operation code for the - OpCodeType *workingMeta = singlePCB->nextOpCode; - char *command; - char *argument; - int intArg; - int intArgTwo; - bool memManagerSuccess = true; - // char *inOutArg; - command = workingMeta->command; - argument = workingMeta->strArg1; - intArg = workingMeta->intArg2; - intArgTwo = workingMeta->intArg3; - // inOutArg = workingMeta->inOutArg; - while (!(compareString(command, "app") == EQUIV && compareString(argument, "end") == EQUIV) && - !(compareString(command, "sys") == EQUIV && compareString(argument, "end") == EQUIV) && - memManagerSuccess) - { - // check to see what operation will be performed - 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, - 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, - singlePCB, schedMethod); - } - if(compareString(command, "mem") == EQUIV) - { - // run memory operations with the memory manager - if(compareString(argument, "allocate") == EQUIV) - { - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(processOutput, "%f, Process: %d, %s %s request (%d, %d)\n", timeDigits, - singlePCB->uniquePid, command, argument, intArg, intArgTwo); - logOutput(configPtr, processOutput, false); - // run the memory manager in allocate mode - memManagerSuccess = memManager(pcbList, MEMORY_ALLOCATE, intArg, intArgTwo, configPtr, singlePCB); - if(!memManagerSuccess) - { - // - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(processOutput, "%f, Process: %d, failed %s %s request (%d, %d)\n", timeDigits, - singlePCB->uniquePid, command, argument, intArg, intArgTwo); - logOutput(configPtr, processOutput, false); - } - } - else if(compareString(argument, "access") == EQUIV) - { - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(processOutput, "%f, Process: %d, %s %s request (%d, %d)\n", timeDigits, - singlePCB->uniquePid, command, argument, intArg, intArgTwo); - logOutput(configPtr, processOutput, false); - // run the memory manager in access mode - memManagerSuccess = memManager(pcbList, MEMORY_ACCESS, intArg, intArgTwo, configPtr, singlePCB); - if (!memManagerSuccess) - { - // - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(processOutput, "%f, Process: %d, failed %s %s request (%d, %d)\n", timeDigits, - singlePCB->uniquePid, command, argument, intArg, intArgTwo); - logOutput(configPtr, processOutput, false); - } - } - } - workingMeta = workingMeta->nextNode; - command = workingMeta->command; - 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) - { - // - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(processOutput, "\n%f, OS: Process %d ended\n", timeDigits, singlePCB->uniquePid); - logOutput(configPtr, processOutput, false); - } - else - { - // - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(processOutput, "\n%f, OS: Segmentation Fault, Process %d ended\n", timeDigits, singlePCB->uniquePid); - logOutput(configPtr, processOutput, false); - } - // deallocate the memory for the process - memManager(pcbList, MEMORY_DEALLOCATE, intArg, intArgTwo, configPtr, singlePCB); -} - -/* -Name: runSim -Process: primary simulation driver -Function Input/Parameters: configuration data (ConfigDataType *), - metadata (OpCodeType *) -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: pthreads, accessTimer, sprintf, logOutput, runProcess, destroyProcessList, ??? -*/ -void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) -{ - // initialize function/variables - // 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 - int schedulingMethod = configPtr->cpuSchedCode; - char simulatorOutput[MAX_STR_LEN * 4]; - double timeDigits; - char timeStringy[MAX_STR_LEN]; - int processCount = 0; - int processIterator; - 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); - sprintf(simulatorOutput, "%f, OS: Simulator start\n", timeDigits); - logOutput(configPtr, simulatorOutput, false); - // int variable for process to run - int currentPid; - // create the process list with createProcessList, store the pointed to address - pcbList = createProcessList(); - // fill the process list given the metadata - pcbList = fillProcessList(configPtr, metaDataMstrPtr, pcbList); - pcbPtr = pcbList->headPtr; - - // calculate pcb total time, number of processes - int totalPCBTime = 0; - while(pcbPtr != NULL) - { - totalPCBTime = totalPCBTime + pcbPtr->timeLeft; - pcbPtr = pcbPtr->nextPtr; - processCount = processCount + 1; - } - pcbPtr = pcbList->headPtr; - int *totalPCBTimePtr = &totalPCBTime; - - - pthread_t cpuThread; - pthread_create(&cpuThread, NULL, runTimer, (void *)totalPCBTimePtr); - - // - int processTimeLeft = pcbPtr->timeLeft; - int *processTimeLeftPtr = &processTimeLeft; - - // set the current process id to the first scheduled process - currentPid = scheduleProcess(pcbList, configPtr); - - // initialize memory with the memManager - memManager(pcbList, MEMORY_INITIALIZE, memoryOffset, memorySize, configPtr, pcbList->headPtr); - - // loop until current process is hit - for(processIterator = 0; processIterator < processCount; processIterator++) - { - while (pcbPtr != NULL) - { - // printf("Current Process Number is: %d\n", pcbPtr->uniquePid); - // printf("Process Status is: %d\n", pcbPtr->process_state); - // printf("Scheduled Process is: %d\n", currentPid); - if (pcbPtr->process_state != PROCESS_STATE_TERMINATED && pcbPtr->uniquePid == currentPid) - { - // needs to set from READY to RUNNING - pcbPtr->process_state = PROCESS_STATE_RUNNING; - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(simulatorOutput, "%f, OS: Process %d set to RUNNING state from READY state\n\n", timeDigits, - pcbPtr->uniquePid); - logOutput(configPtr, simulatorOutput, false); - pthread_t runThread; - pthread_create(&runThread, NULL, runTimer, (void *)processTimeLeftPtr); - 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; - processTimeLeftPtr = &processTimeLeft; - pcbPtr = pcbPtr->nextPtr; - } - currentPid = scheduleProcess(pcbList, configPtr); - pcbPtr = pcbList->headPtr; - } - pthread_join(cpuThread, NULL); - // deallocate all the memory for each process. - memManager(pcbList, MEMORY_CLEAR, memoryOffset, memorySize, configPtr, pcbList->headPtr); - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(simulatorOutput, "%f, OS: System Stop\n", timeDigits); - logOutput(configPtr, simulatorOutput, false); - timeDigits = accessTimer(LAP_TIMER, timeStringy); - sprintf(simulatorOutput, "%f, OS: Simulation End\n", timeDigits); - logOutput(configPtr, simulatorOutput, true); - // deallocate the process list with destroyProcessList - destroyProcessList(pcbList); - // once complete, log the output to FILE if required - logOutput(configPtr, "", true); - // pthread_exit(NULL); // this line seems to make the program execution stop short... no warning either - // void function, no return. -} - -/* -Name: scheduleProcess -Process: takes in the scheduling data, and then returns which process is to be ran -Function Input/Parameters: head pointer of PCB List (ProcessControlBlockLL *), - configuration data (ConfigDataType *) -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: sprintf, logOutput, ??? -*/ -int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr) -{ - double timeDigits; - ProcessControlBlock *wkgPtr; - int returnPid = -1; - wkgPtr = headPointer->headPtr; - char loggingStr[MAX_STR_LEN]; - char timeStringy[MAX_STR_LEN]; - int processCount = 0; - - int shortestJob = 0; - int shortestJobProcNum = 0; - - while (wkgPtr != NULL) - { - if(wkgPtr->process_state != PROCESS_STATE_TERMINATED) - { - // - processCount = processCount + 1; - } - wkgPtr = wkgPtr->nextPtr; - } - wkgPtr = headPointer->headPtr; - - // switch case for each scheduling algorithm - switch (configPtr->cpuSchedCode) - { - case CPU_SCHED_FCFS_N_CODE: - // First Come, First Served, Non-preemptive Scheduling - // 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. - - // set every process in the list to READY from NEW - 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 terminated - if (wkgPtr->process_state != PROCESS_STATE_RUNNING && wkgPtr->process_state != PROCESS_STATE_TERMINATED) - { - //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_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 - // need to find shortest job, maybe using a find min function? - // reuse the previous code to set each process to READY from NEW - // will select the process that is in the READY state, with the shortest time. - - 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 - // now, ALSO needs to check which process takes the least time. - if (wkgPtr->process_state != PROCESS_STATE_RUNNING && wkgPtr->process_state != PROCESS_STATE_TERMINATED) - { - // 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; - 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 - return returnPid; -} \ No newline at end of file diff --git a/Sim04/simulator.h b/Sim04/simulator.h deleted file mode 100644 index b31aa41..0000000 --- a/Sim04/simulator.h +++ /dev/null @@ -1,232 +0,0 @@ -#ifndef SIMULATORX -#define SIMULATORX - -#include "StandardConstants.h" -#include "configops.h" -#include "metadataops.h" -#include "simtimer.h" -#include - -// data structures - -typedef enum{ - PROCESS_STATE_NEW = 0, - PROCESS_STATE_READY, - PROCESS_STATE_RUNNING, - PROCESS_STATE_BLOCKED, - PROCESS_STATE_TERMINATED - } PROCESS_STATES; - -typedef enum{ - MEMORY_INITIALIZE = 0, - MEMORY_ACCESS, - MEMORY_ALLOCATE, - MEMORY_CLEAR, - MEMORY_DEALLOCATE - } MEMORY_SIGNALS; - -typedef enum{ - IO_RETURN = 0, - QUANTUM_TIMEOUT, - CPU_SWITCH, - CLEAR_INTERRUPT - } INTERRUPT_ROUTINE; - -typedef struct ProcessControlBlockStruct -{ - int uniquePid; - PROCESS_STATES process_state; - // need a process start ptr for where the process starts. - // this will be a mini loop within the master loop that goes until it - // hits the app end command. - // it may hold the next opcode, since you don't need to traverse backward - OpCodeType *nextOpCode; - // have an IO cycle count here - int ioCycles; - // have a CPU cycle count here - int cpuCycles; - // maybe have a total cycle count here - int totalCycles; - // time left could be calculated from these. - // potentially could change the cycles or have a 'left' variable to - // see how many are left. - // also need a time left state here? - double timeLeft; - // allocated memory array (stores the offsets) - int *allocatedMemOffsets; - // allocated memory array sizes (stores the sizes for each offset) - int *allocatedMemSizes; - // size of memory array - int memArraySize; - // connect to the next process control block here - struct ProcessControlBlockStruct *nextPtr; -} ProcessControlBlock; - -typedef struct ProcessControlBlockLLStruct -{ - // holds the head ptr for PCBs - ProcessControlBlock *headPtr; -} ProcessControlBlockLL; - -/* -Name: ??? -Process: ??? -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ - -/* -Name: ??? -Process: ??? -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ - -/* -Name: addProcess -Process: allocates the memory for the pcb, grabs the data from the created PCB, - dumps the data so that the node can be linked correctly. -Function Input/Parameters: source PCB (ProcessControlBlock) -Function Output/Parameters: none -Function Output/Returned: filled PCB (ProcessControlBlock *) -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, sizeof, ??? -*/ -ProcessControlBlock *addProcess(const ProcessControlBlock source); - -/* -Name: createProcessList -Process: initializes head pointer to the PCBs -Function Input/Parameters: none -Function Output/Parameters: none -Function Output/Returned: head pointer to the PCBs -Device Input/Device: none -Device Output/Device: none -Dependencies: malloc, sizeof, ??? -*/ -ProcessControlBlockLL *createProcessList(); - -/* -Name: destroyProcessList -Process: deallocates memory used for the linked list struct -Function Input/Parameters: head pointer to linked list (ProcessControlBlockLL *) -Function Output/Parameters: none -Function Output/Returned: NULL -Device Input/Device: none -Device Output/Device: none -Dependencies: free, destroyProcessListHelper, ??? -*/ -ProcessControlBlockLL *destroyProcessList(ProcessControlBlockLL *linkedListPtr); - -/* -Name: destroyProcessListHelper -Process: recursively clears the PCB linked list struct, freeing the struct -Function Input/Parameters: head pointer to linked list (ProcessControlBlockLL *) -Function Output/Parameters: none -Function Output/Returned: NULL -Device Input/Device: none -Device Output/Device: none -Dependencies: free, destroyProcessListHelper(recursively), ??? -*/ -ProcessControlBlock *destroyProcessListHelper(ProcessControlBlock *nodePtr); - -/* -Name: fillProcessList -Process: iterates through the metadata LL, fills out each process as needed. -Function Input/Parameters: metadata (OpCodeType *), - headPointer (ProcessControlBlockLL *) -Function Output/Parameters: none -Function Output/Returned: pointer to filled PCB (ProcessControlBlockLL *) -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *metadataPtr, - ProcessControlBlockLL *headPointer); - -/* -Name: findMin -Process: compares two values, returns the smaller of the two. -Function Input/Parameters: two integer values (int) -Function Output/Parameters: none -Function Output/Returned: minimum of the two input integer values (int) -Device Input/Device: none -Device Output/Device: none -Dependencies: none -*/ -int findMin(int one, int another); - -/* -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); - -/* -Name: runCPU -Process: runs the CPU operations for however long it takes -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, - int processId, ProcessControlBlock *singlePCB, ConfigDataCodes schedMethod); - -/* -Name: runIO -Process: runs the IO operations for however long it takes -Function Input/Parameters: ??? -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, - int processId, ProcessControlBlock *singlePCB, ConfigDataCodes schedMethod); -/* -Name: runSim -Process: primary simulation driver -Function Input/Parameters: configuration data (ConfigDataType *), - metadata (OpCodeType *) -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr); - -/* -Name: scheduleProcess -Process: takes in the scheduling data, and then returns which process is to be ran -Function Input/Parameters: head pointer of PCB List (ProcessControlBlockLL *) -Function Output/Parameters: none -Function Output/Returned: none -Device Input/Device: none -Device Output/Device: none -Dependencies: ??? -*/ -int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr); - -#endif // SIMULATORX \ No newline at end of file diff --git a/Sim04/testfile-dnw.mdf b/Sim04/testfile-dnw.mdf deleted file mode 100644 index 6fdd099..0000000 --- a/Sim04/testfile-dnw.mdf +++ /dev/null @@ -1,86 +0,0 @@ -Start Program Meta-Data Code: - -# starting the master loop -sys start - -# process 0 start -app start, 0 -# process 0 I/O (run HDD for 18 cycles) -dev in, hard drive, 18 -# process 0 CPU (run CPU for 9 cycles 3 times) -cpu process, 9 -cpu process, 9 -cpu process, 9 -# process 0 I/O (run monitor for 60 cycles) -dev out, monitor, 60 -# process 0 end -app end - -# P0 total cycles ran: 105 - -# process 1 start -app start, 0 -# process 1 I/O (run sound for 40 cycles, HDD for 30 cycles, sound for 25 cycles) -dev in, sound signal, 40 -dev in, hard drive, 30 -dev in, sound signal, 25 -# process 1 CPU (run CPU for 6 cycles) -cpu process, 6 -# process 1 I/O (run USB for 10 cycles) -dev out, usb, 10 -# process 1 end -app end - -# P1 total cycles ran: 111 - -# process 2 start -app start, 0 -# process 2 I/O (run video for 70 cycles) -dev in, video signal, 70 -# process 2 CPU (run CPU for 10 cycles) -cpu process, 10 -# process 2 I/O (run monitor for 70 cycles, HDD for 18 cycles) -dev out, monitor, 70 -dev in, hard drive, 18 -# process 2 CPU (run CPU for 9 cycles) -cpu process, 9 -# process 2 end -app end - -# P2 total cycles ran: 177 - -# process 3 start -app start, 0 -# process 3 I/O (run sound for 35 cycles, monitor for 100 cycles, keyboard for 50 cycles) -dev in, sound signal, 35 -dev out, monitor, 100 -dev in, keyboard, 50 -# process 3 CPU (run CPU for 9 cycles) -cpu process, 9 -# process 3 I/O (run video for 49 cycles) -dev out, video signal, 49 -# process 3 end -app end - -# P3 total cycles ran: 243 - -# process 4 start -app start, 0 -# process 4 I/O (run keyboard for 90 cycles, sound for 40 cycles, serial for 32 cycles) -dev in, keyboard, 90 -dev out, sound signal, 40 -dev out, serial, 32 -# process 4 CPU (run CPU for 10 cycles) -cpu process, 10 -# process 4 I/O (run HDD for 15 cycles) -dev in, hard drive, 15 -# process 4 end -app end - -# P4 total cycles ran: 187 - -# master loop ends -sys end - -End Program Meta-Data Code. - diff --git a/Sim04/testfile.cnf b/Sim04/testfile.cnf deleted file mode 100644 index 77c71ed..0000000 --- a/Sim04/testfile.cnf +++ /dev/null @@ -1,12 +0,0 @@ -Start Simulator Configuration File: -Version/Phase : 1.00 -File Path : testfile.mdf -CPU Scheduling Code : FCFS-N -Quantum Time (cycles) : 55 -Memory Available (KB) : 12000 -Memory Display (On/Off) : On -Processor Cycle Time (msec) : 10 -I/O Cycle Time (msec) : 20 -Log To : Monitor -Log File Path : logfile_1.lgf -End Simulator Configuration File. \ No newline at end of file diff --git a/Sim04/testfile.mdf b/Sim04/testfile.mdf deleted file mode 100644 index b8da714..0000000 --- a/Sim04/testfile.mdf +++ /dev/null @@ -1,40 +0,0 @@ -Start Program Meta-Data Code: -sys start -app start, 0 -dev in, hard drive, 18 -cpu process, 9 -cpu process, 9 -cpu process, 9 -dev out, monitor, 60 -app end -app start, 0 -dev in, sound signal, 40 -dev in, hard drive, 30 -dev in, sound signal, 25 -cpu process, 6 -dev out, usb, 10 -app end -app start, 0 -dev in, video signal, 70 -cpu process, 10 -dev out, monitor, 70 -dev in, hard drive, 18 -cpu process, 9 -app end -app start, 0 -dev in, sound signal, 35 -dev out, monitor, 100 -dev in, keyboard, 50 -cpu process, 9 -dev out, video signal, 49 -app end -app start, 0 -dev in, keyboard, 90 -dev out, sound signal, 40 -dev out, serial, 32 -cpu process, 10 -dev in, hard drive, 15 -app end -sys end -End Program Meta-Data Code. -