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

Binary file not shown.

View file

@ -1,5 +1,20 @@
#include "simulator.h" #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 Name: addProcess
Process: allocates the memory for the pcb, grabs the data from the created PCB, 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->process_state = source.process_state;
workingNode->timeLeft = source.timeLeft; workingNode->timeLeft = source.timeLeft;
workingNode->totalCycles = source.totalCycles; 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! // make sure to set the next pointer to NULL!
workingNode->nextPtr = NULL; workingNode->nextPtr = NULL;
// return workingNode // return workingNode
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 Name: createProcessList
Process: reads through the opcode struct to fill out the linked list of PCBs Process: reads through the opcode struct to fill out the linked list of PCBs
@ -52,6 +85,21 @@ ProcessControlBlockLL *createProcessList()
return headBlock; 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 Name: destroyProcessList
Process: deallocates memory used for the linked list struct 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 // check to see if the pointer is NOT null
if(nodePtr != NULL) if(nodePtr != NULL)
{ {
free(nodePtr->allocatedMemOffsets);
free(nodePtr->allocatedMemSizes);
// if not null, move to the next pointer (recurse) // if not null, move to the next pointer (recurse)
nodePtr->nextPtr = destroyProcessListHelper(nodePtr->nextPtr); nodePtr->nextPtr = destroyProcessListHelper(nodePtr->nextPtr);
} }
@ -123,6 +173,8 @@ ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *me
double timeLeftCount = 0.0; double timeLeftCount = 0.0;
// need a variable that fills PIDs, starting at 0 // need a variable that fills PIDs, starting at 0
int processId = 0; int processId = 0;
// need a variable that checks how many allocate statements there are.
int memAllocation = 0;
// process variables? // process variables?
char *command; char *command;
char *argument; char *argument;
@ -181,6 +233,12 @@ ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *me
cpuCycleCount = cpuCycleCount + integerArgumentOne; 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)) if ((compareString(argument, "end") == EQUIV && compareString(command, "app") == EQUIV))
{ {
// set the ioCycles from variable // set the ioCycles from variable
@ -189,6 +247,9 @@ ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *me
currentPCB.cpuCycles = cpuCycleCount; currentPCB.cpuCycles = cpuCycleCount;
// set totalCycles from adding both IO/CPU // set totalCycles from adding both IO/CPU
currentPCB.totalCycles = ioCycleCount + cpuCycleCount; 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 // currentPCB must have the starting instruction from wkgInsPtr
wkgInsPtr = wkgMetaPtr; 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 Name: runCPU
Process: runs the CPU operations for however long it takes Process: runs the CPU operations for however long it takes
@ -369,7 +521,7 @@ Device Input/Device: none
Device Output/Device: none Device Output/Device: none
Dependencies: accessTimer, compareString, runCPU, runIO, ??? 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 // run over the entire process, running the CPU when a CPU cycle comes up
// or a run IO when an IO 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]; char timeStringy[MAX_STR_LEN];
int processCount = 0; int processCount = 0;
int processIterator; int processIterator;
int memoryOffset = 0;
int memorySize = 1;
accessTimer(ZERO_TIMER, timeStringy); accessTimer(ZERO_TIMER, timeStringy);
// Operating System start timer goes here, log it. // Operating System start timer goes here, log it.
@ -455,6 +609,7 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
} }
pcbPtr = pcbList->headPtr; pcbPtr = pcbList->headPtr;
pthread_t cpuThread; pthread_t cpuThread;
pthread_create(&cpuThread, NULL, (void *)&simThread, (void *)totalPCBTime); 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 // set the current process id to the first scheduled process
currentPid = scheduleProcess(pcbList, configPtr); currentPid = scheduleProcess(pcbList, configPtr);
// initialize memory with the memManager
memManager(pcbList, MEMORY_INITIALIZE, memoryOffset, memorySize, configPtr);
// loop until current process is hit // 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++) for(processIterator = 0; processIterator < processCount; processIterator++)
{ {
while (pcbPtr != NULL) while (pcbPtr != NULL)
@ -506,7 +638,7 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
logOutput(configPtr, simulatorOutput, false); logOutput(configPtr, simulatorOutput, false);
pthread_t runThread; pthread_t runThread;
pthread_create(&runThread, NULL, (void *)&simThread, (void *)processTimeLeft); pthread_create(&runThread, NULL, (void *)&simThread, (void *)processTimeLeft);
runProcess(pcbPtr, configPtr); runProcess(pcbPtr, configPtr, pcbList);
// when finished, set to terminated // 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); 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); logOutput(configPtr, simulatorOutput, false);

View file

@ -17,6 +17,13 @@ typedef enum{
PROCESS_STATE_TERMINATED PROCESS_STATE_TERMINATED
} PROCESS_STATES; } PROCESS_STATES;
typedef enum{
MEMORY_INITIALIZE = 0,
MEMORY_ACCESS,
MEMORY_ALLOCATE,
MEMORY_DEALLOCATE
} MEMORY_SIGNALS;
typedef struct ProcessControlBlockStruct typedef struct ProcessControlBlockStruct
{ {
int uniquePid; int uniquePid;
@ -37,6 +44,12 @@ typedef struct ProcessControlBlockStruct
// see how many are left. // see how many are left.
// also need a time left state here? // also need a time left state here?
double timeLeft; 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 // connect to the next process control block here
struct ProcessControlBlockStruct *nextPtr; struct ProcessControlBlockStruct *nextPtr;
} ProcessControlBlock; } ProcessControlBlock;