CS480-Projects/Sim02/simulator.c
2024-02-20 11:47:12 -07:00

255 lines
No EOL
9.6 KiB
C

#include "configops.h"
#include "metadataops.h"
#include "StandardConstants.h"
#include "simulator.h"
/*
Name: addProcess
Process: adds a process to the
Function Input/Parameters: none
Function Output/Parameters: none
Function Output/Returned: head pointer to the PCBs
Device Input/Device: none
Device Output/Device: none
Dependencies: malloc, sizeof, fillProcessList
*/
// ProcessControlBlock *addProcess()
// {
// // return NULL (temp)
// return NULL;
// }
/*
Name: createProcessList
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
Device Input/Device: none
Device Output/Device: none
Dependencies: malloc, sizeof, ???
*/
ProcessControlBlockLL *createProcessList()
{
// allocate and create the ProcessControlBlockLL using malloc and size of
ProcessControlBlockLL *headBlock;
headBlock = malloc(sizeof(ProcessControlBlockLL));
// set the head pointer to NULL
headBlock->headPtr = NULL;
// return headBlock
return headBlock;
}
/*
Name: destroyProcessList
Process: deallocates memory used for the linked list struct
Function Input/Parameters: head pointer to linked list (ProcessControlBlockLL *)
Function Output/Parameters: none
Function Output/Returned: NULL
Device Input/Device: none
Device Output/Device: none
Dependencies: free, destroyProcessListHelper, ???
*/
ProcessControlBlockLL *destroyProcessList(ProcessControlBlockLL *linkedListPtr)
{
// call the first destroyProcessListHelper
destroyProcessListHelper(linkedListPtr->headPtr);
// free the rest of the struct
free(linkedListPtr);
// return null
return NULL;
}
/*
Name: destroyProcessListHelper
Process: recursively clears the PCB linked list struct, freeing the struct
Function Input/Parameters: head pointer to linked list (ProcessControlBlockLL *)
Function Output/Parameters: none
Function Output/Returned: NULL
Device Input/Device: none
Device Output/Device: none
Dependencies: free, destroyProcessListHelper(recursively), ???
*/
ProcessControlBlock *destroyProcessListHelper(ProcessControlBlock *nodePtr)
{
// check to see if the pointer is NOT null
if(nodePtr != NULL)
{
// if not null, move to the next pointer (recurse)
nodePtr->nextPtr = destroyProcessListHelper(nodePtr->nextPtr);
}
// free the 'parent' node
free(nodePtr);
// return null
return NULL;
}
/*
Name: fillProcessList
Process: iterates through the metadata LL, fills out each process as needed.
(Linking is left to the calling function, returns a pointer to the filled struct)
Function Input/Parameters: metadata (OpCodeType *)
Function Output/Parameters: none
Function Output/Returned: pointer to filled PCB (ProcessControlBlock *)
Device Input/Device: none
Device Output/Device: none
Dependencies: ???
*/
ProcessControlBlock *fillProcessList(OpCodeType *metadataPtr)
{
// initialize function/variables
// need a working pointer for the metadata
OpCodeType *wkgMetaPtr;
OpCodeType *wkgInternalPtr;
ProcessControlBlock currentPCB;
// need a pointer to save the location of first metadata opcode
OpCodeType metaAddress;
// need a variable to count how many IO cycles are in the process
int ioCycleCount;
// need a variable to count how many CPU cycles are in the process
int cpuCycleCount;
// need a variable to calculate the time left in ms for a process
int timeLeftCount;
// need a variable that fills PIDs, starting at 0
int processId = 0;
// process variables?
char *command;
char *commandInt;
char *argument;
char *argumentInt;
// set the working pointer to the first part of the metadata pointer
wkgMetaPtr = metadataPtr;
//
// grab the first command and argument
command = wkgMetaPtr->command;
argument = wkgMetaPtr->strArg1;
// loop through the process list, until you hit a sys end.
while(wkgMetaPtr->nextNode != NULL || (compareString(argument, "end") && compareString(command, "sys")))
{
// if app start,
if (compareString(command, "app") && compareString(argument, "start"))
{
// set the unique ID for both PCB and Metadata
wkgMetaPtr->pid = processId;
currentPCB.uniquePid = processId;
// set the process state to PROCESS_STATE_NEW
currentPCB.process_state = PROCESS_STATE_NEW;
// set the nextOpCode as a pointer to the first place metadataPtr started
currentPCB.nextOpCode = wkgMetaPtr;
// set the internal pointer to the location that wkgPtr is at
wkgInternalPtr = wkgMetaPtr;
// set the internal command and argument
commandInt = wkgInternalPtr->command;
argumentInt = wkgInternalPtr->strArg1;
// loop while no longer have io or cpu instructions? (aka not at app end?)
while(wkgInternalPtr->nextNode != NULL || (compareString(argumentInt, "end") && compareString(commandInt, "app")))
{
printf("%s command, %s argument:\n", commandInt, argumentInt);
// count number of io cycles
if((compareString(argumentInt, "in") || compareString(commandInt, "dev")))
{
//
printf("IO CYCLE %s\n", argumentInt);
}
else if((compareString(argumentInt, "out") || compareString(commandInt, "dev")))
{
//
printf("IO CYCLE %s\n", argumentInt);
}
// count number of cpu cycles
// if((compareString(argumentInt, "process") || compareString(commandInt, "cpu")))
// {
// //
// printf("CPU CYCLE\n");
// }
// move to next node, set relevant args
wkgInternalPtr = wkgInternalPtr->nextNode;
commandInt = wkgInternalPtr->command;
argumentInt = wkgInternalPtr->strArg1;
}
// set the ioCycles from variable
// set the cpuCycles from variable
// set totalCycles from adding both IO/CPU
// set the time left from (ioCycles * ioCycleRate) + (cpuCycles * procCyclesRate)
// this gets the number of ms in the process.
// increment the PID counter
processId = processId + 1;
}
wkgMetaPtr = wkgMetaPtr->nextNode;
command = wkgMetaPtr->command;
argument = wkgMetaPtr->strArg1;
}
// return null (temp)
return (ProcessControlBlock *)NULL;
}
/*
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: ???
*/
void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
{
// initialize function/variables
// need a FILE * for file operations
FILE *fileWritePtr;
// need two working pointers, one for master loop, one for internal loop
OpCodeType *wkgPtrMaster;
// currentTime variable that stores the time. [now unsure if needed]
// need a variable for headPointer to point
ProcessControlBlockLL *pcbList;
// string variable for nextCode
char *nextCode;
// create the process list with createProcessList, store the pointed to address
pcbList = createProcessList();
// fill the process list given the metadata
pcbList->headPtr = fillProcessList(metaDataMstrPtr);
// create temp strings
char *command;
char *argument;
// get the first data out of the metadata
command = metaDataMstrPtr->command;
argument = metaDataMstrPtr->strArg1;
// set the master working pointer to the first metadata block
wkgPtrMaster = metaDataMstrPtr;
// function holds master loop, loops until sys end opcode found OR wkgPtrMaster nextNode != NULL
while( wkgPtrMaster->nextNode != NULL || (compareString(argument, "end") && compareString(command, "sys")))
{
// will have a loop that goes from app start to app end for a PCB
// (checks to see if the next instruction is NOT app end), using getNextProcess?
// this will getNextOpCode
// this will checkForIO and run the IO operations, outputting to FILE * and/or monitor
// checkForIO will need the FILE * passed, will need timer access, and ???
// this will checkForCPU and run the CPU operations, outputting to FILE * and/or monitor
// checkForCPU will need the FILE * passed, will need timer access, and ???
// move the wkgPtrMaster to the next metadata block
wkgPtrMaster = wkgPtrMaster->nextNode;
// set the command and argument to the current cmd and arg
command = wkgPtrMaster->command;
argument = wkgPtrMaster->strArg1;
}
//
// deallocate the process list with destroyProcessList
destroyProcessList(pcbList);
//printf("runSim called here");
// void function, no return.
}
// getNextProcess/scheduler/dispatcher run here, loads/"runs" the process
// getNextOpCode, not needed for Sim02 apparently, keep in mind.
// checkForIO, I think this gets passed the current process and runs the IO ops
// checkForCPU, I think this gets passed the current process and runs the CPU ops
// checkForMemory, I think this gets passed the current process
// and runs mem ops (not needed for Sim02)
// cpuIdler (not needed for Sim02)