Savepoint for memory operations.
This commit is contained in:
parent
ee95d19bfe
commit
67df0ceeaf
3 changed files with 174 additions and 29 deletions
BIN
Sim03/sim03
BIN
Sim03/sim03
Binary file not shown.
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue