Merge branch 'main' of https://git.cdezselfhosted.pw/cdez/CS480-Projects
This commit is contained in:
commit
37aa8c3b81
28 changed files with 5614 additions and 147 deletions
BIN
Sim03/Sim03_GradingForm_413499.xlsx
Normal file
BIN
Sim03/Sim03_GradingForm_413499.xlsx
Normal file
Binary file not shown.
|
|
@ -1,7 +1 @@
|
|||
0.000000, OS: Simulator start
|
||||
READY state from NEW state
|
||||
ate
|
||||
|
||||
ate
|
||||
|
||||
|
||||
0.000988, OS: Simulator start
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ OBJECTS = OS_SimDriver.o simulator.o metadataops.o configops.o StringUtils.o sim
|
|||
all: Simulator
|
||||
|
||||
Simulator: $(OBJECTS)
|
||||
$(CC) $(OBJECTS) -o sim03
|
||||
$(CC) $(OBJECTS) -lpthread -o sim03
|
||||
|
||||
StringUtils.o: StringUtils.c
|
||||
$(CC) -c StringUtils.c -o StringUtils.o
|
||||
|
|
|
|||
|
|
@ -30,11 +30,13 @@
|
|||
const char RADIX_POINT = '.';
|
||||
const char SPACED = ' ';
|
||||
|
||||
void runTimer( int milliSeconds )
|
||||
void *runTimer( void *mSecVoidPtr )
|
||||
{
|
||||
struct timeval startTime, endTime;
|
||||
int startSec, startUSec, endSec, endUSec;
|
||||
int uSecDiff, mSecDiff, secDiff, timeDiff;
|
||||
int *mSecPtr = (int *)mSecVoidPtr;
|
||||
int milliSeconds = *mSecPtr;
|
||||
|
||||
gettimeofday( &startTime, NULL );
|
||||
|
||||
|
|
@ -62,9 +64,44 @@ void runTimer( int milliSeconds )
|
|||
secDiff = ( endSec - startSec ) * 1000;
|
||||
timeDiff = secDiff + mSecDiff;
|
||||
}
|
||||
// return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// void runTimer(int milliSeconds)
|
||||
// {
|
||||
// struct timeval startTime, endTime;
|
||||
// int startSec, startUSec, endSec, endUSec;
|
||||
// int uSecDiff, mSecDiff, secDiff, timeDiff;
|
||||
|
||||
// gettimeofday(&startTime, NULL);
|
||||
|
||||
// startSec = startTime.tv_sec;
|
||||
// startUSec = startTime.tv_usec;
|
||||
|
||||
// timeDiff = 0;
|
||||
|
||||
// while (timeDiff < milliSeconds)
|
||||
// {
|
||||
// gettimeofday(&endTime, NULL);
|
||||
|
||||
// endSec = endTime.tv_sec;
|
||||
// endUSec = endTime.tv_usec;
|
||||
// uSecDiff = endUSec - startUSec;
|
||||
|
||||
// if (uSecDiff < 0)
|
||||
// {
|
||||
// uSecDiff = uSecDiff + 1000000;
|
||||
|
||||
// endSec = endSec - 1;
|
||||
// }
|
||||
|
||||
// mSecDiff = uSecDiff / 1000;
|
||||
// secDiff = (endSec - startSec) * 1000;
|
||||
// timeDiff = secDiff + mSecDiff;
|
||||
// }
|
||||
// // return NULL;
|
||||
// }
|
||||
|
||||
double accessTimer( int controlCode, char *timeStr )
|
||||
{
|
||||
static bool running = false;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ extern const char SPACED;
|
|||
|
||||
// Function Prototyp /////////////////////////////////////////////////////////
|
||||
|
||||
void runTimer( int milliSeconds );
|
||||
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
|
||||
|
|
|
|||
|
|
@ -2,17 +2,45 @@
|
|||
|
||||
/*
|
||||
Name: accessMemory
|
||||
Process: checks offset from the PCB
|
||||
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: none?
|
||||
Function Output/Returned: boolean to indicate success or failure of accessed memory
|
||||
Device Input/Device: none
|
||||
Device Output/Device: none
|
||||
Dependencies: ???
|
||||
*/
|
||||
void accessMemory(ProcessControlBlock *singlePCB, int offset, int size)
|
||||
bool accessMemory(ProcessControlBlock *singlePCB, int offset, int size)
|
||||
{
|
||||
// no return, void (temp)
|
||||
// return true (temp)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
// declare a pointer to working node
|
||||
logFile *workingNode;
|
||||
// make some space that the pointer is pointing to
|
||||
workingNode = malloc(sizeof(logFile));
|
||||
// make some space for the string data
|
||||
// workingNode->stringData = 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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -40,6 +68,9 @@ 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
|
||||
|
|
@ -51,14 +82,46 @@ 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?
|
||||
Function Output/Returned: boolean to indicate success or failure of allocated memory
|
||||
Device Input/Device: none
|
||||
Device Output/Device: none
|
||||
Dependencies: ???
|
||||
*/
|
||||
void allocMemory(ProcessControlBlock *singlePCB, int offset, int size)
|
||||
bool allocMemory(ProcessControlBlock *singlePCB, int offset, int size, int arraySize)
|
||||
{
|
||||
// no return, void (temp)
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -84,17 +147,46 @@ ProcessControlBlockLL *createProcessList()
|
|||
|
||||
/*
|
||||
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)
|
||||
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: none?
|
||||
Function Output/Returned: boolean to indicate success or failure of allocated memory
|
||||
Device Input/Device: none
|
||||
Device Output/Device: none
|
||||
Dependencies: ???
|
||||
*/
|
||||
void deallocMemory(ProcessControlBlock *singlePCB, int offset, int size)
|
||||
bool deallocMemory(ProcessControlBlock *singlePCB, int arraySize)
|
||||
{
|
||||
// no return, void (temp)
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -117,6 +209,30 @@ 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
|
||||
|
|
@ -132,6 +248,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);
|
||||
}
|
||||
|
|
@ -168,6 +286,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;
|
||||
|
|
@ -226,6 +346,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
|
||||
|
|
@ -234,6 +360,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;
|
||||
|
|
@ -305,48 +434,350 @@ Device Input/Device: none
|
|||
Device Output/Device: none
|
||||
Dependencies: fprintf, ???
|
||||
*/
|
||||
void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd)
|
||||
logFileLL *logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd, logFileLL *logPtr)
|
||||
{
|
||||
if(configPtr->logToCode == LOGTO_BOTH_CODE)
|
||||
logFile toLog;
|
||||
// toLog.stringData = malloc(sizeof(*logStr));
|
||||
logFile *wkgLogPtr;
|
||||
wkgLogPtr = logPtr->headPtr;
|
||||
if (configPtr->logToCode == LOGTO_BOTH_CODE)
|
||||
{
|
||||
//
|
||||
FILE *fileWritePtr;
|
||||
fileWritePtr = fopen(configPtr->logToFileName, "w+");
|
||||
if (fileWritePtr != NULL)
|
||||
// close the file, if at the end.
|
||||
if (isEnd)
|
||||
{
|
||||
fprintf(fileWritePtr, "%s", logStr);
|
||||
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);
|
||||
}
|
||||
// no return, void
|
||||
// close the file, if at the end.
|
||||
if (isEnd)
|
||||
{
|
||||
fclose(fileWritePtr);
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
fclose(fileWritePtr);
|
||||
}
|
||||
// fclose(fileWritePtr);
|
||||
// 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);
|
||||
// }
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -399,7 +830,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)
|
||||
void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId, logFileLL *logList)
|
||||
{
|
||||
char timeStringy[MAX_STR_LEN];
|
||||
// char *command = workingMeta->command;
|
||||
|
|
@ -407,15 +838,16 @@ 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);
|
||||
logOutput(configPtr, cpuOutput, false, logList);
|
||||
// run timer for intArg * procCycleRate
|
||||
pthread_t cpuThread;
|
||||
pthread_create(&cpuThread, NULL, (void *)&simThread, (void *)cpuTime);
|
||||
pthread_create(&cpuThread, NULL, runTimer, (void *)cpuTimePtr);
|
||||
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);
|
||||
logOutput(configPtr, cpuOutput, false, logList);
|
||||
// pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
|
@ -429,19 +861,20 @@ Device Input/Device: none
|
|||
Device Output/Device: none
|
||||
Dependencies: pthreads, sprintf, logOutput, ???
|
||||
*/
|
||||
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId)
|
||||
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId, logFileLL *logList)
|
||||
{
|
||||
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);
|
||||
logOutput(configPtr, ioOutput, false, logList);
|
||||
pthread_t ioThread;
|
||||
pthread_create(&ioThread, NULL, (void *)&simThread, (void *)ioTime);
|
||||
pthread_create(&ioThread, NULL, runTimer, (void *)ioTimePtr);
|
||||
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);
|
||||
logOutput(configPtr, ioOutput, false, logList);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -454,39 +887,89 @@ 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, logFileLL *logList)
|
||||
{
|
||||
// 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;
|
||||
char *inOutArg;
|
||||
int intArgTwo;
|
||||
bool memManagerSuccess = true;
|
||||
// char *inOutArg;
|
||||
command = workingMeta->command;
|
||||
argument = workingMeta->strArg1;
|
||||
intArg = workingMeta->intArg2;
|
||||
inOutArg = workingMeta->inOutArg;
|
||||
while (!(compareString(command, "app") == EQUIV && compareString(argument, "end") == EQUIV) && !(compareString(command, "sys") == EQUIV && compareString(argument, "end") == EQUIV))
|
||||
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);
|
||||
runCPU(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid, logList);
|
||||
}
|
||||
if(compareString(command, "dev") == EQUIV)
|
||||
{
|
||||
// run IO operations for the required amount of time.
|
||||
runIO(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -504,11 +987,12 @@ 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
|
||||
|
|
@ -516,13 +1000,17 @@ 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);
|
||||
|
||||
// int variable for process to run
|
||||
logOutput(configPtr, simulatorOutput, false, loggingList);
|
||||
// int variable for process to run
|
||||
int currentPid;
|
||||
// create the process list with createProcessList, store the pointed to address
|
||||
pcbList = createProcessList();
|
||||
|
|
@ -539,43 +1027,23 @@ void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
|
|||
processCount = processCount + 1;
|
||||
}
|
||||
pcbPtr = pcbList->headPtr;
|
||||
int *totalPCBTimePtr = &totalPCBTime;
|
||||
|
||||
|
||||
pthread_t cpuThread;
|
||||
pthread_create(&cpuThread, NULL, (void *)&simThread, (void *)totalPCBTime);
|
||||
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);
|
||||
currentPid = scheduleProcess(pcbList, configPtr, loggingList);
|
||||
|
||||
// initialize memory with the memManager
|
||||
memManager(pcbList, MEMORY_INITIALIZE, memoryOffset, memorySize, configPtr, pcbList->headPtr, loggingList);
|
||||
|
||||
// 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)
|
||||
|
|
@ -588,31 +1056,36 @@ 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);
|
||||
logOutput(configPtr, simulatorOutput, false, loggingList);
|
||||
pthread_t runThread;
|
||||
pthread_create(&runThread, NULL, (void *)&simThread, (void *)processTimeLeft);
|
||||
runProcess(pcbPtr, configPtr);
|
||||
pthread_create(&runThread, NULL, runTimer, (void *)processTimeLeftPtr);
|
||||
runProcess(pcbPtr, configPtr, pcbList, loggingList);
|
||||
// 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);
|
||||
logOutput(configPtr, simulatorOutput, false, loggingList);
|
||||
pcbPtr->process_state = PROCESS_STATE_TERMINATED;
|
||||
pthread_join(runThread, NULL);
|
||||
}
|
||||
processTimeLeft = pcbPtr->timeLeft;
|
||||
processTimeLeftPtr = &processTimeLeft;
|
||||
pcbPtr = pcbPtr->nextPtr;
|
||||
}
|
||||
currentPid = scheduleProcess(pcbList, configPtr);
|
||||
currentPid = scheduleProcess(pcbList, configPtr, loggingList);
|
||||
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);
|
||||
logOutput(configPtr, simulatorOutput, false, loggingList);
|
||||
sprintf(simulatorOutput, "%f, OS: Simulation End\n", accessTimer(LAP_TIMER, timeStringy));
|
||||
logOutput(configPtr, simulatorOutput, true);
|
||||
logOutput(configPtr, simulatorOutput, true, loggingList);
|
||||
// deallocate the process list with destroyProcessList
|
||||
destroyProcessList(pcbList);
|
||||
// once complete, log the output to FILE if required
|
||||
logOutput(configPtr, "", true);
|
||||
// logOutput(configPtr, "", true, loggingList);
|
||||
// deallocate the file log list with destroyFileLogList
|
||||
destroyFileLogList(loggingList);
|
||||
// pthread_exit(NULL); // this line seems to make the program execution stop short... no warning either
|
||||
// void function, no return.
|
||||
}
|
||||
|
|
@ -628,7 +1101,7 @@ Device Input/Device: none
|
|||
Device Output/Device: none
|
||||
Dependencies: sprintf, logOutput, ???
|
||||
*/
|
||||
int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr)
|
||||
int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr, logFileLL *logList)
|
||||
{
|
||||
ProcessControlBlock *wkgPtr;
|
||||
int returnPid = -1;
|
||||
|
|
@ -637,6 +1110,9 @@ 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)
|
||||
|
|
@ -667,7 +1143,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);
|
||||
logOutput(configPtr, loggingStr, false, logList);
|
||||
}
|
||||
// move to the next pointer
|
||||
wkgPtr = wkgPtr->nextPtr;
|
||||
|
|
@ -682,7 +1158,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);
|
||||
logOutput(configPtr, loggingStr, false, logList);
|
||||
returnPid = wkgPtr->uniquePid;
|
||||
}
|
||||
// move to next pointer
|
||||
|
|
@ -700,8 +1176,7 @@ 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)
|
||||
{
|
||||
//
|
||||
|
|
@ -711,7 +1186,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);
|
||||
logOutput(configPtr, loggingStr, false, logList);
|
||||
}
|
||||
// move to the next pointer
|
||||
wkgPtr = wkgPtr->nextPtr;
|
||||
|
|
@ -762,7 +1237,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);
|
||||
logOutput(configPtr, loggingStr, false, logList);
|
||||
}
|
||||
returnPid = shortestJobProcNum;
|
||||
break;
|
||||
|
|
@ -784,8 +1259,8 @@ Device Input/Device: none
|
|||
Device Output/Device: none
|
||||
Dependencies: pthreads, runTimer
|
||||
*/
|
||||
void *simThread(int milSec)
|
||||
{
|
||||
runTimer(milSec);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
// void *simThread(int milSec)
|
||||
// {
|
||||
// runTimer(milSec);
|
||||
// pthread_exit(NULL);
|
||||
// }
|
||||
|
|
@ -21,9 +21,23 @@ 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;
|
||||
|
|
@ -48,6 +62,8 @@ 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;
|
||||
|
|
@ -80,6 +96,31 @@ 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,
|
||||
|
|
@ -93,9 +134,33 @@ 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: initializes head pointer to the PCBs
|
||||
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
|
||||
|
|
@ -105,6 +170,30 @@ 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
|
||||
|
|
@ -117,6 +206,18 @@ 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
|
||||
|
|
@ -157,16 +258,31 @@ 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: sprintf, ???
|
||||
Dependencies: fprintf, ???
|
||||
*/
|
||||
void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd);
|
||||
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);
|
||||
|
||||
/*
|
||||
Name: runCPU
|
||||
|
|
@ -176,9 +292,9 @@ Function Output/Parameters: none
|
|||
Function Output/Returned: none
|
||||
Device Input/Device: none
|
||||
Device Output/Device: none
|
||||
Dependencies: ???
|
||||
Dependencies: pthreads, sprintf, logOutput, ???
|
||||
*/
|
||||
void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId);
|
||||
void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId, logFileLL *logList);
|
||||
|
||||
/*
|
||||
Name: runIO
|
||||
|
|
@ -188,44 +304,46 @@ Function Output/Parameters: none
|
|||
Function Output/Returned: none
|
||||
Device Input/Device: none
|
||||
Device Output/Device: none
|
||||
Dependencies: ???
|
||||
Dependencies: pthreads, sprintf, logOutput, ???
|
||||
*/
|
||||
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId);
|
||||
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId, logFileLL *logList);
|
||||
|
||||
/*
|
||||
Name: runSim
|
||||
Process: primary simulation driver
|
||||
Function Input/Parameters: configuration data (ConfigDataType *),
|
||||
metadata (OpCodeType *)
|
||||
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: ???
|
||||
Dependencies: accessTimer, compareString, runCPU, runIO, ???
|
||||
*/
|
||||
void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr, ProcessControlBlockLL *pcbList, logFileLL *logList);
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
/*
|
||||
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 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: ???
|
||||
Dependencies: sprintf, logOutput, ???
|
||||
*/
|
||||
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);
|
||||
int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr, logFileLL *logList);
|
||||
|
||||
#endif // SIMULATORX
|
||||
Loading…
Add table
Add a link
Reference in a new issue