diff --git a/Sim03/sim03 b/Sim03/sim03 index 6b254d6..b4cb1a2 100755 Binary files a/Sim03/sim03 and b/Sim03/sim03 differ diff --git a/Sim03/simulator.c b/Sim03/simulator.c index f5acfb5..df0ef2a 100644 --- a/Sim03/simulator.c +++ b/Sim03/simulator.c @@ -1,5 +1,20 @@ #include "simulator.h" +/* +Name: accessMemory +Process: checks offset from the PCB +Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int) +Function Output/Parameters: none +Function Output/Returned: none? +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void accessMemory(ProcessControlBlock *singlePCB, int offset, int size) +{ + // no return, void (temp) +} + /* Name: addProcess Process: allocates the memory for the pcb, grabs the data from the created PCB, @@ -25,12 +40,30 @@ 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 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: none? +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void allocMemory(ProcessControlBlock *singlePCB, int offset, int size) +{ + // no return, void (temp) +} + /* Name: createProcessList Process: reads through the opcode struct to fill out the linked list of PCBs @@ -52,6 +85,21 @@ ProcessControlBlockLL *createProcessList() return headBlock; } +/* +Name: deallocMemory +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: none? +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void deallocMemory(ProcessControlBlock *singlePCB, int offset, int size) +{ + // no return, void (temp) +} + /* Name: destroyProcessList Process: deallocates memory used for the linked list struct @@ -87,6 +135,8 @@ 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); } @@ -123,6 +173,8 @@ 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; @@ -181,6 +233,12 @@ 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 @@ -189,6 +247,9 @@ 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; @@ -304,6 +365,97 @@ void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd) } } +/* +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: none? +Device Input/Device: none +Device Output/Device: none +Dependencies: ??? +*/ +void memManager(ProcessControlBlockLL *pcbList, MEMORY_SIGNALS memCode, int offset, int size, ConfigDataType *configPtr) +{ + bool memDisplay = configPtr->memDisplay; + ProcessControlBlock *wkgPtr; + int availableMem = configPtr->memAvailable; + int usedMem = 0; + int currentOffset = 0; + int currentSize = 0; + int memIterator; + wkgPtr = pcbList->headPtr; + + while(wkgPtr != NULL) + { + // count up the total used memory within each process control block. + for(memIterator = 0; memIterator < wkgPtr->memArraySize; memIterator++) + { + // grab how much memory is used by that process + usedMem = usedMem + wkgPtr->allocatedMemSizes[memIterator]; + } + // move to the next pointer + wkgPtr = wkgPtr->nextPtr; + } + + // switch case for each memory code + switch (memCode) + { + case MEMORY_INITIALIZE: + 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: + if (memDisplay) + { + // + printf("--------------------------------------------------\n"); + printf("After memory allocation\n"); + printf("%d [ Used, P%d: x, %d-%d ] %d\n", usedMem, wkgPtr->uniquePid, offset, size, availableMem - 1); + printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); + printf("--------------------------------------------------\n"); + } + break; + + case MEMORY_ACCESS: + if (memDisplay) + { + // + printf("--------------------------------------------------\n"); + printf("After access success/failure\n"); + printf("%d [ Used, P%d: x, %d-%d ] %d\n", usedMem, wkgPtr->uniquePid, offset, size, availableMem - 1); + printf("%d [ Open, P#: x, %d-%d ] %d\n", usedMem, currentOffset, currentSize, availableMem - 1); + printf("--------------------------------------------------\n"); + } + break; + + case MEMORY_DEALLOCATE: + if (memDisplay) + { + // + printf("--------------------------------------------------\n"); + printf("After memory clear\n"); + printf("No memory configured"); + printf("--------------------------------------------------\n"); + } + break; + + default: + break; + } + // no return, void (temp) +} + /* Name: runCPU Process: runs the CPU operations for however long it takes @@ -369,7 +521,7 @@ Device Input/Device: none Device Output/Device: none Dependencies: accessTimer, compareString, runCPU, runIO, ??? */ -void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr) +void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr, ProcessControlBlockLL *pcbList) { // run over the entire process, running the CPU when a CPU cycle comes up // or a run IO when an IO cycle comes up @@ -431,6 +583,8 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) char timeStringy[MAX_STR_LEN]; int processCount = 0; int processIterator; + int memoryOffset = 0; + int memorySize = 1; accessTimer(ZERO_TIMER, timeStringy); // Operating System start timer goes here, log it. @@ -455,6 +609,7 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) } pcbPtr = pcbList->headPtr; + pthread_t cpuThread; pthread_create(&cpuThread, NULL, (void *)&simThread, (void *)totalPCBTime); @@ -463,34 +618,11 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) // 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); + // 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) @@ -506,7 +638,7 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr) logOutput(configPtr, simulatorOutput, false); pthread_t runThread; pthread_create(&runThread, NULL, (void *)&simThread, (void *)processTimeLeft); - runProcess(pcbPtr, configPtr); + runProcess(pcbPtr, configPtr, pcbList); // 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); diff --git a/Sim03/simulator.h b/Sim03/simulator.h index 4ccba46..f75f791 100644 --- a/Sim03/simulator.h +++ b/Sim03/simulator.h @@ -17,6 +17,13 @@ typedef enum{ PROCESS_STATE_TERMINATED } PROCESS_STATES; +typedef enum{ + MEMORY_INITIALIZE = 0, + MEMORY_ACCESS, + MEMORY_ALLOCATE, + MEMORY_DEALLOCATE + } MEMORY_SIGNALS; + typedef struct ProcessControlBlockStruct { int uniquePid; @@ -37,6 +44,12 @@ typedef struct ProcessControlBlockStruct // 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;