Savepoint for memory operations.

This commit is contained in:
Charles Descamps 2024-03-18 15:55:32 -07:00
parent ee95d19bfe
commit 67df0ceeaf
3 changed files with 174 additions and 29 deletions

View file

@ -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);