Resetting the Simulator 3 and 4 Projects here... Git repository got really bad...
This commit is contained in:
parent
d98c664002
commit
46bd58931f
21 changed files with 0 additions and 4310 deletions
|
|
@ -1,246 +0,0 @@
|
||||||
// header files
|
|
||||||
#include "OS_SimDriver.h"
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
// initialize program (variables and title)
|
|
||||||
ConfigDataType *configDataPtr = NULL;
|
|
||||||
OpCodeType *metaDataPtr = NULL;
|
|
||||||
char errorMsg[MAX_STR_LEN];
|
|
||||||
CmdLineData cmdLineData;
|
|
||||||
bool configUploadSuccess = false;
|
|
||||||
|
|
||||||
// show title
|
|
||||||
// fct: printf
|
|
||||||
printf("\nSimulator Program\n");
|
|
||||||
printf("=================\n\n");
|
|
||||||
|
|
||||||
// process command line arguments
|
|
||||||
// check for at least one correct switch and config file name verified
|
|
||||||
// fct: processCmdLine
|
|
||||||
if(processCmdLine(argc, argv, &cmdLineData))
|
|
||||||
{
|
|
||||||
// upload config file, check for success
|
|
||||||
// fct: getConfigData
|
|
||||||
if(getConfigData(cmdLineData.fileName, &configDataPtr, errorMsg))
|
|
||||||
{
|
|
||||||
// check for config display flag
|
|
||||||
if(cmdLineData.configDisplayFlag)
|
|
||||||
{
|
|
||||||
// display config display flag
|
|
||||||
// fct: displayConfigData
|
|
||||||
displayConfigData(configDataPtr);
|
|
||||||
}
|
|
||||||
// set config upload success flag
|
|
||||||
configUploadSuccess = true;
|
|
||||||
}
|
|
||||||
// otherwise, assume config file upload failure
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// show error message, end program
|
|
||||||
// fct: printf
|
|
||||||
printf("\nConfig Upload Error: %s, program aborted\n\n", errorMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for config success and need for metadata
|
|
||||||
if(configUploadSuccess &&
|
|
||||||
(cmdLineData.mdDisplayFlag || cmdLineData.runSimFlag))
|
|
||||||
{
|
|
||||||
// upload metadata file, check for success
|
|
||||||
// fct: getMetaData
|
|
||||||
if(getMetaData(configDataPtr->metaDataFileName,
|
|
||||||
&metaDataPtr, errorMsg))
|
|
||||||
{
|
|
||||||
// check metadata display flag
|
|
||||||
if(cmdLineData.mdDisplayFlag)
|
|
||||||
{
|
|
||||||
// display metadata
|
|
||||||
// fct: displayMetaData
|
|
||||||
displayMetaData(metaDataPtr);
|
|
||||||
}
|
|
||||||
// check run simulator flag
|
|
||||||
if(cmdLineData.runSimFlag)
|
|
||||||
{
|
|
||||||
// run simulator
|
|
||||||
// fct: runSim
|
|
||||||
runSim(configDataPtr, metaDataPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// otherwise, assume metadata upload failure
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// show error message, end program
|
|
||||||
// fct: printf
|
|
||||||
printf("\nMetadata Upload Error: %s, program aborted\n",
|
|
||||||
errorMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// end check for config success and need for metadata
|
|
||||||
|
|
||||||
// clean up config data as needed
|
|
||||||
// fct: clearConfigData
|
|
||||||
configDataPtr = clearConfigData(configDataPtr);
|
|
||||||
|
|
||||||
// clean up metadata as needed
|
|
||||||
// fct: clearMetaDataList
|
|
||||||
metaDataPtr = clearMetaDataList(metaDataPtr);
|
|
||||||
}
|
|
||||||
// end process command line arguments
|
|
||||||
|
|
||||||
// otherwise, assume command line failure
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// show command line argument requirements
|
|
||||||
// fct: showCommandLineFormat
|
|
||||||
showCommandLineFormat();
|
|
||||||
}
|
|
||||||
// show program end
|
|
||||||
// fct: printf
|
|
||||||
printf("\nSimulator Program End.\n");
|
|
||||||
|
|
||||||
// return program success
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: clearCmdLineStruct
|
|
||||||
Process: sets command line structure data to defaults
|
|
||||||
Booleans to false, fileName to empty string
|
|
||||||
Function Input/Parameters: pointer to command line structure (CmdLineData *)
|
|
||||||
Function Output/Parameters: pointer to command line structure (CmdLineData *)
|
|
||||||
with updated members
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
void clearCmdLineStruct(CmdLineData *clDataPtr)
|
|
||||||
{
|
|
||||||
// set all struct members to default
|
|
||||||
clDataPtr->programRunFlag = false;
|
|
||||||
clDataPtr->configDisplayFlag = false;
|
|
||||||
clDataPtr->mdDisplayFlag = false;
|
|
||||||
clDataPtr->runSimFlag = false;
|
|
||||||
clDataPtr->fileName[0] = NULL_CHAR;
|
|
||||||
// void function, no return.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: processCmdLine
|
|
||||||
Process: checks for at least two arguments,
|
|
||||||
then sets Booleans depending on command line switches
|
|
||||||
which can be in any order,
|
|
||||||
also captures config file name which must be last arugment
|
|
||||||
Function Input/Parameters: number of arguments (int),
|
|
||||||
vector of arguments (char **)
|
|
||||||
Function Output/Parameters: pointer to command line structure (CmdLineData *)
|
|
||||||
with updated members,
|
|
||||||
set to default values if failure
|
|
||||||
to capture arguments
|
|
||||||
Function Output/Returned: Boolean result of argument capture
|
|
||||||
true if at least one switch and config file name,
|
|
||||||
false otherwise
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
bool processCmdLine(int numArgs, char **strVector, CmdLineData *clDataPtr)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
|
|
||||||
// initialize structure to defaults
|
|
||||||
// fct: clearCmdLineStruct
|
|
||||||
clearCmdLineStruct(clDataPtr);
|
|
||||||
// initialize success flags to false
|
|
||||||
bool atLeastOneSwitchFlag = false;
|
|
||||||
bool correctConfigFileFlag = false;
|
|
||||||
// initialize first arg index to one
|
|
||||||
int argIndex = 1;
|
|
||||||
// iniitialize file variables
|
|
||||||
int fileStrLen, fileStrSubLoc;
|
|
||||||
// must have program name, one switch, config file name at minimum
|
|
||||||
if(numArgs >= MIN_NUM_ARGS)
|
|
||||||
{
|
|
||||||
// loop across args (starting at 1) and program run flag
|
|
||||||
while(argIndex < numArgs)
|
|
||||||
{
|
|
||||||
// check for -dc
|
|
||||||
if(compareString(strVector[argIndex], "-dc") == 0)
|
|
||||||
{
|
|
||||||
// set config display flag
|
|
||||||
clDataPtr->configDisplayFlag = true;
|
|
||||||
// set at least one switch flag
|
|
||||||
atLeastOneSwitchFlag = true;
|
|
||||||
}
|
|
||||||
// otherwise, check for -dm
|
|
||||||
else if(compareString(strVector[argIndex], "-dm") == 0)
|
|
||||||
{
|
|
||||||
// set metadata display flag
|
|
||||||
clDataPtr->mdDisplayFlag = true;
|
|
||||||
// set at least one switch flag
|
|
||||||
atLeastOneSwitchFlag = true;
|
|
||||||
}
|
|
||||||
// otherwise, check for -rs
|
|
||||||
else if(compareString(strVector[argIndex], "-rs") == 0)
|
|
||||||
{
|
|
||||||
// set run simulator flag
|
|
||||||
clDataPtr->runSimFlag = true;
|
|
||||||
// set at least one switch flag
|
|
||||||
atLeastOneSwitchFlag = true;
|
|
||||||
}
|
|
||||||
// otherwise, check for file name, ending in .cfg (must be last)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// find lengths to verify file name
|
|
||||||
// file name must be last argument, have '.cnf' extension
|
|
||||||
fileStrLen = getStringLength(strVector[numArgs - 1]);
|
|
||||||
fileStrSubLoc = findSubString(strVector[numArgs - 1], ".cnf");
|
|
||||||
// check for file existence and correct file format
|
|
||||||
if(fileStrSubLoc != SUBSTRING_NOT_FOUND &&
|
|
||||||
fileStrSubLoc == fileStrLen - LAST_FOUR_LETTERS)
|
|
||||||
{
|
|
||||||
// set file name to variable
|
|
||||||
copyString(clDataPtr->fileName, strVector[numArgs - 1]);
|
|
||||||
// set success flag to true
|
|
||||||
correctConfigFileFlag = true;
|
|
||||||
}
|
|
||||||
// otherwise, assume bad config file name
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// reset struct, correct config file flag stays false
|
|
||||||
// fct: clearCmdLineStruct
|
|
||||||
clearCmdLineStruct(clDataPtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// update arg index
|
|
||||||
argIndex = argIndex + 1;
|
|
||||||
}
|
|
||||||
// end loop across args and program run flag
|
|
||||||
}
|
|
||||||
// return verification of at least one switch and file name
|
|
||||||
return atLeastOneSwitchFlag && correctConfigFileFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: showCommandLineFormat
|
|
||||||
Process: displays command line format as assistance to user
|
|
||||||
Function Input/Parameters: none
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Monitor: data displayed as spec'd
|
|
||||||
Dependencies: printf
|
|
||||||
*/
|
|
||||||
void showCommandLineFormat()
|
|
||||||
{
|
|
||||||
// display command line format
|
|
||||||
// fct: printf
|
|
||||||
printf("Command Line Format:\n");
|
|
||||||
printf(" sim_01 [-dc] [-dm] [-rs] <configfile.cnf>\n");
|
|
||||||
printf(" -dc [optional] displays configuration data\n");
|
|
||||||
printf(" -dm [optional] displays metadata\n");
|
|
||||||
printf(" -rs [optional] runs the simulator\n");
|
|
||||||
printf(" required configfile.cnf\n");
|
|
||||||
// void function, no return.
|
|
||||||
}
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
#ifndef OS_DRIVER
|
|
||||||
#define OS_DRIVER
|
|
||||||
|
|
||||||
// header files
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "StringUtils.h"
|
|
||||||
#include "configops.h"
|
|
||||||
#include "metadataops.h"
|
|
||||||
#include "simulator.h"
|
|
||||||
// ??? #include "datatypes.h"
|
|
||||||
|
|
||||||
// program constants
|
|
||||||
typedef enum {SUBSTRING_NOT_FOUND = 0, MIN_NUM_ARGS = 3, LAST_FOUR_LETTERS = 4} PRG_CONSTANTS;
|
|
||||||
|
|
||||||
typedef struct CmdLineDataStruct
|
|
||||||
{
|
|
||||||
bool programRunFlag;
|
|
||||||
bool configDisplayFlag;
|
|
||||||
bool mdDisplayFlag;
|
|
||||||
bool runSimFlag;
|
|
||||||
char fileName[STD_STR_LEN];
|
|
||||||
} CmdLineData;
|
|
||||||
|
|
||||||
|
|
||||||
// function prototypes
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: clearCmdLineStruct
|
|
||||||
Process: sets command line structure data to defaults
|
|
||||||
Booleans to false, fileName to empty string
|
|
||||||
Function Input/Parameters: pointer to command line structure (CmdLineData *)
|
|
||||||
Function Output/Parameters: pointer to command line structure (CmdLineData *)
|
|
||||||
with updated members
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
void clearCmdLineStruct(CmdLineData *clDataPtr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: processCmdLine
|
|
||||||
Process: checks for at least two arguments,
|
|
||||||
then sets Booleans depending on command line switches
|
|
||||||
which can be in any order,
|
|
||||||
also captures config file name which must be last arugment
|
|
||||||
Function Input/Parameters: number of arguments (int),
|
|
||||||
vector of arguments (char **)
|
|
||||||
Function Output/Parameters: pointer to command line structure (CmdLineData *)
|
|
||||||
with updated members,
|
|
||||||
set to default values if failure
|
|
||||||
to capture arguments
|
|
||||||
Function Output/Returned: Boolean result of argument capture
|
|
||||||
true if at least one switch and config file name,
|
|
||||||
false otherwise
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
bool processCmdLine(int numArgs, char **strVector, CmdLineData *clDataPtr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: showCommandLineFormat
|
|
||||||
Process: displays command line format as assistance to user
|
|
||||||
Function Input/Parameters: none
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Monitor: data displayed as spec'd
|
|
||||||
Dependencies: printf
|
|
||||||
*/
|
|
||||||
void showCommandLineFormat();
|
|
||||||
|
|
||||||
#endif //OS_DRIVER
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
// Preprocessor directives
|
|
||||||
#ifndef STANDARD_CONSTANTS_H
|
|
||||||
#define STANDARD_CONSTANTS_H
|
|
||||||
|
|
||||||
// Include Boolean
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
// global constants
|
|
||||||
|
|
||||||
// constant for end of c-string null character
|
|
||||||
#define CARRIAGE_RETURN_CHAR '\r'
|
|
||||||
|
|
||||||
//constant for a COLON
|
|
||||||
#define COLON ':'
|
|
||||||
|
|
||||||
//constant for a SEMICOLON
|
|
||||||
#define SEMICOLON ';'
|
|
||||||
|
|
||||||
//constant for a COMMA
|
|
||||||
#define COMMA ','
|
|
||||||
|
|
||||||
//Constant to print a dash
|
|
||||||
#define DASH '-'
|
|
||||||
|
|
||||||
// constant for equivalent strings
|
|
||||||
#define EQUIV 0
|
|
||||||
|
|
||||||
// highest printable character
|
|
||||||
#define HIGHEST_PRINTABLE_CHAR '~'
|
|
||||||
|
|
||||||
// constant for huge string length
|
|
||||||
#define HUGE_STR_LEN 256
|
|
||||||
|
|
||||||
// lowest printable character
|
|
||||||
#define LOWEST_PRINTABLE_CHAR ' '
|
|
||||||
|
|
||||||
// constant for small string length
|
|
||||||
#define MIN_STR_LEN 32
|
|
||||||
|
|
||||||
// constant for maximum string length
|
|
||||||
#define MAX_STR_LEN 128
|
|
||||||
|
|
||||||
// constant for end of c-string null character
|
|
||||||
#define NEWLINE_CHAR '\n'
|
|
||||||
|
|
||||||
// first non-printable above ASCII
|
|
||||||
#define DELETE_KEY 127
|
|
||||||
|
|
||||||
// constant for end of c-string null character
|
|
||||||
#define NULL_CHAR '\0'
|
|
||||||
|
|
||||||
// columns found in grade sheet before grading columns
|
|
||||||
#define NUM_BASE_COLS 5
|
|
||||||
|
|
||||||
// constant for number of grading frequency bins
|
|
||||||
#define NUM_FREQUENCY_BINS 10
|
|
||||||
|
|
||||||
//Constant for printing a pipe
|
|
||||||
#define PIPE '|'
|
|
||||||
|
|
||||||
//Constant for a period
|
|
||||||
#define PERIOD '.'
|
|
||||||
|
|
||||||
//Constant for PRECISION, 2 digits
|
|
||||||
#define PRECISION_2 2
|
|
||||||
|
|
||||||
//Constant for PRECISION, 4 digits
|
|
||||||
#define PRECISION_4 4
|
|
||||||
|
|
||||||
// constant for space character
|
|
||||||
#define SPACE ' '
|
|
||||||
|
|
||||||
// constant for standard string length
|
|
||||||
#define STD_STR_LEN 64
|
|
||||||
|
|
||||||
// constant for smallest string length
|
|
||||||
#define TINY_STR_LEN 16
|
|
||||||
|
|
||||||
#endif // STANDARD_CONSTANTS
|
|
||||||
|
|
@ -1,454 +0,0 @@
|
||||||
// header files
|
|
||||||
#include "StringUtils.h"
|
|
||||||
|
|
||||||
// global constants
|
|
||||||
const int SUBSTRING_NOT_FOUND = 0;
|
|
||||||
|
|
||||||
// list of utils:
|
|
||||||
// string length
|
|
||||||
// getStringLength
|
|
||||||
// string copy
|
|
||||||
// copyString
|
|
||||||
// string concatenate
|
|
||||||
// catString
|
|
||||||
// string compare (<, >, =)
|
|
||||||
// compareString
|
|
||||||
// string substring get
|
|
||||||
// getSubString
|
|
||||||
// string substring find
|
|
||||||
// findSubString
|
|
||||||
// string set to lower
|
|
||||||
// toLowerCase
|
|
||||||
// string get to delimiter
|
|
||||||
// stringDelimiter
|
|
||||||
// string get to end of line
|
|
||||||
// stringEOL
|
|
||||||
|
|
||||||
// function implementations
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: catString
|
|
||||||
Process: concatenates two strings
|
|
||||||
Function input/parameters: c-style string (char *)
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: NONE
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: malloc, free, getStringLength
|
|
||||||
*/
|
|
||||||
void catString(char *outString, const char *inString)
|
|
||||||
{
|
|
||||||
// initialize variables
|
|
||||||
// set dest index
|
|
||||||
int destIndex = getStringLength(outString);
|
|
||||||
// set source str length
|
|
||||||
int sourceStrLen = getStringLength(inString);
|
|
||||||
// create temp string pointer
|
|
||||||
char *tempString;
|
|
||||||
int sourceIndex = 0;
|
|
||||||
|
|
||||||
// copy source string in case of aliasing
|
|
||||||
tempString = (char *)malloc(sizeof(char) * sourceStrLen);
|
|
||||||
copyString(tempString, inString);
|
|
||||||
|
|
||||||
// loop to end of source string
|
|
||||||
while(tempString[sourceIndex] != NULL_CHAR)
|
|
||||||
{
|
|
||||||
// assign characters to end of destination string
|
|
||||||
outString[destIndex] = inString[sourceIndex];
|
|
||||||
// update indices
|
|
||||||
destIndex = destIndex + 1;
|
|
||||||
sourceIndex = sourceIndex + 1;
|
|
||||||
}
|
|
||||||
// end loop to end of source string
|
|
||||||
// set temporary end of destination string
|
|
||||||
outString[destIndex] = NULL_CHAR;
|
|
||||||
|
|
||||||
// release memory used for temp string
|
|
||||||
free(tempString);
|
|
||||||
|
|
||||||
// no return, void.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: compareString
|
|
||||||
Process: compares two strings as follows:
|
|
||||||
- if left string is alphabetically greater than the right string,
|
|
||||||
returns value greater than zero
|
|
||||||
- if left string is alphabetically less than the right string,
|
|
||||||
returns value less than zero
|
|
||||||
- if strings are alphabetically equal but one is longer,
|
|
||||||
longer one is greater
|
|
||||||
- otherwise, returns zero
|
|
||||||
Function input/parameters: c-style strings (char *) [first and second/left&right]
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: results as specfifed above (int)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringLength
|
|
||||||
*/
|
|
||||||
int compareString(const char *firstString, const char *secondString)
|
|
||||||
{
|
|
||||||
// initialize variables
|
|
||||||
int diff, index = 0;
|
|
||||||
|
|
||||||
// loop to end of string (within bounds)
|
|
||||||
while(firstString[index] != NULL_CHAR && secondString[index] != NULL_CHAR)
|
|
||||||
{
|
|
||||||
// get diff of characters
|
|
||||||
diff = firstString[index] - secondString[index];
|
|
||||||
// check diff of characters
|
|
||||||
if(diff != 0)
|
|
||||||
{
|
|
||||||
// return diff
|
|
||||||
return diff;
|
|
||||||
}
|
|
||||||
// increment index
|
|
||||||
index = index + 1;
|
|
||||||
}
|
|
||||||
// end loop to end of string
|
|
||||||
|
|
||||||
// return difference in length of strings, if needed
|
|
||||||
return getStringLength(firstString) - getStringLength(secondString);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: copyString
|
|
||||||
Process: copies string into new string variable, overwrites destination.
|
|
||||||
Function input/parameters: c-style string (char *)
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: NONE
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringLength
|
|
||||||
*/
|
|
||||||
void copyString(char *outString, const char *inString)
|
|
||||||
{
|
|
||||||
// initialize variables
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
// check to see if outString is not the same as inString.
|
|
||||||
if(outString != inString)
|
|
||||||
{
|
|
||||||
// loop to end of inString
|
|
||||||
while(inString[index] != NULL_CHAR)
|
|
||||||
{
|
|
||||||
// assign characters to end of outString
|
|
||||||
outString[index] = inString[index];
|
|
||||||
// increment index
|
|
||||||
index = index + 1;
|
|
||||||
}
|
|
||||||
// end loop to end of inString
|
|
||||||
// set end of the outString
|
|
||||||
outString[index] = NULL_CHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no return, void.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: findSubString
|
|
||||||
Process: linear search for given substring within another string
|
|
||||||
Function input/parameters: c-style test string (char *),
|
|
||||||
c-style source string (char *)
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: index of found substring, or
|
|
||||||
SUBSTRING_NOT_FOUND constant
|
|
||||||
if string not found
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringLength
|
|
||||||
*/
|
|
||||||
int findSubString(const char *testStr, const char *searchSubStr)
|
|
||||||
{
|
|
||||||
// initialize variables
|
|
||||||
// initialize test string length
|
|
||||||
int testStrLength = getStringLength(testStr);
|
|
||||||
// initialize master index (location of substring start point)
|
|
||||||
int masterIndex = 0;
|
|
||||||
int searchIndex, internalIndex;
|
|
||||||
|
|
||||||
// loop across testStr
|
|
||||||
while(masterIndex < testStrLength)
|
|
||||||
{
|
|
||||||
// set internal loop index to current test string index
|
|
||||||
internalIndex = masterIndex;
|
|
||||||
// set internal search index to zero
|
|
||||||
searchIndex = 0;
|
|
||||||
// loop to end of testStr
|
|
||||||
// while testStr/searchSubStr characters are the same
|
|
||||||
while(internalIndex <= testStrLength &&
|
|
||||||
testStr[internalIndex] == searchSubStr[searchIndex])
|
|
||||||
{
|
|
||||||
// increment testStr and substring indices
|
|
||||||
internalIndex = internalIndex + 1;
|
|
||||||
searchIndex = searchIndex + 1;
|
|
||||||
// check for end of substring (search complete)
|
|
||||||
if(searchSubStr[searchIndex] == NULL_CHAR)
|
|
||||||
{
|
|
||||||
// return beginning location of substring
|
|
||||||
return masterIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// end while testStr/searchSubStr characters are the same
|
|
||||||
// increment current location starting index
|
|
||||||
masterIndex = masterIndex + 1;
|
|
||||||
}
|
|
||||||
// end loop across testStr
|
|
||||||
|
|
||||||
// return SUBSTRING_NOT_FOUND
|
|
||||||
return SUBSTRING_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringConstrained
|
|
||||||
Process: captures a string from the file stream with various constraints
|
|
||||||
Function input/parameters: input stream (FILE *),
|
|
||||||
clears leading non printable (bool),
|
|
||||||
clears leading space (bool),
|
|
||||||
stops at non printable (bool),
|
|
||||||
stops at specified delimiter (char)
|
|
||||||
will consume the delimiter.
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: success of operation (bool)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: fgetc
|
|
||||||
*/
|
|
||||||
bool getStringConstrained(FILE *inStream, bool clearLeadingNonPrintable,
|
|
||||||
bool clearLeadingSpace, bool stopAtNonPrintable,
|
|
||||||
char delimiter, char *capString)
|
|
||||||
{
|
|
||||||
// initialize variables
|
|
||||||
int intChar = EOF, index = 0;
|
|
||||||
|
|
||||||
// initialize output string
|
|
||||||
capString[index] = NULL_CHAR;
|
|
||||||
// capture first value in stream using fgetc
|
|
||||||
intChar = fgetc(inStream);
|
|
||||||
// loop to clear non-printable or space if indicated
|
|
||||||
while((intChar != EOF) &&
|
|
||||||
((clearLeadingNonPrintable && intChar < (int)SPACE)
|
|
||||||
|| (clearLeadingSpace && intChar == (int)SPACE)))
|
|
||||||
{
|
|
||||||
// get next character in stream using fgetc
|
|
||||||
intChar = fgetc(inStream);
|
|
||||||
}
|
|
||||||
// end loop to clear non-printable or space if indicated
|
|
||||||
// check for end of file found
|
|
||||||
if(intChar == EOF)
|
|
||||||
{
|
|
||||||
// return false (failed)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// loop to get input from file stream
|
|
||||||
while((intChar != EOF && index < MAX_STR_LEN - 1) &&
|
|
||||||
((stopAtNonPrintable && intChar >= (int)SPACE) || (!stopAtNonPrintable)) &&
|
|
||||||
(intChar != (char)delimiter))
|
|
||||||
{
|
|
||||||
// [continues if not at end of file and max string len not reached ]
|
|
||||||
// [AND continues if not printable flag set and characters printable ]
|
|
||||||
// [OR continues if not printable flag not set ]
|
|
||||||
// [AND continues if specified delimited is not found ]
|
|
||||||
|
|
||||||
// place character in array element
|
|
||||||
capString[index] = (char)intChar;
|
|
||||||
// increment array index
|
|
||||||
index = index + 1;
|
|
||||||
// set next element to null character
|
|
||||||
capString[index] = NULL_CHAR;
|
|
||||||
// get next character as integer using fgetc
|
|
||||||
intChar = fgetc(inStream);
|
|
||||||
}
|
|
||||||
// end loop to get input from file stream
|
|
||||||
// return success
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringLength
|
|
||||||
Process: gets length of string from start to NULL_CHAR ('\0')
|
|
||||||
Function input/parameters: c-style string (char *)
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: length of string (int)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: included by standard libraries
|
|
||||||
*/
|
|
||||||
int getStringLength(const char *stringIn)
|
|
||||||
{
|
|
||||||
// define variables
|
|
||||||
int stringLength = 0, currentCharacter = 0;
|
|
||||||
// get user input (not needed)
|
|
||||||
// do calculations
|
|
||||||
while (currentCharacter < STD_STR_LEN && stringIn[currentCharacter] != NULL_CHAR)
|
|
||||||
{
|
|
||||||
// increment string length
|
|
||||||
stringLength = stringLength + 1;
|
|
||||||
// increment currentCharacter
|
|
||||||
currentCharacter = currentCharacter + 1;
|
|
||||||
}
|
|
||||||
// display results (not needed)
|
|
||||||
// return success
|
|
||||||
return stringLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringToDelimiter
|
|
||||||
Process: captures a string from the input stream to a specified delimiter.
|
|
||||||
will consume the delimiter.
|
|
||||||
Function input/parameters: input stream (FILE *),
|
|
||||||
stops at specified character
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: success of operation (bool)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringConstrained
|
|
||||||
*/
|
|
||||||
bool getStringToDelimiter(FILE *inStream, char delimiter, char *capString)
|
|
||||||
{
|
|
||||||
// use getStringConstrained with delimiter to get string
|
|
||||||
return getStringConstrained(inStream, true, true, true, delimiter, capString);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringToLineEnd
|
|
||||||
Process: captures a string from the input stream to the end of the line
|
|
||||||
Function input/parameters: input file stream (FILE *)
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: success of operation (bool)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringConstrained
|
|
||||||
*/
|
|
||||||
bool getStringToLineEnd(FILE *inStream, char *capString)
|
|
||||||
{
|
|
||||||
// use getStringConstrained with line end character to get string
|
|
||||||
return getStringConstrained(inStream, true, true, true, '\n', capString);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getSubString
|
|
||||||
Process: captures sub string within larger string
|
|
||||||
between two inclusive indices.
|
|
||||||
returns empty string if either index is out of range,
|
|
||||||
assumes enough memory in dest string
|
|
||||||
Function input/parameters: c-style string (char *)
|
|
||||||
start and end indices (int)
|
|
||||||
Function output/parameters: c-style destination string (char *)
|
|
||||||
Function output/returned: NONE
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringLength, malloc, copyString, free
|
|
||||||
*/
|
|
||||||
void getSubString(char *destStr, const char *sourceStr,
|
|
||||||
int startIndex, int endIndex)
|
|
||||||
{
|
|
||||||
// initialize variables
|
|
||||||
// set length of source string using getStringLength
|
|
||||||
int sourceStrLen = getStringLength(sourceStr);
|
|
||||||
// initialize the destination index to zero
|
|
||||||
int destIndex = 0;
|
|
||||||
// initialize source index to start index (parameter)
|
|
||||||
int sourceIndex = startIndex;
|
|
||||||
// create pointer for temp string
|
|
||||||
char *tempStr;
|
|
||||||
|
|
||||||
// check for indices within limits
|
|
||||||
if(startIndex >= 0 && startIndex <= endIndex && endIndex < sourceStrLen)
|
|
||||||
{
|
|
||||||
// create temp string using malloc and copyString
|
|
||||||
tempStr = (char *)malloc(sourceStrLen + 1);
|
|
||||||
copyString(tempStr, sourceStr);
|
|
||||||
// loop across requested substring indices
|
|
||||||
while(sourceIndex <= endIndex)
|
|
||||||
{
|
|
||||||
// assign source character to destination element
|
|
||||||
destStr[destIndex] = tempStr[sourceIndex];
|
|
||||||
// increment indices
|
|
||||||
destIndex = destIndex + 1;
|
|
||||||
sourceIndex = sourceIndex + 1;
|
|
||||||
// set temporary end of destination string
|
|
||||||
destStr[destIndex] = NULL_CHAR;
|
|
||||||
}
|
|
||||||
// end loop across requested substring indices
|
|
||||||
// free temp string
|
|
||||||
free(tempStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// no return, void.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: strToLowerCase
|
|
||||||
Process: iterates through string, sets any uppercase letter to lowercase
|
|
||||||
equivalent, does not affect any letter with an upper/lower diff.
|
|
||||||
Function input/parameters: c-style source string (char *)
|
|
||||||
Function output/parameters: c-style dest string (char *)
|
|
||||||
Function output/returned: NONE
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: toLowerCase
|
|
||||||
*/
|
|
||||||
void strToLowerCase(char *outString, const char *inString)
|
|
||||||
{
|
|
||||||
// initialize variables
|
|
||||||
// get source string length
|
|
||||||
int sourceStrLen = getStringLength(inString);
|
|
||||||
// create temporary string pointer
|
|
||||||
char *tempStr;
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
// copy source string in case of aliasing using malloc and copyString
|
|
||||||
tempStr = (char *)malloc((sizeof(char) * (sourceStrLen + 1)));
|
|
||||||
copyString(tempStr, inString);
|
|
||||||
// loop across source string
|
|
||||||
while(tempStr[index] != NULL_CHAR && index < MAX_STR_LEN)
|
|
||||||
{
|
|
||||||
// set individual character to lowercase as needed, assigning back
|
|
||||||
outString[index] = toLowerCase(tempStr[index]);
|
|
||||||
// update index
|
|
||||||
index = index + 1;
|
|
||||||
// set temporary end of destination string
|
|
||||||
outString[index] = NULL_CHAR;
|
|
||||||
}
|
|
||||||
// end loop across source string
|
|
||||||
// free temporary string
|
|
||||||
free(tempStr);
|
|
||||||
|
|
||||||
// no return, void.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: toLowerCase
|
|
||||||
Process: sets character to lowercase letter if uppercase letter,
|
|
||||||
returns character
|
|
||||||
Function input/parameters: character input (char)
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: character output (char)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
char toLowerCase(char testChar)
|
|
||||||
{
|
|
||||||
// check for uppercase letter
|
|
||||||
if(testChar >= 'A' && testChar <= 'Z')
|
|
||||||
{
|
|
||||||
// return lowercase letter
|
|
||||||
return testChar - 'A' + 'a';
|
|
||||||
}
|
|
||||||
// otherwise, assume not uppercase letter, return unchanged
|
|
||||||
return testChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: ???
|
|
||||||
Process: ???
|
|
||||||
Function input/parameters: ???
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: ???
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: included by standard libraries
|
|
||||||
*/
|
|
||||||
|
|
@ -1,176 +0,0 @@
|
||||||
#ifndef STRINGUTILS
|
|
||||||
#define STRINGUTILS
|
|
||||||
|
|
||||||
// header files
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "StandardConstants.h"
|
|
||||||
|
|
||||||
// data structures
|
|
||||||
|
|
||||||
// program constants
|
|
||||||
|
|
||||||
// function prototypes
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: catString
|
|
||||||
Process: concatenates two strings
|
|
||||||
Function input/parameters: c-style string (char *)
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: NONE
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: malloc, free, getStringLength
|
|
||||||
*/
|
|
||||||
void catString(char *outString, const char *inString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: compareString
|
|
||||||
Process: compares two strings as follows:
|
|
||||||
- if left string is alphabetically greater than the right string,
|
|
||||||
returns value greater than zero
|
|
||||||
- if left string is alphabetically less than the right string,
|
|
||||||
returns value less than zero
|
|
||||||
- if strings are alphabetically equal but one is longer,
|
|
||||||
longer one is greater
|
|
||||||
- otherwise, returns zero
|
|
||||||
Function input/parameters: c-style strings (char *) [first and second/left&right]
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: results as specfifed above (int)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringLength
|
|
||||||
*/
|
|
||||||
int compareString(const char *firstString, const char *secondString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: copyString
|
|
||||||
Process: copies string into new string variable, overwrites destination.
|
|
||||||
Function input/parameters: c-style string (char *)
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: NONE
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringLength
|
|
||||||
*/
|
|
||||||
void copyString(char *outString, const char *inString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: findSubString
|
|
||||||
Process: linear search for given substring within another string
|
|
||||||
Function input/parameters: c-style test string (char *),
|
|
||||||
c-style source string (char *)
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: index of found substring, or
|
|
||||||
SUBSTRING_NOT_FOUND constant
|
|
||||||
if string not found
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringLength
|
|
||||||
*/
|
|
||||||
int findSubString(const char *testStr, const char *searchSubStr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringConstrained
|
|
||||||
Process: captures a string from the file stream with various constraints
|
|
||||||
Function input/parameters: input stream (FILE *),
|
|
||||||
clears leading non printable (bool),
|
|
||||||
clears leading space (bool),
|
|
||||||
stops at non printable (bool),
|
|
||||||
stops at specified delimiter (char)
|
|
||||||
will consume the delimiter.
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: success of operation (bool)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: fgetc
|
|
||||||
*/
|
|
||||||
bool getStringConstrained(FILE *inStream, bool clearLeadingNonPrintable,
|
|
||||||
bool clearLeadingSpace, bool stopAtNonPrintable,
|
|
||||||
char delimiter, char *capString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringLength
|
|
||||||
Process: gets length of string from start to NULL_CHAR ('\0')
|
|
||||||
Function input/parameters: c-style string (char *)
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: length of string (int)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: included by standard libraries
|
|
||||||
*/
|
|
||||||
int getStringLength(const char *stringIn);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringToDelimiter
|
|
||||||
Process: captures a string from the input stream to a specified delimiter.
|
|
||||||
will consume the delimiter.
|
|
||||||
Function input/parameters: input stream (FILE *),
|
|
||||||
stops at specified character
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: success of operation (bool)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringConstrained
|
|
||||||
*/
|
|
||||||
bool getStringToDelimiter(FILE *inStream, char delimiter, char *capString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringToLineEnd
|
|
||||||
Process: captures a string from the input stream to the end of the line
|
|
||||||
Function input/parameters: input file stream (FILE *)
|
|
||||||
Function output/parameters: c-style string (char *)
|
|
||||||
Function output/returned: success of operation (bool)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringConstrained
|
|
||||||
*/
|
|
||||||
bool getStringToLineEnd(FILE *inStream, char *capString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getSubString
|
|
||||||
Process: captures sub string within larger string
|
|
||||||
between two inclusive indices.
|
|
||||||
returns empty string if either index is out of range,
|
|
||||||
assumes enough memory in dest string
|
|
||||||
Function input/parameters: c-style string (char *)
|
|
||||||
start and end indices (int)
|
|
||||||
Function output/parameters: c-style destination string (char *)
|
|
||||||
Function output/returned: NONE
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: getStringLength, malloc, copyString, free
|
|
||||||
*/
|
|
||||||
void getSubString(char *destStr, const char *sourceStr,
|
|
||||||
int startIndex, int endIndex);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: strToLowerCase
|
|
||||||
Process: iterates through string, sets any uppercase letter to lowercase
|
|
||||||
equivalent, does not affect any letter with an upper/lower diff.
|
|
||||||
Function input/parameters: c-style source string (char *)
|
|
||||||
Function output/parameters: c-style dest string (char *)
|
|
||||||
Function output/returned: NONE
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: toLowerCase
|
|
||||||
*/
|
|
||||||
void strToLowerCase(char *outString, const char *inString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: toLowerCase
|
|
||||||
Process: sets character to lowercase letter if uppercase letter,
|
|
||||||
returns character
|
|
||||||
Function input/parameters: character input (char)
|
|
||||||
Function output/parameters: NONE
|
|
||||||
Function output/returned: character output (char)
|
|
||||||
Device input/---: NONE
|
|
||||||
Device output/---: NONE
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
char toLowerCase(char testChar);
|
|
||||||
|
|
||||||
#endif // STRINGUTILS
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
Start Simulator Configuration File:
|
|
||||||
Version/Phase : 1.05
|
|
||||||
File Path : metadata5.mdf
|
|
||||||
CPU Scheduling Code : SJF-N
|
|
||||||
Quantum Time (cycles) : 3
|
|
||||||
Memory Available (KB) : 11100
|
|
||||||
Memory Display (On/Off) : On
|
|
||||||
Processor Cycle Time (msec) : 10
|
|
||||||
I/O Cycle Time (msec) : 20
|
|
||||||
Log To : Both
|
|
||||||
Log File Path : logfile_1.lgf
|
|
||||||
End Simulator Configuration File.
|
|
||||||
|
|
||||||
|
|
@ -1,608 +0,0 @@
|
||||||
#include "configops.h"
|
|
||||||
#include "StandardConstants.h"
|
|
||||||
#include "StringUtils.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: clearConfigData
|
|
||||||
Process: frees dynamically allocated config data structure
|
|
||||||
if it has not already been freed
|
|
||||||
Function Input/Parameters: pointer to config data structure (ConfigDataType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: NULL (ConfigDataType *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: free
|
|
||||||
*/
|
|
||||||
ConfigDataType *clearConfigData(ConfigDataType *configData)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// check that config data pointer is not null
|
|
||||||
if(configData != NULL)
|
|
||||||
{
|
|
||||||
// free data structure memory
|
|
||||||
// fct: free
|
|
||||||
free(configData);
|
|
||||||
// set config pointer to NULL
|
|
||||||
configData = NULL;
|
|
||||||
}
|
|
||||||
// set config data pointer to null
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: configCodeToString
|
|
||||||
Process: utility fct converts configuration code numbers to string they represent
|
|
||||||
Function Input/Parameters: configuration code (int)
|
|
||||||
Function Output/Parameters: resulting output string (char *)
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: copyString
|
|
||||||
*/
|
|
||||||
void configCodeToString(int code, char *outString)
|
|
||||||
{
|
|
||||||
// define array with eight items, and short (10) lengths
|
|
||||||
char displayStrings[8][10] = {"SJF-N","SRTF-P","FCFS-P","RR-P",
|
|
||||||
"FCFS-N","Monitor", "File", "Both"};
|
|
||||||
// copy string to return parameter
|
|
||||||
// fct: copyString
|
|
||||||
copyString(outString, displayStrings[code]);
|
|
||||||
// void function, no return.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: displayConfigData
|
|
||||||
Process: screen dump/display of all config data
|
|
||||||
Function Input/Parameters: pointer to config data structure (ConfigDataType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Monitor: displayed as spec'd
|
|
||||||
Dependencies: configCodeToString, printf
|
|
||||||
*/
|
|
||||||
void displayConfigData(ConfigDataType *configData)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
char displayString[STD_STR_LEN];
|
|
||||||
// print lines of display for all member values
|
|
||||||
// fct: printf, codeToString
|
|
||||||
printf("Config File Display\n");
|
|
||||||
printf("-------------------\n");
|
|
||||||
printf("Version : %3.2f\n", configData->version);
|
|
||||||
printf("Program File Name : %s\n", configData->metaDataFileName);
|
|
||||||
configCodeToString(configData->cpuSchedCode, displayString);
|
|
||||||
printf("CPU Schedule Selection: %s\n", displayString);
|
|
||||||
printf("Quantum Time : %d\n", configData->quantumCycles);
|
|
||||||
printf("Memory Display : ");
|
|
||||||
if(configData->memDisplay)
|
|
||||||
{
|
|
||||||
printf("On\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Off\n");
|
|
||||||
}
|
|
||||||
printf("Memory Available : %d\n", configData->memAvailable);
|
|
||||||
printf("Process Cycle Rate : %d\n", configData->procCycleRate);
|
|
||||||
printf("I/O Cycle Rate : %d\n", configData->ioCycleRate);
|
|
||||||
configCodeToString(configData->logToCode, displayString);
|
|
||||||
printf("Log to Selection : %s\n", displayString);
|
|
||||||
printf("Log File Name : %s\n\n", configData->logToFileName);
|
|
||||||
// void function, no return.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getConfigData
|
|
||||||
Process: driver function for capturing config data from config file
|
|
||||||
Function Input/Parameters: file name (const char *)
|
|
||||||
Function Output/Parameters: pointer to config data pointer (ConfigDataType **)
|
|
||||||
end/result state message pointer (char *)
|
|
||||||
Function Output/Returned: Boolean result of data access operation (bool)
|
|
||||||
Device Input/File: config data uploaded
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: copyString, fopen, getStringToDelimiter, compareString, fclose,
|
|
||||||
malloc, free, stripTrailingSpaces, getDataLineCode, fscanf,
|
|
||||||
strToLowerCase, valueInRange, getCpuSchedCode, getLogToCode
|
|
||||||
*/
|
|
||||||
bool getConfigData(const char *fileName,
|
|
||||||
ConfigDataType **configData, char *endStateMsg)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// set constant number of data lines
|
|
||||||
const int NUM_DATA_LINES = 10;
|
|
||||||
// set read only constant
|
|
||||||
const char READ_ONLY_FLAG[] = "r";
|
|
||||||
// create pointer for data input
|
|
||||||
ConfigDataType *tempData;
|
|
||||||
// declare other variables
|
|
||||||
FILE *fileAccessPtr;
|
|
||||||
char dataBuffer[MAX_STR_LEN], lowerCaseDataBuffer[MAX_STR_LEN];
|
|
||||||
int intData, dataLineCode, lineCtr = 0;
|
|
||||||
double doubleData;
|
|
||||||
// set endStateMsg to success
|
|
||||||
// fct: copyString
|
|
||||||
char testMsg[] = "Configuration file upload successful";
|
|
||||||
copyString(endStateMsg, testMsg);
|
|
||||||
// initialize config data pointer in case of return error
|
|
||||||
*configData = NULL;
|
|
||||||
// open file
|
|
||||||
// fct: fopen
|
|
||||||
fileAccessPtr = fopen(fileName, READ_ONLY_FLAG);
|
|
||||||
// check for file open failure
|
|
||||||
if(fileAccessPtr == NULL)
|
|
||||||
{
|
|
||||||
// set end state message to config file access error
|
|
||||||
// fct: copyString
|
|
||||||
char testMsg[] = "Configuration file access error";
|
|
||||||
copyString(endStateMsg, testMsg);
|
|
||||||
// return file access error
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// get first line, check for failure
|
|
||||||
// fct: getStringToDelimiter, compareString
|
|
||||||
if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer)
|
|
||||||
|| compareString(dataBuffer, "Start Simulator Configuration File") != 0)
|
|
||||||
{
|
|
||||||
// close file access
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// set end state message to corrupt leader line error
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Corrupt configuration leader line error");
|
|
||||||
// return corrupt file data
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// create temporary pointer to configuration data structure
|
|
||||||
// fct: malloc
|
|
||||||
tempData = (ConfigDataType *) malloc(sizeof(ConfigDataType));
|
|
||||||
// loop to end of config data items
|
|
||||||
while(lineCtr < NUM_DATA_LINES)
|
|
||||||
{
|
|
||||||
// get line leader, check for failure
|
|
||||||
// fct: getStringToDelimiter
|
|
||||||
if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer))
|
|
||||||
{
|
|
||||||
// free temp struct memory
|
|
||||||
// fct: free
|
|
||||||
free(tempData);
|
|
||||||
// close file access
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// set end state message to line capture failure
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg,
|
|
||||||
"Configuration data leader line capture error");
|
|
||||||
// return incomplete file error
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// strip trailing spaces of config leader lines
|
|
||||||
// for use in other fcts
|
|
||||||
// fct: stripTrailingSpaces
|
|
||||||
stripTrailingSpaces(dataBuffer);
|
|
||||||
// find correct data line code number from string
|
|
||||||
// fct: getDataLineCode
|
|
||||||
dataLineCode = getDataLineCode(dataBuffer);
|
|
||||||
// check for data line found
|
|
||||||
if(dataLineCode != CFG_CORRUPT_PROMPT_ERR)
|
|
||||||
{
|
|
||||||
// get data value
|
|
||||||
// check for version number (double value)
|
|
||||||
if(dataLineCode == CFG_VERSION_CODE)
|
|
||||||
{
|
|
||||||
// get version number
|
|
||||||
// fct: fscanf
|
|
||||||
fscanf(fileAccessPtr, "%lf", &doubleData);
|
|
||||||
}
|
|
||||||
// otherwise, check for metaData, fileNames,
|
|
||||||
// CPU Scheduling names, or memory display setting (strings)
|
|
||||||
else if(dataLineCode == CFG_MD_FILE_NAME_CODE ||
|
|
||||||
dataLineCode == CFG_LOG_FILE_NAME_CODE ||
|
|
||||||
dataLineCode == CFG_CPU_SCHED_CODE ||
|
|
||||||
dataLineCode == CFG_LOG_TO_CODE ||
|
|
||||||
dataLineCode == CFG_MEM_DISPLAY_CODE)
|
|
||||||
{
|
|
||||||
// get string input
|
|
||||||
// fct: fscanf
|
|
||||||
fscanf(fileAccessPtr, "%s", dataBuffer);
|
|
||||||
// set string to lower case for testing in valueInRange
|
|
||||||
// fct: strToLowerCase
|
|
||||||
strToLowerCase(lowerCaseDataBuffer, dataBuffer);
|
|
||||||
}
|
|
||||||
// otherwise, assume integer data
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get integer input
|
|
||||||
// fct: fscanf
|
|
||||||
fscanf(fileAccessPtr, "%d", &intData);
|
|
||||||
}
|
|
||||||
// check for data value in range
|
|
||||||
// fct: valueInRange
|
|
||||||
if(valueInRange(dataLineCode, intData,
|
|
||||||
doubleData, lowerCaseDataBuffer))
|
|
||||||
{
|
|
||||||
// assign to data pointer depending on config item
|
|
||||||
// (all config line possibilities)
|
|
||||||
// fct: copyString, getCpuSchedCode,
|
|
||||||
// compareString, getLogToCode, as needed
|
|
||||||
switch(dataLineCode)
|
|
||||||
{
|
|
||||||
case CFG_VERSION_CODE:
|
|
||||||
tempData->version = doubleData;
|
|
||||||
break;
|
|
||||||
case CFG_MD_FILE_NAME_CODE:
|
|
||||||
copyString(tempData->metaDataFileName, dataBuffer);
|
|
||||||
break;
|
|
||||||
case CFG_CPU_SCHED_CODE:
|
|
||||||
tempData->cpuSchedCode =
|
|
||||||
getCpuSchedCode(lowerCaseDataBuffer);
|
|
||||||
break;
|
|
||||||
case CFG_QUANT_CYCLES_CODE:
|
|
||||||
tempData->quantumCycles = intData;
|
|
||||||
break;
|
|
||||||
case CFG_MEM_DISPLAY_CODE:
|
|
||||||
tempData->memDisplay =
|
|
||||||
compareString(lowerCaseDataBuffer, "on") == 0;
|
|
||||||
break;
|
|
||||||
case CFG_MEM_AVAILABLE_CODE:
|
|
||||||
tempData->memAvailable = intData;
|
|
||||||
break;
|
|
||||||
case CFG_PROC_CYCLES_CODE:
|
|
||||||
tempData->procCycleRate = intData;
|
|
||||||
break;
|
|
||||||
case CFG_IO_CYCLES_CODE:
|
|
||||||
tempData->ioCycleRate = intData;
|
|
||||||
break;
|
|
||||||
case CFG_LOG_TO_CODE:
|
|
||||||
tempData->logToCode = getLogToCode(lowerCaseDataBuffer);
|
|
||||||
break;
|
|
||||||
case CFG_LOG_FILE_NAME_CODE:
|
|
||||||
copyString(tempData->logToFileName, dataBuffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// otherwise, assume data value not in range
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// free temp struct memory
|
|
||||||
// fct: free
|
|
||||||
free(tempData);
|
|
||||||
// close file access
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// set end state message to configuration data out of range
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Configuration item out of range");
|
|
||||||
// return data out of range
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// otherwise, check for data line not found
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// free temp struct memory
|
|
||||||
// fct: free
|
|
||||||
free(tempData);
|
|
||||||
// close file access
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// set end state message to configuration corrupt prompt error
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Corrupted configuration prompt");
|
|
||||||
// return corrupt config file code
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// increment line counter
|
|
||||||
lineCtr = lineCtr + 1;
|
|
||||||
}
|
|
||||||
// end loop to end of config data items
|
|
||||||
// acquire end of sim config string
|
|
||||||
// fct: getStringToDelimiter, compareString
|
|
||||||
if(!getStringToDelimiter(fileAccessPtr, PERIOD, dataBuffer) ||
|
|
||||||
compareString(dataBuffer, "End Simulator Configuration File") != 0)
|
|
||||||
{
|
|
||||||
// free temp struct memory
|
|
||||||
// fct: free
|
|
||||||
free(tempData);
|
|
||||||
// close file access
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// set end state message to corrupt configuration end line
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Configuration end line capture error");
|
|
||||||
// return corrupt file data
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// test for "file only" output so memory diagnostics do not display
|
|
||||||
tempData->memDisplay = tempData->memDisplay &&
|
|
||||||
tempData->logToCode != LOGTO_FILE_CODE;
|
|
||||||
// assign temp ptr to parameter return ptr
|
|
||||||
*configData = tempData;
|
|
||||||
// close file access
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// return no error code
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getCpuSchedCode
|
|
||||||
Process: converts cpu schedule string to code (all scheduling possibilities)
|
|
||||||
Function Input/Parameters: lower case code string (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: cpu schedule code (ConfigDataCodes)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
ConfigDataCodes getCpuSchedCode(const char *lowerCaseCodeStr)
|
|
||||||
{
|
|
||||||
// iniitalize function and variables
|
|
||||||
// set default return to FCFS-N
|
|
||||||
ConfigDataCodes returnVal = CPU_SCHED_FCFS_N_CODE;
|
|
||||||
// check for SJF-N
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseCodeStr, "sjf-n") == 0)
|
|
||||||
{
|
|
||||||
// set SJF-N code
|
|
||||||
returnVal = CPU_SCHED_SJF_N_CODE;
|
|
||||||
}
|
|
||||||
// check for SRTF-P
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseCodeStr, "srtf-p") == 0)
|
|
||||||
{
|
|
||||||
// set SRTF-P code
|
|
||||||
returnVal = CPU_SCHED_SRTF_P_CODE;
|
|
||||||
}
|
|
||||||
// check for FCFS-P
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseCodeStr, "fcfs-p") == 0)
|
|
||||||
{
|
|
||||||
// set FCFS-P code
|
|
||||||
returnVal = CPU_SCHED_FCFS_P_CODE;
|
|
||||||
}
|
|
||||||
// check for RR-P
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseCodeStr, "rr-p") == 0)
|
|
||||||
{
|
|
||||||
// set RR-P code
|
|
||||||
returnVal = CPU_SCHED_RR_P_CODE;
|
|
||||||
}
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getDataLineCode
|
|
||||||
Process: converts leader line string to configuration code value
|
|
||||||
(processes all config file leader lines)
|
|
||||||
Function Input/Parameters: config leader line string (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: configuration code value (ConfigCodeMessages)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
ConfigCodeMessages getDataLineCode(const char *dataBuffer)
|
|
||||||
{
|
|
||||||
// iniitalize function and variables
|
|
||||||
// return appropriate code depending on prompt string provided
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(dataBuffer, "Version/Phase") == 0)
|
|
||||||
{
|
|
||||||
return CFG_VERSION_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "File Path") == 0)
|
|
||||||
{
|
|
||||||
return CFG_MD_FILE_NAME_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "CPU Scheduling Code") == 0)
|
|
||||||
{
|
|
||||||
return CFG_CPU_SCHED_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "Quantum Time (cycles)") == 0)
|
|
||||||
{
|
|
||||||
return CFG_QUANT_CYCLES_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "Memory Display (On/Off)") == 0)
|
|
||||||
{
|
|
||||||
return CFG_MEM_DISPLAY_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "Memory Available (KB)") == 0)
|
|
||||||
{
|
|
||||||
return CFG_MEM_AVAILABLE_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "Processor Cycle Time (msec)") == 0)
|
|
||||||
{
|
|
||||||
return CFG_PROC_CYCLES_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "I/O Cycle Time (msec)") == 0)
|
|
||||||
{
|
|
||||||
return CFG_IO_CYCLES_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "Log To") == 0)
|
|
||||||
{
|
|
||||||
return CFG_LOG_TO_CODE;
|
|
||||||
}
|
|
||||||
if(compareString(dataBuffer, "Log File Path") == 0)
|
|
||||||
{
|
|
||||||
return CFG_LOG_FILE_NAME_CODE;
|
|
||||||
}
|
|
||||||
// return corrupt leader line error code
|
|
||||||
return CFG_CORRUPT_PROMPT_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getLogToCode
|
|
||||||
Process: converts "log to" text to
|
|
||||||
configuration data code (three log to strings)
|
|
||||||
Function Input/Parameters: lower case log to string (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: configuration data code value
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
ConfigDataCodes getLogToCode(const char *lowerCaseLogToStr)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// set default to log to monitor
|
|
||||||
ConfigDataCodes returnVal = LOGTO_MONITOR_CODE;
|
|
||||||
// check for BOTH
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseLogToStr, "both") == 0)
|
|
||||||
{
|
|
||||||
// set return value to both code
|
|
||||||
returnVal = LOGTO_BOTH_CODE;
|
|
||||||
}
|
|
||||||
// check for FILE
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseLogToStr, "file") == 0)
|
|
||||||
{
|
|
||||||
// set return value to file code
|
|
||||||
returnVal = LOGTO_FILE_CODE;
|
|
||||||
}
|
|
||||||
// return selected code
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: stripTrailingSpaces
|
|
||||||
Process: removes trailing spaces from input config leader lines
|
|
||||||
Function Input/Parameters: config leader line string (char *)
|
|
||||||
Function Output/Parameters: updates config leader line string (char *)
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: getStringLength
|
|
||||||
*/
|
|
||||||
void stripTrailingSpaces(char *str)
|
|
||||||
{
|
|
||||||
// initialize index to length of string - 1 to get highest array index
|
|
||||||
int index = getStringLength(str) - 1;
|
|
||||||
// loop while space is found at the end of string
|
|
||||||
while(str[index] == SPACE)
|
|
||||||
{
|
|
||||||
// set element to NULL_CHAR
|
|
||||||
str[index] = NULL_CHAR;
|
|
||||||
// decrement index
|
|
||||||
index = index - 1;
|
|
||||||
}
|
|
||||||
// end loop from end of string
|
|
||||||
// void function, no return.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: valueInRange
|
|
||||||
Process: checks for config data values in range, including str values
|
|
||||||
Function Input/Parameters: line code number for specific config value (int),
|
|
||||||
integer value, as needed (int),
|
|
||||||
double value, as needed (double),
|
|
||||||
string value, as needed (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: Boolean result of the range test (bool)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
bool valueInRange(int lineCode, int intVal, double doubleVal,
|
|
||||||
const char *lowerCaseStringVal)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// set result to true, all tests are to find false
|
|
||||||
bool result = true;
|
|
||||||
// use line code to identify prompt line
|
|
||||||
switch(lineCode)
|
|
||||||
{
|
|
||||||
// for version code
|
|
||||||
case CFG_VERSION_CODE:
|
|
||||||
// check if limits of version code are exceeded
|
|
||||||
if(doubleVal < 0.00 || doubleVal > 10.00)
|
|
||||||
{
|
|
||||||
// set bool to false
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
break;
|
|
||||||
// for cpu scheduling code
|
|
||||||
case CFG_CPU_SCHED_CODE:
|
|
||||||
// check for not finding one of the scheduling strings
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseStringVal, "fcfs-n") != 0 &&
|
|
||||||
compareString(lowerCaseStringVal, "sjf-n") != 0 &&
|
|
||||||
compareString(lowerCaseStringVal, "srtf-p") != 0 &&
|
|
||||||
compareString(lowerCaseStringVal, "fcfs-p") != 0 &&
|
|
||||||
compareString(lowerCaseStringVal, "rr-p") != 0)
|
|
||||||
{
|
|
||||||
// set bool to false
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
break;
|
|
||||||
// for quantum cycles
|
|
||||||
case CFG_QUANT_CYCLES_CODE:
|
|
||||||
// check for quantum cycles limits exceeded
|
|
||||||
if(intVal < 0 || intVal > 100)
|
|
||||||
{
|
|
||||||
// set bool to false
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
break;
|
|
||||||
// for memory display
|
|
||||||
case CFG_MEM_DISPLAY_CODE:
|
|
||||||
// check for not finding either on or off
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseStringVal, "on") != 0 &&
|
|
||||||
compareString(lowerCaseStringVal, "off") != 0)
|
|
||||||
{
|
|
||||||
// set bool to false
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
break;
|
|
||||||
// for memory available
|
|
||||||
case CFG_MEM_AVAILABLE_CODE:
|
|
||||||
// check for memory limits exceeded
|
|
||||||
if(intVal < 1024 || intVal > 102400)
|
|
||||||
{
|
|
||||||
// set bool to false
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
break;
|
|
||||||
// check for process cycles
|
|
||||||
case CFG_PROC_CYCLES_CODE:
|
|
||||||
// check for process cycles limits exceeded
|
|
||||||
if(intVal < 1 || intVal > 100)
|
|
||||||
{
|
|
||||||
// set bool to false
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
break;
|
|
||||||
// check for process cycles
|
|
||||||
case CFG_IO_CYCLES_CODE:
|
|
||||||
// check for process cycles limits exceeded
|
|
||||||
if(intVal < 1 || intVal > 1000)
|
|
||||||
{
|
|
||||||
// set bool to false
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
break;
|
|
||||||
// check for log to operation
|
|
||||||
case CFG_LOG_TO_CODE:
|
|
||||||
// check for not finding one of the log to strings
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(lowerCaseStringVal, "both") != 0 &&
|
|
||||||
compareString(lowerCaseStringVal, "monitor") != 0 &&
|
|
||||||
compareString(lowerCaseStringVal, "file") != 0)
|
|
||||||
{
|
|
||||||
// set bool to false
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// return result of limits analysis
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
#ifndef CONFIGOPS
|
|
||||||
#define CONFIGOPS
|
|
||||||
|
|
||||||
#include "StandardConstants.h"
|
|
||||||
#include "StringUtils.h"
|
|
||||||
|
|
||||||
typedef enum {CFG_FILE_ACCESS_ERR,
|
|
||||||
CFG_CORRUPT_DESCRIPTOR_ERR,
|
|
||||||
CFG_DATA_OUT_OF_RANGE_ERR,
|
|
||||||
CFG_CORRUPT_PROMPT_ERR,
|
|
||||||
CFG_VERSION_CODE,
|
|
||||||
CFG_MD_FILE_NAME_CODE,
|
|
||||||
CFG_CPU_SCHED_CODE,
|
|
||||||
CFG_QUANT_CYCLES_CODE,
|
|
||||||
CFG_MEM_DISPLAY_CODE,
|
|
||||||
CFG_MEM_AVAILABLE_CODE,
|
|
||||||
CFG_PROC_CYCLES_CODE,
|
|
||||||
CFG_IO_CYCLES_CODE,
|
|
||||||
CFG_LOG_TO_CODE,
|
|
||||||
CFG_LOG_FILE_NAME_CODE
|
|
||||||
} ConfigCodeMessages;
|
|
||||||
|
|
||||||
typedef enum {CPU_SCHED_SJF_N_CODE,
|
|
||||||
CPU_SCHED_SRTF_P_CODE,
|
|
||||||
CPU_SCHED_FCFS_P_CODE,
|
|
||||||
CPU_SCHED_RR_P_CODE,
|
|
||||||
CPU_SCHED_FCFS_N_CODE,
|
|
||||||
LOGTO_MONITOR_CODE,
|
|
||||||
LOGTO_FILE_CODE,
|
|
||||||
LOGTO_BOTH_CODE,
|
|
||||||
NON_PREEMPTIVE_CODE,
|
|
||||||
PREEMPTIVE_CODE
|
|
||||||
} ConfigDataCodes;
|
|
||||||
|
|
||||||
typedef struct ConfigDataTypeStruct
|
|
||||||
{
|
|
||||||
double version;
|
|
||||||
char metaDataFileName[MAX_STR_LEN];
|
|
||||||
int cpuSchedCode;
|
|
||||||
int quantumCycles;
|
|
||||||
bool memDisplay;
|
|
||||||
int memAvailable;
|
|
||||||
int procCycleRate;
|
|
||||||
int ioCycleRate;
|
|
||||||
int logToCode;
|
|
||||||
char logToFileName[MAX_STR_LEN];
|
|
||||||
} ConfigDataType;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: clearConfigData
|
|
||||||
Process: frees dynamically allocated config data structure
|
|
||||||
if it has not already been freed
|
|
||||||
Function Input/Parameters: pointer to config data structure (ConfigDataType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: NULL (ConfigDataType *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
ConfigDataType *clearConfigData(ConfigDataType *configData);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: configCodeToString
|
|
||||||
Process: utility fct converts configuration code numbers to string they represent
|
|
||||||
Function Input/Parameters: configuration code (int)
|
|
||||||
Function Output/Parameters: resulting output string (char *)
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: copyString
|
|
||||||
*/
|
|
||||||
void configCodeToString(int code, char *outString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: displayConfigData
|
|
||||||
Process: screen dump/display of all config data
|
|
||||||
Function Input/Parameters: pointer to config data structure (ConfigDataType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Monitor: displayed as spec'd
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
void displayConfigData(ConfigDataType *configData);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getConfigData
|
|
||||||
Process: driver function for capturing config data from config file
|
|
||||||
Function Input/Parameters: file name (const char *)
|
|
||||||
Function Output/Parameters: pointer to config data pointer (ConfigDataType **)
|
|
||||||
end/result state message pointer (char *)
|
|
||||||
Function Output/Returned: Boolean result of data access operation (bool)
|
|
||||||
Device Input/File: config data uploaded
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: copyString, fopen, getStringToDelimiter, compareString, fclose,
|
|
||||||
malloc, free, stripTrailingSpaces, getDataLineCode, fscanf,
|
|
||||||
setStrToLowerCase, valueInRange, getCpuSchedCode, getLogToCode
|
|
||||||
*/
|
|
||||||
bool getConfigData(const char *fileName,
|
|
||||||
ConfigDataType **configData, char *endStateMsg);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getCpuSchedCode
|
|
||||||
Process: converts cpu schedule string to code (all scheduling possibilities)
|
|
||||||
Function Input/Parameters: lower case code string (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: cpu schedule code (ConfigDataCodes)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
ConfigDataCodes getCpuSchedCode(const char *lowerCaseCodeStr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getDataLineCode
|
|
||||||
Process: converts leader line string to configuration code value
|
|
||||||
(processes all config file leader lines)
|
|
||||||
Function Input/Parameters: config leader line string (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: configuration code value (ConfigCodeMessages)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
ConfigCodeMessages getDataLineCode(const char *dataBuffer);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getLogToCode
|
|
||||||
Process: converts "log to" text to
|
|
||||||
configuration data code (three log to strings)
|
|
||||||
Function Input/Parameters: lower case log to string (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: configuration data code value
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
ConfigDataCodes getLogToCode(const char *lowerCaseLogToStr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: stripTrailingSpaces
|
|
||||||
Process: removes trailing spaces from input config leader lines
|
|
||||||
Function Input/Parameters: config leader line string (char *)
|
|
||||||
Function Output/Parameters: updates config leader line string (char *)
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: getStringLength
|
|
||||||
*/
|
|
||||||
void stripTrailingSpaces(char *str);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: valueInRange
|
|
||||||
Process: checks for config data values in range, including str values
|
|
||||||
Function Input/Parameters: line code number for specific config value (int),
|
|
||||||
integer value, as needed (int),
|
|
||||||
double value, as needed (double),
|
|
||||||
string value, as needed (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: Boolean result of the range test (bool)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
bool valueInRange(int lineCode, int intVal, double doubleVal,
|
|
||||||
const char *lowerCaseStringVal);
|
|
||||||
|
|
||||||
#endif // CONFIGOPS
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
0.000000, OS: Simulator start
|
|
||||||
READY state from NEW state
|
|
||||||
ate
|
|
||||||
|
|
||||||
ate
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
Start Program Meta-Data Code:
|
|
||||||
sys start
|
|
||||||
app start, 0
|
|
||||||
dev in, serial, 28
|
|
||||||
dev out, video signal, 42
|
|
||||||
dev in, sound signal, 40
|
|
||||||
dev out, hard drive, 15
|
|
||||||
mem allocate, 4000, 2000
|
|
||||||
dev in, keyboard, 80
|
|
||||||
dev in, serial, 28
|
|
||||||
cpu process, 10
|
|
||||||
cpu process, 8
|
|
||||||
cpu process, 6
|
|
||||||
dev out, video signal, 49
|
|
||||||
app end
|
|
||||||
app start, 0
|
|
||||||
dev in, serial, 20
|
|
||||||
cpu process, 6
|
|
||||||
cpu process, 8
|
|
||||||
dev out, monitor, 70
|
|
||||||
cpu process, 6
|
|
||||||
cpu process, 9
|
|
||||||
mem allocate, 1000, 3000
|
|
||||||
dev out, sound signal, 45
|
|
||||||
dev out, hard drive, 15
|
|
||||||
dev in, video signal, 49
|
|
||||||
dev out, serial, 20
|
|
||||||
mem access, 2000, 1000
|
|
||||||
app end
|
|
||||||
app start, 0
|
|
||||||
dev in, hard drive, 18
|
|
||||||
dev out, video signal, 49
|
|
||||||
dev out, usb, 14
|
|
||||||
dev out, monitor, 70
|
|
||||||
cpu process, 7
|
|
||||||
mem allocate, 1500, 2000
|
|
||||||
cpu process, 9
|
|
||||||
dev in, keyboard, 70
|
|
||||||
dev in, video signal, 42
|
|
||||||
mem access, 2800, 1000
|
|
||||||
cpu process, 5
|
|
||||||
cpu process, 6
|
|
||||||
app end
|
|
||||||
app start, 0
|
|
||||||
dev in, hard drive, 21
|
|
||||||
dev out, sound signal, 30
|
|
||||||
cpu process, 7
|
|
||||||
mem allocate, 2500, 3000
|
|
||||||
dev in, keyboard, 80
|
|
||||||
dev in, hard drive, 30
|
|
||||||
dev out, video signal, 63
|
|
||||||
mem access, 2600, 1500
|
|
||||||
dev in, serial, 28
|
|
||||||
dev out, sound signal, 25
|
|
||||||
cpu process, 9
|
|
||||||
mem allocate, 2500, 1000
|
|
||||||
dev out, sound signal, 45
|
|
||||||
app end
|
|
||||||
app start, 0
|
|
||||||
dev in, serial, 24
|
|
||||||
dev out, video signal, 42
|
|
||||||
mem allocate, 3000, 3000
|
|
||||||
cpu process, 5
|
|
||||||
dev in, usb, 10
|
|
||||||
cpu process, 8
|
|
||||||
cpu process, 9
|
|
||||||
mem access, 3500, 2000
|
|
||||||
cpu process, 6
|
|
||||||
dev out, hard drive, 18
|
|
||||||
dev out, hard drive, 24
|
|
||||||
dev out, hard drive, 21
|
|
||||||
app end
|
|
||||||
sys end
|
|
||||||
End Program Meta-Data Code.
|
|
||||||
|
|
||||||
|
|
@ -1,729 +0,0 @@
|
||||||
#include "metadataops.h"
|
|
||||||
#include "StandardConstants.h"
|
|
||||||
#include "StringUtils.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: addNode
|
|
||||||
Process: adds metadata node to linked list recursively, handles empty list
|
|
||||||
Function Input/Parameters: ptr to head or next linked node (OpCodeType *),
|
|
||||||
ptr to new node (OpCodeType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: pointer to previous node, or head node (OpCodeType *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: malloc, copyString
|
|
||||||
*/
|
|
||||||
OpCodeType *addNode(OpCodeType *localPtr, OpCodeType *newNode)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// check for local pointer assigned to null
|
|
||||||
if(localPtr == NULL)
|
|
||||||
{
|
|
||||||
// access memory for new link/node
|
|
||||||
// fct: malloc
|
|
||||||
localPtr = (OpCodeType *) malloc(sizeof(OpCodeType));
|
|
||||||
// assign all three values to newly created node
|
|
||||||
// assign next pointer to null
|
|
||||||
// fct: copyString
|
|
||||||
localPtr->pid = newNode->pid;
|
|
||||||
copyString(localPtr->command, newNode->command);
|
|
||||||
copyString(localPtr->inOutArg, newNode->inOutArg);
|
|
||||||
copyString(localPtr->strArg1, newNode->strArg1);
|
|
||||||
localPtr->intArg2 = newNode->intArg2;
|
|
||||||
localPtr->intArg3 = newNode->intArg3;
|
|
||||||
localPtr->opEndTime = newNode->opEndTime;
|
|
||||||
localPtr->nextNode = NULL;
|
|
||||||
// return current local pointer
|
|
||||||
return localPtr;
|
|
||||||
}
|
|
||||||
// assume end of list not found
|
|
||||||
// assign recursive fct to current node's next link
|
|
||||||
// fct: addNode
|
|
||||||
localPtr->nextNode = addNode(localPtr->nextNode, newNode);
|
|
||||||
// return current local ptr
|
|
||||||
return localPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: clearMetaDataList
|
|
||||||
Process: recursively traverses list, frees dynamically allocated nodes
|
|
||||||
Function Input/Parameters: node opcode (const OpCodeType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: NULL (OpCodeType *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
OpCodeType *clearMetaDataList(OpCodeType *localPtr)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// check for local pointer not set to null (list not empty)
|
|
||||||
if(localPtr != NULL)
|
|
||||||
{
|
|
||||||
// call recursive function with next pointer
|
|
||||||
// fct: clearMetaDataList
|
|
||||||
clearMetaDataList(localPtr->nextNode);
|
|
||||||
// after recursive call, release mem to OS
|
|
||||||
// fct: free
|
|
||||||
free(localPtr);
|
|
||||||
// set given pointer to NULL
|
|
||||||
localPtr = NULL;
|
|
||||||
}
|
|
||||||
// return NULL to calling fct
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: displayMetaData
|
|
||||||
Process: data dump/display of all opcode items
|
|
||||||
Function Input/Parameters: pointer to
|
|
||||||
head of opcode/metadata list (const OpCodeType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: calculated time (int)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: printf, compareString
|
|
||||||
*/
|
|
||||||
void displayMetaData(const OpCodeType *localPtr)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// display title, with underline
|
|
||||||
// fct: printf
|
|
||||||
printf("Metadata File Display\n");
|
|
||||||
printf("---------------------\n\n");
|
|
||||||
// loop to end of linked list
|
|
||||||
while(localPtr != NULL)
|
|
||||||
{
|
|
||||||
// print leader
|
|
||||||
// fct: printf
|
|
||||||
printf("Opcode: ");
|
|
||||||
// print opcode pid
|
|
||||||
// fct: printf
|
|
||||||
printf("/pid: %d", localPtr->pid);
|
|
||||||
// print opcode command
|
|
||||||
// fct: printf
|
|
||||||
printf("/cmd: %s", localPtr->command);
|
|
||||||
// check for dev op
|
|
||||||
if(compareString(localPtr->command, "dev") == 0)
|
|
||||||
{
|
|
||||||
// print in/out parameter
|
|
||||||
// fct: printf
|
|
||||||
printf("/io: %s", localPtr->inOutArg);
|
|
||||||
}
|
|
||||||
// otherwise, assume other than dev
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// print NA
|
|
||||||
// fct: printf
|
|
||||||
printf("/io: NA");
|
|
||||||
}
|
|
||||||
// print first string argument
|
|
||||||
// fct: printf
|
|
||||||
printf("\n\t/arg 1: %s", localPtr->strArg1);
|
|
||||||
// print first int argument
|
|
||||||
// fct: printf
|
|
||||||
printf("/arg 2: %d", localPtr->intArg2);
|
|
||||||
// print second int argument
|
|
||||||
// fct: printf
|
|
||||||
printf("/arg 3: %d", localPtr->intArg3);
|
|
||||||
// print op end time
|
|
||||||
printf("/op end time: %8.6f", localPtr->opEndTime);
|
|
||||||
// endline print
|
|
||||||
// fct: printf
|
|
||||||
printf("\n\n");
|
|
||||||
// assign local pointer to next node
|
|
||||||
localPtr = localPtr->nextNode;
|
|
||||||
}
|
|
||||||
// void function, no return.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getCommand
|
|
||||||
Process: parses thre letter command part of opcode str
|
|
||||||
Function Input/Parameters: input opcode str (const char *),
|
|
||||||
starting index (int)
|
|
||||||
Function Output/Parameters: parsed command (char *)
|
|
||||||
Function Output/Returned: updated starting index for use by calling fct (int)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
int getCommand(char *cmd, const char *inputStr, int index)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
int lengthOfCommand = 3;
|
|
||||||
// loop across command length
|
|
||||||
while(index < lengthOfCommand)
|
|
||||||
{
|
|
||||||
// assign character from input string to buffer string
|
|
||||||
cmd[index] = inputStr[index];
|
|
||||||
// increment index
|
|
||||||
index = index + 1;
|
|
||||||
// set next character to null character
|
|
||||||
cmd[index] = NULL_CHAR;
|
|
||||||
}
|
|
||||||
// return current index
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getMetaData
|
|
||||||
Process: main driver function to upload, parse, and store list
|
|
||||||
of op code commands in a linked list
|
|
||||||
Function Input/Parameters: file name (const char *)
|
|
||||||
Function Output/Parameters: ptr to opcode linked list head ptr (OpCodeType **),
|
|
||||||
result msg of fct state after completion (char *)
|
|
||||||
Function Output/Returned: Boolean result of operation (bool)
|
|
||||||
Device Input/File: op code list uploaded
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: copyString, fopen, getStringToDelimiter, compareString, fclose,
|
|
||||||
malloc, getOpCommand, updateStartCount, updateEndCount,
|
|
||||||
clearMetaDataList, free, addNode
|
|
||||||
*/
|
|
||||||
bool getMetaData(const char *fileName,
|
|
||||||
OpCodeType **opCodeDataHead, char *endStateMsg)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// iniitialize read only constant
|
|
||||||
const char READ_ONLY_FLAG[] = "r";
|
|
||||||
// initialize variables
|
|
||||||
int accessResult, startCount = 0, endCount = 0;
|
|
||||||
char dataBuffer[MAX_STR_LEN];
|
|
||||||
bool returnState = true;
|
|
||||||
OpCodeType *newNodePtr;
|
|
||||||
OpCodeType *localHeadPtr = NULL;
|
|
||||||
FILE *fileAccessPtr;
|
|
||||||
// initialize opcode data pointer in case of return error
|
|
||||||
*opCodeDataHead = NULL;
|
|
||||||
// initialize end state message
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Metadata file upload successful");
|
|
||||||
// open file for reading
|
|
||||||
// fct: fopen
|
|
||||||
fileAccessPtr = fopen(fileName, READ_ONLY_FLAG);
|
|
||||||
// check for file open failure
|
|
||||||
if(fileAccessPtr == NULL)
|
|
||||||
{
|
|
||||||
// set end state message
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Metadata file access error");
|
|
||||||
// return file access error
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// check first line for correct leader
|
|
||||||
// fct: getStringToDelimiter, compareString
|
|
||||||
if(!getStringToDelimiter(fileAccessPtr, COLON, dataBuffer) ||
|
|
||||||
compareString(dataBuffer, "Start Program Meta-Data Code") != 0)
|
|
||||||
{
|
|
||||||
// close file
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// set end state message
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Corrupt metadata leader line error");
|
|
||||||
// return corrupt descriptor error
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// allocate memory for the temporary data structure
|
|
||||||
// fct: malloc
|
|
||||||
newNodePtr = (OpCodeType *) malloc(sizeof(OpCodeType));
|
|
||||||
// get the first op command
|
|
||||||
// fct: getOpCommand
|
|
||||||
accessResult = getOpCommand(fileAccessPtr, newNodePtr);
|
|
||||||
// get start and end counts for later comparison
|
|
||||||
// fct: updateStartCount, updateEndCount
|
|
||||||
startCount = updateStartCount(startCount, newNodePtr->strArg1);
|
|
||||||
endCount = updateEndCount(endCount, newNodePtr->strArg1);
|
|
||||||
// check for failure of first complete op command
|
|
||||||
if(accessResult != COMPLETE_OPCMD_FOUND_MSG)
|
|
||||||
{
|
|
||||||
// close file
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// clear data from the structure list
|
|
||||||
// fct: clearMetaDataList
|
|
||||||
*opCodeDataHead = clearMetaDataList(localHeadPtr);
|
|
||||||
// free temporary structure memory
|
|
||||||
// fct: free
|
|
||||||
free(newNodePtr);
|
|
||||||
// set end state message
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Metadata incomplete first op command found");
|
|
||||||
// return result of operation
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// loop across all remaining op commands
|
|
||||||
// (while complete op commands are found)
|
|
||||||
while(accessResult == COMPLETE_OPCMD_FOUND_MSG)
|
|
||||||
{
|
|
||||||
// add the new op command to the linked list
|
|
||||||
// fct: addNode
|
|
||||||
localHeadPtr = addNode(localHeadPtr, newNodePtr);
|
|
||||||
// get a new op command
|
|
||||||
// fct: getOpCommand
|
|
||||||
accessResult = getOpCommand(fileAccessPtr, newNodePtr);
|
|
||||||
// update start and end counts for later comparison
|
|
||||||
// fct: updateStartCount, updateEndCount
|
|
||||||
startCount = updateStartCount(startCount, newNodePtr->strArg1);
|
|
||||||
endCount = updateEndCount(endCount, newNodePtr->strArg1);
|
|
||||||
}
|
|
||||||
// end loop across all remaining op commands
|
|
||||||
// check for last op command found
|
|
||||||
if(accessResult == LAST_OPCMD_FOUND_MSG)
|
|
||||||
{
|
|
||||||
// check for start and end opcode counts equal
|
|
||||||
if(startCount == endCount)
|
|
||||||
{
|
|
||||||
// add the last node to the linked list
|
|
||||||
// fct: addNode
|
|
||||||
localHeadPtr = addNode(localHeadPtr, newNodePtr);
|
|
||||||
// set access result to no error for later operation
|
|
||||||
accessResult = NO_ACCESS_ERR;
|
|
||||||
// check last line for incorrect end descriptor
|
|
||||||
// fct: getStringToDelimiter, compareString
|
|
||||||
if(!getStringToDelimiter(fileAccessPtr, PERIOD, dataBuffer) ||
|
|
||||||
compareString(dataBuffer, "End Program Meta-Data Code") != 0)
|
|
||||||
{
|
|
||||||
// set access result to corrupted descriptor error
|
|
||||||
accessResult = MD_CORRUPT_DESCRIPTOR_ERR;
|
|
||||||
// set end state message
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Metadata corrupted descriptor error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// otherwise, assume start/end counts not equal
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// close file
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// clear data from the structure list
|
|
||||||
// fct: clearMetaDataList
|
|
||||||
*opCodeDataHead = clearMetaDataList(localHeadPtr);
|
|
||||||
// free temporary structure memory
|
|
||||||
// fct: free
|
|
||||||
free(newNodePtr);
|
|
||||||
// set access result to error
|
|
||||||
accessResult = UNBALANCED_START_END_ERR;
|
|
||||||
// set end state message
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg,
|
|
||||||
"Unbalanced start and end arguments in metadata");
|
|
||||||
// return result of operation
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// otherwise, assume didn't find end
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// set end state message
|
|
||||||
// fct: copyString
|
|
||||||
copyString(endStateMsg, "Corrupted metadata opcode");
|
|
||||||
// unset return state
|
|
||||||
returnState = false;
|
|
||||||
}
|
|
||||||
// check for any errors found (not no error)
|
|
||||||
if(accessResult != NO_ACCESS_ERR)
|
|
||||||
{
|
|
||||||
// clear the op command list
|
|
||||||
// fct: clearMetaDataList
|
|
||||||
localHeadPtr = clearMetaDataList(localHeadPtr);
|
|
||||||
}
|
|
||||||
// close access file
|
|
||||||
// fct: fclose
|
|
||||||
fclose(fileAccessPtr);
|
|
||||||
// release temporary structure memory
|
|
||||||
// fct: free
|
|
||||||
free(newNodePtr);
|
|
||||||
// assign temporary local head ptr to parameter return ptr
|
|
||||||
*opCodeDataHead = localHeadPtr;
|
|
||||||
// return access result
|
|
||||||
return returnState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getOpCommand
|
|
||||||
Process: acquires one op command line from a previously opened file,
|
|
||||||
parses it, and sets various struct members according to the
|
|
||||||
three letter command
|
|
||||||
Function Input/Parameters: ptr to open file handle (FILE *)
|
|
||||||
Function Output/Parameters: ptr to one opcode struct (OpCodeType *)
|
|
||||||
Function Output/Returned: coded result of operation (OpCodeMessages)
|
|
||||||
Device Input/File: opcode line uploaded
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: getStringToDelimiter, getCommand, copyString, verifyValidCommand,
|
|
||||||
compareString, getStringArg, verifyFirstStringArg, getNumberArg
|
|
||||||
*/
|
|
||||||
OpCodeMessages getOpCommand(FILE *filePtr, OpCodeType *inData)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
// initialize local constants
|
|
||||||
const int MAX_CMD_LENGTH = 5;
|
|
||||||
const int MAX_ARG_STR_LENGTH = 15;
|
|
||||||
// initialize other variables
|
|
||||||
int numBuffer = 0;
|
|
||||||
char strBuffer[STD_STR_LEN];
|
|
||||||
char cmdBuffer[MAX_CMD_LENGTH];
|
|
||||||
char argStrBuffer[MAX_ARG_STR_LENGTH];
|
|
||||||
int runningStringIndex = 0;
|
|
||||||
bool arg2FailureFlag = false;
|
|
||||||
bool arg3FailureFlag = false;
|
|
||||||
// get whole op command as string, check for successful access
|
|
||||||
// fct: getStringToDelimiter
|
|
||||||
if(getStringToDelimiter(filePtr, SEMICOLON, strBuffer))
|
|
||||||
{
|
|
||||||
// get three-letter command
|
|
||||||
// fct: getCommand
|
|
||||||
runningStringIndex = getCommand(cmdBuffer,
|
|
||||||
strBuffer, runningStringIndex);
|
|
||||||
// assign op command to node
|
|
||||||
// fct: copyString
|
|
||||||
copyString(inData->command, cmdBuffer);
|
|
||||||
}
|
|
||||||
// otherwise, assume unsuccessful access
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// set ptr to data structure to null
|
|
||||||
inData = NULL;
|
|
||||||
// return op command access failure
|
|
||||||
return OPCMD_ACCESS_ERR;
|
|
||||||
}
|
|
||||||
// verify op command
|
|
||||||
if(!verifyValidCommand(cmdBuffer))
|
|
||||||
{
|
|
||||||
// return op command error
|
|
||||||
return CORRUPT_OPCMD_ERR;
|
|
||||||
}
|
|
||||||
// set all struct values that may not be initialized to defaults
|
|
||||||
inData->pid = 0;
|
|
||||||
inData->inOutArg[0] = NULL_CHAR;
|
|
||||||
inData->intArg2 = 0;
|
|
||||||
inData->intArg3 = 0;
|
|
||||||
inData->opEndTime = 0.0;
|
|
||||||
inData->nextNode = NULL;
|
|
||||||
// check for device command
|
|
||||||
if(compareString(cmdBuffer, "dev") == 0)
|
|
||||||
{
|
|
||||||
// get in/out arg
|
|
||||||
runningStringIndex = getStringArg(argStrBuffer,
|
|
||||||
strBuffer, runningStringIndex);
|
|
||||||
// set device in/out arg
|
|
||||||
copyString(inData->inOutArg, argStrBuffer);
|
|
||||||
// check correct argument
|
|
||||||
if(compareString(argStrBuffer, "in") != 0 &&
|
|
||||||
compareString(argStrBuffer, "out") != 0)
|
|
||||||
{
|
|
||||||
// return argument error
|
|
||||||
return CORRUPT_OPCMD_ARG_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// get first string arg
|
|
||||||
runningStringIndex = getStringArg(argStrBuffer,
|
|
||||||
strBuffer, runningStringIndex);
|
|
||||||
// set device in/out arg
|
|
||||||
copyString(inData->strArg1, argStrBuffer);
|
|
||||||
// check for legit first string arg
|
|
||||||
if(!verifyFirstStringArg(argStrBuffer))
|
|
||||||
{
|
|
||||||
// return arg error
|
|
||||||
return CORRUPT_OPCMD_ARG_ERR;
|
|
||||||
}
|
|
||||||
// check for last op command found
|
|
||||||
if(compareString(inData->command, "sys") == 0 &&
|
|
||||||
compareString(inData->strArg1, "end") == 0)
|
|
||||||
{
|
|
||||||
// return last op command found message
|
|
||||||
return LAST_OPCMD_FOUND_MSG;
|
|
||||||
}
|
|
||||||
// check for app start seconds argument
|
|
||||||
if(compareString(inData->command, "app") == 0 &&
|
|
||||||
compareString(inData->strArg1, "start") == 0)
|
|
||||||
{
|
|
||||||
// get number argument
|
|
||||||
// fct: getNumberArg
|
|
||||||
runningStringIndex = getNumberArg(&numBuffer,
|
|
||||||
strBuffer, runningStringIndex);
|
|
||||||
// check for failed number access
|
|
||||||
if(numBuffer <= BAD_ARG_VAL)
|
|
||||||
{
|
|
||||||
// set failure flag
|
|
||||||
arg2FailureFlag = true;
|
|
||||||
}
|
|
||||||
// set first int argument to number
|
|
||||||
inData->intArg2 = numBuffer;
|
|
||||||
}
|
|
||||||
// check for cpu cycle time
|
|
||||||
else if(compareString(inData->command, "cpu") == 0)
|
|
||||||
{
|
|
||||||
// get number argument
|
|
||||||
// fct: getNumberArg
|
|
||||||
runningStringIndex = getNumberArg(&numBuffer,
|
|
||||||
strBuffer, runningStringIndex);
|
|
||||||
// check for failed number access
|
|
||||||
if(numBuffer <= BAD_ARG_VAL)
|
|
||||||
{
|
|
||||||
// set failure flag
|
|
||||||
arg2FailureFlag = true;
|
|
||||||
}
|
|
||||||
// set first int argument to number
|
|
||||||
inData->intArg2 = numBuffer;
|
|
||||||
}
|
|
||||||
// check for device cycle time
|
|
||||||
else if(compareString(inData->command, "dev") == 0)
|
|
||||||
{
|
|
||||||
// get number argument
|
|
||||||
// fct: getNumberArg
|
|
||||||
runningStringIndex = getNumberArg(&numBuffer,
|
|
||||||
strBuffer, runningStringIndex);
|
|
||||||
// check for failed number access
|
|
||||||
if(numBuffer <= BAD_ARG_VAL)
|
|
||||||
{
|
|
||||||
// set failure flag
|
|
||||||
arg2FailureFlag = true;
|
|
||||||
}
|
|
||||||
// set first int argument to number
|
|
||||||
inData->intArg2 = numBuffer;
|
|
||||||
}
|
|
||||||
// check for memory base and offset
|
|
||||||
else if(compareString(inData->command, "mem") == 0)
|
|
||||||
{
|
|
||||||
// get number argument
|
|
||||||
// fct: getNumberArg
|
|
||||||
runningStringIndex = getNumberArg(&numBuffer,
|
|
||||||
strBuffer, runningStringIndex);
|
|
||||||
// check for failed number access
|
|
||||||
if(numBuffer <= BAD_ARG_VAL)
|
|
||||||
{
|
|
||||||
// set failure flag
|
|
||||||
arg2FailureFlag = true;
|
|
||||||
}
|
|
||||||
// set first int argument to number
|
|
||||||
inData->intArg2 = numBuffer;
|
|
||||||
// get number argument for offset
|
|
||||||
// fct: getNumberArg
|
|
||||||
runningStringIndex = getNumberArg(&numBuffer,
|
|
||||||
strBuffer, runningStringIndex);
|
|
||||||
if(numBuffer <= BAD_ARG_VAL)
|
|
||||||
{
|
|
||||||
// set failure flag
|
|
||||||
arg3FailureFlag = true;
|
|
||||||
}
|
|
||||||
// set second int argument to number
|
|
||||||
inData->intArg3 = numBuffer;
|
|
||||||
}
|
|
||||||
// check int args for upload failure
|
|
||||||
if(arg2FailureFlag || arg3FailureFlag)
|
|
||||||
{
|
|
||||||
// return corrupt op command found message
|
|
||||||
return CORRUPT_OPCMD_ARG_ERR;
|
|
||||||
}
|
|
||||||
// return complete op command found message
|
|
||||||
return COMPLETE_OPCMD_FOUND_MSG;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getNumberArg
|
|
||||||
Process: starts at given index, captures
|
|
||||||
and assembles int arg, returns as parameter
|
|
||||||
Function Input/Parameters: input str (const char *), starting index (int)
|
|
||||||
Function Output/Parameters: pointer to captured integer value
|
|
||||||
Function Output/Returned: updated index for next function start
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: isDigit
|
|
||||||
*/
|
|
||||||
int getNumberArg(int *number, const char *inputStr, int index)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
bool foundDigit = false;
|
|
||||||
*number = 0;
|
|
||||||
int multiplier = 1;
|
|
||||||
// loop to skip whitespace
|
|
||||||
while(inputStr[index] <= SPACE || inputStr[index] == COMMA)
|
|
||||||
{
|
|
||||||
// increment the index
|
|
||||||
index = index + 1;
|
|
||||||
}
|
|
||||||
// loop across string length
|
|
||||||
while(isDigit(inputStr[index]) &&
|
|
||||||
inputStr[index] != NULL_CHAR)
|
|
||||||
{
|
|
||||||
// set digit found flag
|
|
||||||
foundDigit = true;
|
|
||||||
// assign digit to output
|
|
||||||
(*number) = (*number) * multiplier + (inputStr[index] - '0');
|
|
||||||
// increment index and multiplier
|
|
||||||
index = index + 1;
|
|
||||||
multiplier = 10;
|
|
||||||
}
|
|
||||||
// check for digit not found
|
|
||||||
if(!foundDigit)
|
|
||||||
{
|
|
||||||
// set number to BAD_ARG_VAL, use dereference for ptr
|
|
||||||
*number = BAD_ARG_VAL;
|
|
||||||
}
|
|
||||||
// return current index
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringArg
|
|
||||||
Process: starts at given index, captures
|
|
||||||
and assembles str arg, returns as parameter
|
|
||||||
Function Input/Parameters: input str (const char *), starting index (int)
|
|
||||||
Function Output/Parameters: ptr to captured string argument (char *)
|
|
||||||
Function Output/Returned: updated index for next fct start
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
int getStringArg(char *strArg, const char *inputStr, int index)
|
|
||||||
{
|
|
||||||
// initialize function and variables
|
|
||||||
int localIndex = 0;
|
|
||||||
// loop to skip whitespace
|
|
||||||
while(inputStr[index] <= SPACE || inputStr[index] == COMMA)
|
|
||||||
{
|
|
||||||
// increment the index
|
|
||||||
index = index + 1;
|
|
||||||
}
|
|
||||||
// loop across string length
|
|
||||||
while(inputStr[index] != COMMA && inputStr[index] != NULL_CHAR)
|
|
||||||
{
|
|
||||||
// assign character from input string to buffer string
|
|
||||||
strArg[localIndex] = inputStr[index];
|
|
||||||
// increment index
|
|
||||||
index = index + 1;
|
|
||||||
localIndex = localIndex + 1;
|
|
||||||
// set next character to null character
|
|
||||||
strArg[localIndex] = NULL_CHAR;
|
|
||||||
}
|
|
||||||
// return current index
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: isDigit
|
|
||||||
Process: tests character parameter for digit,
|
|
||||||
returns true if is digit, false otherwise
|
|
||||||
Function Input/Parameters: test character (char)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: bool result of test (bool)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
bool isDigit(char testChar)
|
|
||||||
{
|
|
||||||
// check for test character between characters '0' - '9'
|
|
||||||
// return true
|
|
||||||
// otherwise, assume character if not digit, return false
|
|
||||||
return testChar >= '0' && testChar <= '9';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: updateEndCount
|
|
||||||
Process: manages count of "end" arguments
|
|
||||||
to be compared at end of process input
|
|
||||||
Function Input/Parameters: initial count (int),
|
|
||||||
test string for "end" (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: updated count, if "end" string found,
|
|
||||||
otherwise no change
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
int updateEndCount(int count, const char *opString)
|
|
||||||
{
|
|
||||||
// check for "end" in op string
|
|
||||||
// fct: compareString
|
|
||||||
if(compareString(opString, "end") == 0)
|
|
||||||
{
|
|
||||||
// return incremented end count
|
|
||||||
return count + 1;
|
|
||||||
}
|
|
||||||
// return unchanged end count
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: updateStartCount
|
|
||||||
Process: manages count of "start" arguments
|
|
||||||
to be compared at start of process input
|
|
||||||
Function Input/Parameters: initial count (int),
|
|
||||||
test string for "start" (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: updated count, if "start" string found,
|
|
||||||
otherwise no change
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
int updateStartCount(int count, const char *opString)
|
|
||||||
{
|
|
||||||
// check for "start" in op string
|
|
||||||
// fct: compareString
|
|
||||||
if (compareString(opString, "start") == 0)
|
|
||||||
{
|
|
||||||
// return incremented start count
|
|
||||||
return count + 1;
|
|
||||||
}
|
|
||||||
// return unchanged start count
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: verifyFirstStringArg
|
|
||||||
Process: checks for all possibilities of first argument string of op command
|
|
||||||
Function Input/Parameters: test string (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: bool result of test (bool)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
bool verifyFirstStringArg(const char *strArg)
|
|
||||||
{
|
|
||||||
// check for string holding correct first argument
|
|
||||||
// fct: compareString
|
|
||||||
// return true
|
|
||||||
// otherwise, assume test fail, return false
|
|
||||||
return compareString(strArg, "access") == 0 ||
|
|
||||||
compareString(strArg, "allocate") == 0 ||
|
|
||||||
compareString(strArg, "end") == 0 ||
|
|
||||||
compareString(strArg, "ethernet") == 0 ||
|
|
||||||
compareString(strArg, "hard drive") == 0 ||
|
|
||||||
compareString(strArg, "keyboard") == 0 ||
|
|
||||||
compareString(strArg, "monitor") == 0 ||
|
|
||||||
compareString(strArg, "printer") == 0 ||
|
|
||||||
compareString(strArg, "process") == 0 ||
|
|
||||||
compareString(strArg, "serial") == 0 ||
|
|
||||||
compareString(strArg, "sound signal") == 0 ||
|
|
||||||
compareString(strArg, "start") == 0 ||
|
|
||||||
compareString(strArg, "usb") == 0 ||
|
|
||||||
compareString(strArg, "video signal") == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: verifyValidCommand
|
|
||||||
Process: checks for all possibilities of three-letter opcode command
|
|
||||||
Function Input/Parameters: test string for command (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: bool result of test (bool)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
bool verifyValidCommand(char *testCmd)
|
|
||||||
{
|
|
||||||
// check for string holding three-letter opcode command
|
|
||||||
// fct: compareString
|
|
||||||
// return true
|
|
||||||
// otherwise, assume test failure, return false
|
|
||||||
return compareString(testCmd, "sys") == 0 ||
|
|
||||||
compareString(testCmd, "app") == 0 ||
|
|
||||||
compareString(testCmd, "cpu") == 0 ||
|
|
||||||
compareString(testCmd, "mem") == 0 ||
|
|
||||||
compareString(testCmd, "dev") == 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,207 +0,0 @@
|
||||||
#ifndef METADATAOPS
|
|
||||||
#define METADATAOPS
|
|
||||||
|
|
||||||
#include "StandardConstants.h"
|
|
||||||
#include "StringUtils.h"
|
|
||||||
|
|
||||||
typedef enum {BAD_ARG_VAL = -1,
|
|
||||||
NO_ACCESS_ERR,
|
|
||||||
MD_FILE_ACCESS_ERR,
|
|
||||||
MD_CORRUPT_DESCRIPTOR_ERR,
|
|
||||||
OPCMD_ACCESS_ERR,
|
|
||||||
CORRUPT_OPCMD_ERR,
|
|
||||||
CORRUPT_OPCMD_ARG_ERR,
|
|
||||||
UNBALANCED_START_END_ERR,
|
|
||||||
COMPLETE_OPCMD_FOUND_MSG,
|
|
||||||
LAST_OPCMD_FOUND_MSG
|
|
||||||
} OpCodeMessages;
|
|
||||||
|
|
||||||
typedef struct OpCodeTypeStruct
|
|
||||||
{
|
|
||||||
int pid;
|
|
||||||
char command[MAX_STR_LEN];
|
|
||||||
char inOutArg[MAX_STR_LEN];
|
|
||||||
char strArg1[MAX_STR_LEN];
|
|
||||||
int intArg2;
|
|
||||||
int intArg3;
|
|
||||||
double opEndTime;
|
|
||||||
struct OpCodeTypeStruct *nextNode;
|
|
||||||
} OpCodeType;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: addNode
|
|
||||||
Process: adds metadata node to linked list recursively, handles empty list
|
|
||||||
Function Input/Parameters: ptr to head or next linked node (OpCodeType *),
|
|
||||||
ptr to new node (OpCodeType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: pointer to previous node, or head node (OpCodeType *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: malloc, copyString
|
|
||||||
*/
|
|
||||||
OpCodeType *addNode(OpCodeType *localPtr, OpCodeType *newNode);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: clearMetaDataList
|
|
||||||
Process: recursively traverses list, frees dynamically allocated nodes
|
|
||||||
Function Input/Parameters: node opcode (const OpCodeType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: NULL (OpCodeType *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
OpCodeType *clearMetaDataList(OpCodeType *localPtr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: displayMetaData
|
|
||||||
Process: data dump/display of all opcode items
|
|
||||||
Function Input/Parameters: pointer to
|
|
||||||
head of opcode/metadata list (const OpCodeType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: calculated time (int)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: printf, compareString
|
|
||||||
*/
|
|
||||||
void displayMetaData(const OpCodeType *localPtr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getCommand
|
|
||||||
Process: parses thre letter command part of opcode str
|
|
||||||
Function Input/Parameters: input opcode str (const char *),
|
|
||||||
starting index (int)
|
|
||||||
Function Output/Parameters: parsed command (char *)
|
|
||||||
Function Output/Returned: updated starting index for use by calling fct (int)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
int getCommand(char *cmd, const char *inputStr, int index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getMetaData
|
|
||||||
Process: main driver function to upload, parse, and store list
|
|
||||||
of op code commands in a linked list
|
|
||||||
Function Input/Parameters: file name (const char *)
|
|
||||||
Function Output/Parameters: ptr to opcode linked list head ptr (OpCodeType **),
|
|
||||||
result msg of fct state after completion (char *)
|
|
||||||
Function Output/Returned: Boolean result of operation (bool)
|
|
||||||
Device Input/File: op code list uploaded
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: copyString, fopen, getStringToDelimiter, compareString, fclose,
|
|
||||||
malloc, getOpCommand, updateStartCount, updateEndCount,
|
|
||||||
clearMetaDataList, free, addNode
|
|
||||||
*/
|
|
||||||
bool getMetaData(const char *fileName,
|
|
||||||
OpCodeType **opCodeDataHead, char *endStateMsg);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getOpCommand
|
|
||||||
Process: acquires one op command line from a previously opened file,
|
|
||||||
parses it, and sets various struct members according to the
|
|
||||||
three letter command
|
|
||||||
Function Input/Parameters: ptr to open file handle (FILE *)
|
|
||||||
Function Output/Parameters: ptr to one opcode struct (OpCodeType *)
|
|
||||||
Function Output/Returned: coded result of operation (OpCodeMessages)
|
|
||||||
Device Input/File: opcode line uploaded
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: getStringToDelimiter, getCommand, copyString, verifyValidCommand,
|
|
||||||
compareString, getStringArg, verifyFirstStringArg, getNumberArg
|
|
||||||
*/
|
|
||||||
OpCodeMessages getOpCommand(FILE *filePtr, OpCodeType *inData);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getNumberArg
|
|
||||||
Process: starts at given index, captures
|
|
||||||
and assembles int arg, returns as parameter
|
|
||||||
Function Input/Parameters: input str (const char *), starting index (int)
|
|
||||||
Function Output/Parameters: pointer to captured integer value
|
|
||||||
Function Output/Returned: updated index for next function start
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: isDigit
|
|
||||||
*/
|
|
||||||
int getNumberArg(int *number, const char *inputStr, int index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: getStringArg
|
|
||||||
Process: starts at given index, captures
|
|
||||||
and assembles str arg, returns as parameter
|
|
||||||
Function Input/Parameters: input str (const char *), starting index (int)
|
|
||||||
Function Output/Parameters: ptr to captured string argument (char *)
|
|
||||||
Function Output/Returned: updated index for next fct start
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
int getStringArg(char *strArg, const char *inputStr, int index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: isDigit
|
|
||||||
Process: tests character parameter for digit,
|
|
||||||
returns true if is digit, false otherwise
|
|
||||||
Function Input/Parameters: test character (char)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: bool result of test (bool)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
bool isDigit(char testChar);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: updateEndCount
|
|
||||||
Process: manages count of "end" arguments
|
|
||||||
to be compared at end of process input
|
|
||||||
Function Input/Parameters: initial count (int),
|
|
||||||
test string for "end" (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: updated count, if "end" string found,
|
|
||||||
otherwise no change
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
int updateEndCount(int count, const char *opString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: updateStartCount
|
|
||||||
Process: manages count of "start" arguments
|
|
||||||
to be compared at start of process input
|
|
||||||
Function Input/Parameters: initial count (int),
|
|
||||||
test string for "start" (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: updated count, if "start" string found,
|
|
||||||
otherwise no change
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
int updateStartCount(int count, const char *opString);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: verifyFirstStringArg
|
|
||||||
Process: checks for all possibilities of first argument string of op command
|
|
||||||
Function Input/Parameters: test string (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: bool result of test (bool)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
bool verifyFirstStringArg(const char *strArg);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: verifyValidCommand
|
|
||||||
Process: checks for all possibilities of three-letter opcode command
|
|
||||||
Function Input/Parameters: test string for command (const char *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: bool result of test (bool)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: compareString
|
|
||||||
*/
|
|
||||||
bool verifyValidCommand(char *testCmd);
|
|
||||||
|
|
||||||
#endif // METADATAOPS
|
|
||||||
BIN
Sim03/sim03
BIN
Sim03/sim03
Binary file not shown.
|
|
@ -1,32 +0,0 @@
|
||||||
CC = gcc -Wall -std=c99 -pedantic -g
|
|
||||||
SOURCES = StringUtils.c simulator.c metadataops.c configops.c OS_SimDriver.c simtimer.c
|
|
||||||
OBJECTS = OS_SimDriver.o simulator.o metadataops.o configops.o StringUtils.o simtimer.o
|
|
||||||
|
|
||||||
all: Simulator
|
|
||||||
|
|
||||||
Simulator: $(OBJECTS)
|
|
||||||
$(CC) $(OBJECTS) -o sim03
|
|
||||||
|
|
||||||
StringUtils.o: StringUtils.c
|
|
||||||
$(CC) -c StringUtils.c -o StringUtils.o
|
|
||||||
|
|
||||||
simulator.o: simulator.c
|
|
||||||
$(CC) -c simulator.c -o simulator.o
|
|
||||||
|
|
||||||
metadataops.o: metadataops.c
|
|
||||||
$(CC) -c metadataops.c -o metadataops.o
|
|
||||||
|
|
||||||
configops.o: configops.c
|
|
||||||
$(CC) -c configops.c -o configops.o
|
|
||||||
|
|
||||||
OS_SimDriver.o: OS_SimDriver.c
|
|
||||||
$(CC) -c OS_SimDriver.c -o OS_SimDriver.o
|
|
||||||
|
|
||||||
simtimer.o: simtimer.c
|
|
||||||
$(CC) -c simtimer.c -o simtimer.o
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJECTS) sim03 sim03.out
|
|
||||||
|
|
||||||
clean_objects:
|
|
||||||
rm -f $(OBJECTS)
|
|
||||||
233
Sim03/simtimer.c
233
Sim03/simtimer.c
|
|
@ -1,233 +0,0 @@
|
||||||
// Program Information ////////////////////////////////////////////////////////
|
|
||||||
/**
|
|
||||||
* @file SimpleTimer.c
|
|
||||||
*
|
|
||||||
* @brief Implementation file for using a timer with micro-second precision
|
|
||||||
*
|
|
||||||
* @author Michael Leverington
|
|
||||||
*
|
|
||||||
* @details Implements member methods for timing
|
|
||||||
*
|
|
||||||
* @version 3.00 (02 February 2017) Update to simulator timer
|
|
||||||
2.00 (13 January 2017) Update to C language
|
|
||||||
* 1.00 (11 September 2015)
|
|
||||||
*
|
|
||||||
* @Note Requires SimpleTimer.h.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Precompiler directives /////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef SIMTIMER_C
|
|
||||||
#define SIMTIMER_C
|
|
||||||
|
|
||||||
// Header files ///////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "simtimer.h"
|
|
||||||
|
|
||||||
// Constants /////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const char RADIX_POINT = '.';
|
|
||||||
const char SPACED = ' ';
|
|
||||||
|
|
||||||
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;
|
|
||||||
static int startSec = 0, endSec = 0, startUSec = 0, endUSec = 0;
|
|
||||||
static int lapSec = 0, lapUSec = 0;
|
|
||||||
struct timeval startData, lapData, endData;
|
|
||||||
double fpTime = 0.0;
|
|
||||||
|
|
||||||
switch( controlCode )
|
|
||||||
{
|
|
||||||
case ZERO_TIMER:
|
|
||||||
gettimeofday( &startData, NULL );
|
|
||||||
running = true;
|
|
||||||
|
|
||||||
startSec = startData.tv_sec;
|
|
||||||
startUSec = startData.tv_usec;
|
|
||||||
|
|
||||||
fpTime = 0.000000000;
|
|
||||||
lapSec = 0.000000000;
|
|
||||||
lapUSec = 0.000000000;
|
|
||||||
|
|
||||||
timeToString( lapSec, lapUSec, timeStr );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LAP_TIMER:
|
|
||||||
if( running == true )
|
|
||||||
{
|
|
||||||
gettimeofday( &lapData, NULL );
|
|
||||||
|
|
||||||
lapSec = lapData.tv_sec;
|
|
||||||
lapUSec = lapData.tv_usec;
|
|
||||||
|
|
||||||
fpTime = processTime( startSec, lapSec,
|
|
||||||
startUSec, lapUSec, timeStr );
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fpTime = 0.000000000;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STOP_TIMER:
|
|
||||||
if( running == true )
|
|
||||||
{
|
|
||||||
gettimeofday( &endData, NULL );
|
|
||||||
running = false;
|
|
||||||
|
|
||||||
endSec = endData.tv_sec;
|
|
||||||
endUSec = endData.tv_usec;
|
|
||||||
|
|
||||||
fpTime = processTime( startSec, endSec,
|
|
||||||
startUSec, endUSec, timeStr );
|
|
||||||
}
|
|
||||||
|
|
||||||
// assume timer not running
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fpTime = 0.000000000;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fpTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
double processTime( double startSec, double endSec,
|
|
||||||
double startUSec, double endUSec, char *timeStr )
|
|
||||||
{
|
|
||||||
double secDiff = endSec - startSec;
|
|
||||||
double uSecDiff = endUSec - startUSec;
|
|
||||||
double fpTime;
|
|
||||||
|
|
||||||
fpTime = (double) secDiff + (double) uSecDiff / 1000000;
|
|
||||||
|
|
||||||
if( uSecDiff < 0 )
|
|
||||||
{
|
|
||||||
uSecDiff = uSecDiff + 1000000;
|
|
||||||
secDiff = secDiff - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeToString( secDiff, uSecDiff, timeStr );
|
|
||||||
|
|
||||||
return fpTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This is a bit of a drawn-out function, but it is written
|
|
||||||
to force the time result to always be in the form x.xxxxxxx
|
|
||||||
when printed as a string; this will not always be the case
|
|
||||||
if the time is presented as a floating point number
|
|
||||||
*/
|
|
||||||
void timeToString( int secTime, int uSecTime, char *timeStr )
|
|
||||||
{
|
|
||||||
int low, high, index = 0;
|
|
||||||
char temp;
|
|
||||||
|
|
||||||
while( uSecTime > 0 )
|
|
||||||
{
|
|
||||||
timeStr[ index ] = (char) ( uSecTime % 10 + '0' );
|
|
||||||
uSecTime /= 10;
|
|
||||||
|
|
||||||
index++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
while( index < 6 )
|
|
||||||
{
|
|
||||||
timeStr[ index ] = '0';
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeStr[ index ] = RADIX_POINT;
|
|
||||||
|
|
||||||
index++;
|
|
||||||
|
|
||||||
if( secTime < 10 ) // single digit in display
|
|
||||||
{
|
|
||||||
timeStr[ index ] = (char) ( secTime % 10 + '0' );
|
|
||||||
|
|
||||||
index++;
|
|
||||||
|
|
||||||
timeStr[ index ] = SPACE;
|
|
||||||
|
|
||||||
index++;
|
|
||||||
|
|
||||||
secTime = 0;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if( secTime == 0 )
|
|
||||||
{
|
|
||||||
timeStr[ index ] = '0';
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
while( secTime > 0 )
|
|
||||||
{
|
|
||||||
timeStr[ index ] = (char) ( secTime % 10 + '0' );
|
|
||||||
|
|
||||||
secTime /= 10;
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeStr[ index ] = NULL_CHAR;
|
|
||||||
|
|
||||||
low = 0; high = index - 1;
|
|
||||||
|
|
||||||
while( low < high )
|
|
||||||
{
|
|
||||||
temp = timeStr[ low ];
|
|
||||||
timeStr[ low ] = timeStr[ high ];
|
|
||||||
timeStr[ high ] = temp;
|
|
||||||
|
|
||||||
low++; high--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ifndef SIMTIMER_C
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
// Program Information ////////////////////////////////////////////////////////
|
|
||||||
/**
|
|
||||||
* @file SimpleTimer.h
|
|
||||||
*
|
|
||||||
* @brief Header file for micro-second precision timer
|
|
||||||
*
|
|
||||||
* @author Michael Leverington
|
|
||||||
*
|
|
||||||
* @details Specifies all member methods of the SimpleTimer
|
|
||||||
*
|
|
||||||
* @version 2.00 (13 January 2017)
|
|
||||||
* 1.00 (11 September 2015)
|
|
||||||
*
|
|
||||||
* @Note None
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Precompiler directives /////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef SIMTIMER_H
|
|
||||||
#define SIMTIMER_H
|
|
||||||
|
|
||||||
// Header files ///////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include "OS_SimDriver.h"
|
|
||||||
|
|
||||||
// Global Constants //////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
enum TIMER_CTRL_CODES { ZERO_TIMER, LAP_TIMER, STOP_TIMER };
|
|
||||||
|
|
||||||
extern const char RADIX_POINT;
|
|
||||||
extern const char SPACED;
|
|
||||||
|
|
||||||
// Function Prototyp /////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void runTimer( int milliSeconds );
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// no more access needed beyond this point (supporting functions)
|
|
||||||
double processTime( double startSec, double endSec,
|
|
||||||
double startUSec, double endUSec, char *timeStr );
|
|
||||||
void timeToString( int secTime, int uSecTime, char *timeStr );
|
|
||||||
|
|
||||||
#endif // ifndef SIMTIMER_H
|
|
||||||
|
|
||||||
|
|
@ -1,791 +0,0 @@
|
||||||
#include "simulator.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: accessMemory
|
|
||||||
Process: checks offset from the PCB
|
|
||||||
Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none?
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
void accessMemory(ProcessControlBlock *singlePCB, int offset, int size)
|
|
||||||
{
|
|
||||||
// no return, void (temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: addProcess
|
|
||||||
Process: allocates the memory for the pcb, grabs the data from the created PCB,
|
|
||||||
dumps the data so that the node can be linked correctly.
|
|
||||||
Function Input/Parameters: source PCB (ProcessControlBlock)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: filled PCB (ProcessControlBlock *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: malloc, sizeof, ???
|
|
||||||
*/
|
|
||||||
ProcessControlBlock *addProcess(const ProcessControlBlock source)
|
|
||||||
{
|
|
||||||
// declare a pointer to working node
|
|
||||||
ProcessControlBlock *workingNode;
|
|
||||||
// make some space that the pointer is pointing to
|
|
||||||
workingNode = malloc(sizeof(ProcessControlBlock));
|
|
||||||
// get each value from the source, and set their values
|
|
||||||
workingNode->uniquePid = source.uniquePid;
|
|
||||||
workingNode->cpuCycles = source.cpuCycles;
|
|
||||||
workingNode->ioCycles = source.ioCycles;
|
|
||||||
workingNode->nextOpCode = source.nextOpCode;
|
|
||||||
workingNode->process_state = source.process_state;
|
|
||||||
workingNode->timeLeft = source.timeLeft;
|
|
||||||
workingNode->totalCycles = source.totalCycles;
|
|
||||||
// make sure to set the next pointer to NULL!
|
|
||||||
workingNode->nextPtr = NULL;
|
|
||||||
// return workingNode
|
|
||||||
return workingNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: allocMemory
|
|
||||||
Process: 'allocates' memory within the PCB, stores offset and size within it's PCB
|
|
||||||
Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none?
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
void allocMemory(ProcessControlBlock *singlePCB, int offset, int size)
|
|
||||||
{
|
|
||||||
// no return, void (temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: createProcessList
|
|
||||||
Process: reads through the opcode struct to fill out the linked list of PCBs
|
|
||||||
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: deallocMemory
|
|
||||||
Process: 'deallocates' memory within the PCB, removes offset and size within it's PCB
|
|
||||||
Function Input/Parameters: source PCB (ProcessControlBlock *), offset (int), size (int)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none?
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
void deallocMemory(ProcessControlBlock *singlePCB, int offset, int size)
|
|
||||||
{
|
|
||||||
// no return, void (temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: destroyProcessList
|
|
||||||
Process: deallocates memory used for the linked list struct
|
|
||||||
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.
|
|
||||||
Function Input/Parameters: metadata (OpCodeType *),
|
|
||||||
headPointer (ProcessControlBlockLL *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: pointer to filled PCB (ProcessControlBlockLL *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *metadataPtr, ProcessControlBlockLL *headPointer)
|
|
||||||
{
|
|
||||||
// initialize function/variables
|
|
||||||
// need a working pointer for the metadata
|
|
||||||
OpCodeType *wkgMetaPtr;
|
|
||||||
ProcessControlBlock currentPCB;
|
|
||||||
ProcessControlBlock *wkgPCBPtr;
|
|
||||||
OpCodeType *wkgInsPtr;
|
|
||||||
// need a variable to count how many IO cycles are in the process
|
|
||||||
int ioCycleCount = 0;
|
|
||||||
// need a variable to count how many CPU cycles are in the process
|
|
||||||
int cpuCycleCount = 0;
|
|
||||||
// need a variable to calculate the time left in ms for a process
|
|
||||||
double timeLeftCount = 0.0;
|
|
||||||
// need a variable that fills PIDs, starting at 0
|
|
||||||
int processId = 0;
|
|
||||||
// process variables?
|
|
||||||
char *command;
|
|
||||||
char *argument;
|
|
||||||
char *inOutArg;
|
|
||||||
int integerArgumentOne;
|
|
||||||
// unused as of current
|
|
||||||
//int integerArgumentTwo;
|
|
||||||
|
|
||||||
// set the working pointer to the first part of the metadata pointer
|
|
||||||
wkgMetaPtr = metadataPtr;
|
|
||||||
wkgInsPtr = metadataPtr;
|
|
||||||
// set another working pointer to the first part of the PCB list
|
|
||||||
wkgPCBPtr = headPointer->headPtr;
|
|
||||||
|
|
||||||
// grab the first command and argument
|
|
||||||
command = wkgMetaPtr->command;
|
|
||||||
argument = wkgMetaPtr->strArg1;
|
|
||||||
inOutArg = wkgMetaPtr->inOutArg;
|
|
||||||
|
|
||||||
// integer argument two is unused atm
|
|
||||||
//integerArgumentTwo = wkgMetaPtr->intArg3;
|
|
||||||
|
|
||||||
// loop through the process list, until you hit a sys end.
|
|
||||||
while(wkgMetaPtr != NULL && !(compareString(argument, "end") == EQUIV && compareString(command, "sys") == EQUIV))
|
|
||||||
{
|
|
||||||
currentPCB.nextOpCode = wkgInsPtr->nextNode;
|
|
||||||
integerArgumentOne = wkgMetaPtr->intArg2;
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
// count number of io cycles
|
|
||||||
if(compareString(command, "dev") == EQUIV)
|
|
||||||
{
|
|
||||||
integerArgumentOne = wkgMetaPtr->intArg2;
|
|
||||||
if(compareString(inOutArg, "in") == EQUIV)
|
|
||||||
{
|
|
||||||
// add up the IO cycle
|
|
||||||
ioCycleCount = ioCycleCount + integerArgumentOne;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// add up the IO cycle
|
|
||||||
ioCycleCount = ioCycleCount + integerArgumentOne;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// count number of cpu cycles
|
|
||||||
if ((compareString(argument, "process") == EQUIV && compareString(command, "cpu") == EQUIV))
|
|
||||||
{
|
|
||||||
integerArgumentOne = wkgMetaPtr->intArg2;
|
|
||||||
cpuCycleCount = cpuCycleCount + integerArgumentOne;
|
|
||||||
|
|
||||||
}
|
|
||||||
if ((compareString(argument, "end") == EQUIV && compareString(command, "app") == EQUIV))
|
|
||||||
{
|
|
||||||
// set the ioCycles from variable
|
|
||||||
currentPCB.ioCycles = ioCycleCount;
|
|
||||||
// set the cpuCycles from variable
|
|
||||||
currentPCB.cpuCycles = cpuCycleCount;
|
|
||||||
// set totalCycles from adding both IO/CPU
|
|
||||||
currentPCB.totalCycles = ioCycleCount + cpuCycleCount;
|
|
||||||
|
|
||||||
// currentPCB must have the starting instruction from wkgInsPtr
|
|
||||||
wkgInsPtr = wkgMetaPtr;
|
|
||||||
|
|
||||||
// set the time left from (ioCycles * ioCycleRate) + (cpuCycles * procCyclesRate)
|
|
||||||
// this gets the number of ms in the process.
|
|
||||||
timeLeftCount = (ioCycleCount * configPtr->ioCycleRate) + (cpuCycleCount * configPtr->procCycleRate);
|
|
||||||
currentPCB.timeLeft = timeLeftCount;
|
|
||||||
// increment the PID counter
|
|
||||||
processId = processId + 1;
|
|
||||||
|
|
||||||
ioCycleCount = 0;
|
|
||||||
cpuCycleCount = 0;
|
|
||||||
timeLeftCount = 0.0;
|
|
||||||
// needs to add nodes to the end and all data once parsed
|
|
||||||
// do both the metadata and PCBs
|
|
||||||
if(headPointer->headPtr == NULL)
|
|
||||||
{
|
|
||||||
headPointer->headPtr = addProcess(currentPCB);
|
|
||||||
wkgPCBPtr = headPointer->headPtr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wkgPCBPtr->nextPtr = addProcess(currentPCB);
|
|
||||||
wkgPCBPtr = wkgPCBPtr->nextPtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// move to the next bit of data
|
|
||||||
wkgMetaPtr = wkgMetaPtr->nextNode;
|
|
||||||
command = wkgMetaPtr->command;
|
|
||||||
argument = wkgMetaPtr->strArg1;
|
|
||||||
inOutArg = wkgMetaPtr->inOutArg;
|
|
||||||
|
|
||||||
}
|
|
||||||
// return headPointer
|
|
||||||
return headPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: findMin
|
|
||||||
Process: compares two values, returns the smaller of the two.
|
|
||||||
Function Input/Parameters: two integer values (int)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: minimum of the two input integer values (int)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
int findMin(int one, int another)
|
|
||||||
{
|
|
||||||
int minimumVal = one;
|
|
||||||
if(another < minimumVal)
|
|
||||||
{
|
|
||||||
minimumVal = another;
|
|
||||||
}
|
|
||||||
// return zero(temp)
|
|
||||||
return minimumVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: logOutput
|
|
||||||
Process: Takes in a string, and then outputs it to monitor AND/OR 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: fprintf, ???
|
|
||||||
*/
|
|
||||||
void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
// switch case for each memory code
|
|
||||||
switch (memCode)
|
|
||||||
{
|
|
||||||
case MEMORY_INITIALIZE:
|
|
||||||
/* code */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MEMORY_ALLOCATE:
|
|
||||||
/* code */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MEMORY_ACCESS:
|
|
||||||
/* code */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MEMORY_DEALLOCATE:
|
|
||||||
/* code */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// no return, void (temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: runCPU
|
|
||||||
Process: runs the CPU operations for however long it takes
|
|
||||||
Function Input/Parameters: ???
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: pthreads, sprintf, logOutput, ???
|
|
||||||
*/
|
|
||||||
void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId)
|
|
||||||
{
|
|
||||||
char timeStringy[MAX_STR_LEN];
|
|
||||||
// char *command = workingMeta->command;
|
|
||||||
// char *argument = workingMeta->strArg1;
|
|
||||||
// int intArg = workingMeta->intArg2;
|
|
||||||
char cpuOutput[MAX_STR_LEN];
|
|
||||||
int cpuTime = 0;
|
|
||||||
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);
|
|
||||||
// run timer for intArg * procCycleRate
|
|
||||||
pthread_t cpuThread;
|
|
||||||
pthread_create(&cpuThread, NULL, (void *)&simThread, (void *)cpuTime);
|
|
||||||
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);
|
|
||||||
// pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: runIO
|
|
||||||
Process: runs the IO operations for however long it takes
|
|
||||||
Function Input/Parameters: ???
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: pthreads, sprintf, logOutput, ???
|
|
||||||
*/
|
|
||||||
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId)
|
|
||||||
{
|
|
||||||
char timeStringy[MAX_STR_LEN];
|
|
||||||
char ioOutput[MAX_STR_LEN];
|
|
||||||
int ioTime = 0;
|
|
||||||
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);
|
|
||||||
pthread_t ioThread;
|
|
||||||
pthread_create(&ioThread, NULL, (void *)&simThread, (void *)ioTime);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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: accessTimer, compareString, runCPU, runIO, ???
|
|
||||||
*/
|
|
||||||
void runProcess(ProcessControlBlock *singlePCB, ConfigDataType *configPtr)
|
|
||||||
{
|
|
||||||
// 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];
|
|
||||||
// grab the next operation code for the
|
|
||||||
OpCodeType *workingMeta = singlePCB->nextOpCode;
|
|
||||||
char *command;
|
|
||||||
char *argument;
|
|
||||||
int intArg;
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
if(compareString(command, "dev") == EQUIV)
|
|
||||||
{
|
|
||||||
// run IO operations for the required amount of time.
|
|
||||||
runIO(workingMeta->command, workingMeta->strArg1, workingMeta->intArg2, configPtr, singlePCB->uniquePid);
|
|
||||||
}
|
|
||||||
workingMeta = workingMeta->nextNode;
|
|
||||||
command = workingMeta->command;
|
|
||||||
argument = workingMeta->strArg1;
|
|
||||||
intArg = workingMeta->intArg2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
// initialize function/variables
|
|
||||||
// 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;
|
|
||||||
ProcessControlBlock *pcbPtr;
|
|
||||||
// string variable for nextCode, temp unused
|
|
||||||
// char *nextCode;
|
|
||||||
// string variable for the timer stuff
|
|
||||||
char simulatorOutput[MAX_STR_LEN];
|
|
||||||
char timeStringy[MAX_STR_LEN];
|
|
||||||
int processCount = 0;
|
|
||||||
int processIterator;
|
|
||||||
|
|
||||||
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
|
|
||||||
int currentPid;
|
|
||||||
// create the process list with createProcessList, store the pointed to address
|
|
||||||
pcbList = createProcessList();
|
|
||||||
// fill the process list given the metadata
|
|
||||||
pcbList = fillProcessList(configPtr, metaDataMstrPtr, pcbList);
|
|
||||||
pcbPtr = pcbList->headPtr;
|
|
||||||
|
|
||||||
// calculate pcb total time, number of processes
|
|
||||||
int totalPCBTime = 0;
|
|
||||||
while(pcbPtr != NULL)
|
|
||||||
{
|
|
||||||
totalPCBTime = totalPCBTime + pcbPtr->timeLeft;
|
|
||||||
pcbPtr = pcbPtr->nextPtr;
|
|
||||||
processCount = processCount + 1;
|
|
||||||
}
|
|
||||||
pcbPtr = pcbList->headPtr;
|
|
||||||
|
|
||||||
pthread_t cpuThread;
|
|
||||||
pthread_create(&cpuThread, NULL, (void *)&simThread, (void *)totalPCBTime);
|
|
||||||
|
|
||||||
//
|
|
||||||
int processTimeLeft = pcbPtr->timeLeft;
|
|
||||||
|
|
||||||
// set the current process id to the first scheduled process
|
|
||||||
currentPid = scheduleProcess(pcbList, configPtr);
|
|
||||||
// loop until current process is hit
|
|
||||||
// while(pcbPtr->process_state != PROCESS_STATE_TERMINATED && pcbPtr != NULL && processCount != 0)
|
|
||||||
// {
|
|
||||||
// if(pcbPtr->uniquePid == currentPid)
|
|
||||||
// {
|
|
||||||
// // needs to set from READY to RUNNING
|
|
||||||
// pcbPtr->process_state = PROCESS_STATE_RUNNING;
|
|
||||||
// sprintf(simulatorOutput, "%f, OS: Process %d set to RUNNING state from READY state\n\n", accessTimer(LAP_TIMER, timeStringy), pcbPtr->uniquePid);
|
|
||||||
// logOutput(configPtr, simulatorOutput, false);
|
|
||||||
// pthread_t runThread;
|
|
||||||
// pthread_create(&runThread, NULL, (void *)&simThread, (void *)processTimeLeft);
|
|
||||||
// runProcess(pcbPtr, configPtr);
|
|
||||||
// // when finished, set to terminated
|
|
||||||
// sprintf(simulatorOutput, "%f, OS: Process %d set to TERMINATED state from RUNNING state\n\n", accessTimer(LAP_TIMER, timeStringy), pcbPtr->uniquePid);
|
|
||||||
// logOutput(configPtr, simulatorOutput, false);
|
|
||||||
// pcbPtr->process_state = PROCESS_STATE_TERMINATED;
|
|
||||||
// processCount = processCount - 1;
|
|
||||||
// pthread_join(runThread, NULL);
|
|
||||||
// }
|
|
||||||
// processTimeLeft = pcbPtr->timeLeft;
|
|
||||||
// pcbPtr = pcbPtr->nextPtr;
|
|
||||||
// currentPid = scheduleProcess(pcbList, configPtr);
|
|
||||||
// if(configPtr->cpuSchedCode == CPU_SCHED_SJF_N_CODE && pcbPtr == NULL)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// pcbPtr = pcbList->headPtr;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
for(processIterator = 0; processIterator < processCount; processIterator++)
|
|
||||||
{
|
|
||||||
while (pcbPtr != NULL)
|
|
||||||
{
|
|
||||||
// printf("Current Process Number is: %d\n", pcbPtr->uniquePid);
|
|
||||||
// printf("Process Status is: %d\n", pcbPtr->process_state);
|
|
||||||
// printf("Scheduled Process is: %d\n", currentPid);
|
|
||||||
if (pcbPtr->process_state != PROCESS_STATE_TERMINATED && 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;
|
|
||||||
pthread_join(runThread, NULL);
|
|
||||||
}
|
|
||||||
processTimeLeft = pcbPtr->timeLeft;
|
|
||||||
pcbPtr = pcbPtr->nextPtr;
|
|
||||||
}
|
|
||||||
currentPid = scheduleProcess(pcbList, configPtr);
|
|
||||||
pcbPtr = pcbList->headPtr;
|
|
||||||
}
|
|
||||||
pthread_join(cpuThread, NULL);
|
|
||||||
sprintf(simulatorOutput, "%f, OS: System Stop\n", accessTimer(LAP_TIMER, timeStringy));
|
|
||||||
logOutput(configPtr, simulatorOutput, false);
|
|
||||||
sprintf(simulatorOutput, "%f, OS: Simulation End\n", accessTimer(LAP_TIMER, timeStringy));
|
|
||||||
logOutput(configPtr, simulatorOutput, true);
|
|
||||||
// deallocate the process list with destroyProcessList
|
|
||||||
destroyProcessList(pcbList);
|
|
||||||
// once complete, log the output to FILE if required
|
|
||||||
logOutput(configPtr, "", true);
|
|
||||||
// pthread_exit(NULL); // this line seems to make the program execution stop short... no warning either
|
|
||||||
// void function, no return.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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 *),
|
|
||||||
configuration data (ConfigDataType *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: sprintf, logOutput, ???
|
|
||||||
*/
|
|
||||||
int scheduleProcess(ProcessControlBlockLL *headPointer, ConfigDataType *configPtr)
|
|
||||||
{
|
|
||||||
ProcessControlBlock *wkgPtr;
|
|
||||||
int returnPid = -1;
|
|
||||||
wkgPtr = headPointer->headPtr;
|
|
||||||
char loggingStr[MAX_STR_LEN];
|
|
||||||
char timeStringy[MAX_STR_LEN];
|
|
||||||
int processCount = 0;
|
|
||||||
|
|
||||||
while (wkgPtr != NULL)
|
|
||||||
{
|
|
||||||
if(wkgPtr->process_state != PROCESS_STATE_TERMINATED)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
processCount = processCount + 1;
|
|
||||||
}
|
|
||||||
wkgPtr = wkgPtr->nextPtr;
|
|
||||||
}
|
|
||||||
wkgPtr = headPointer->headPtr;
|
|
||||||
|
|
||||||
// switch case for each scheduling algorithm
|
|
||||||
switch (configPtr->cpuSchedCode)
|
|
||||||
{
|
|
||||||
case CPU_SCHED_FCFS_N_CODE:
|
|
||||||
// First Come, First Served, Non-preemptive Scheduling
|
|
||||||
// need to find whichever process is first, AND the state is NEW.
|
|
||||||
// will set the state to READY, return the pid of the process which
|
|
||||||
// was set to ready.
|
|
||||||
|
|
||||||
// set every process in the list to READY from NEW
|
|
||||||
while(wkgPtr != NULL)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
if(wkgPtr->process_state == PROCESS_STATE_NEW)
|
|
||||||
{
|
|
||||||
// set the process within the PCB to the ready state, report in ready state.
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
// move to the next pointer
|
|
||||||
wkgPtr = wkgPtr->nextPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset the pointer to get ready for selection of process
|
|
||||||
wkgPtr = headPointer->headPtr;
|
|
||||||
while(wkgPtr != NULL && (returnPid == -1))
|
|
||||||
{
|
|
||||||
// check if the process is NOT terminated
|
|
||||||
if (wkgPtr->process_state != PROCESS_STATE_RUNNING && wkgPtr->process_state != PROCESS_STATE_TERMINATED)
|
|
||||||
{
|
|
||||||
//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);
|
|
||||||
returnPid = wkgPtr->uniquePid;
|
|
||||||
}
|
|
||||||
// move to next pointer
|
|
||||||
wkgPtr = wkgPtr->nextPtr;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CPU_SCHED_FCFS_P_CODE:
|
|
||||||
// TODO: First Come, First Served, Preemptive Scheduling
|
|
||||||
break;
|
|
||||||
case CPU_SCHED_RR_P_CODE:
|
|
||||||
// TODO: Round Robin Scheduling
|
|
||||||
break;
|
|
||||||
case CPU_SCHED_SJF_N_CODE:
|
|
||||||
// Shortest Job First Scheduling
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
if (wkgPtr->process_state == PROCESS_STATE_NEW)
|
|
||||||
{
|
|
||||||
// set the process within the PCB to the ready state, report in ready state.
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
// move to the next pointer
|
|
||||||
wkgPtr = wkgPtr->nextPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset the pointer to get ready for selection of process
|
|
||||||
wkgPtr = headPointer->headPtr;
|
|
||||||
// load in the first process time
|
|
||||||
shortestJob = wkgPtr->timeLeft;
|
|
||||||
// move to the next pointer.
|
|
||||||
wkgPtr = wkgPtr->nextPtr;
|
|
||||||
while (wkgPtr != NULL && (returnPid == -1))
|
|
||||||
{
|
|
||||||
// check if the process is NOT terminated
|
|
||||||
// now, ALSO needs to check which process takes the least time.
|
|
||||||
if (wkgPtr->process_state != PROCESS_STATE_RUNNING && wkgPtr->process_state != PROCESS_STATE_TERMINATED)
|
|
||||||
{
|
|
||||||
// check to see if the working pointer job is shorter than the current shortest job
|
|
||||||
shortestJob = findMin(shortestJob, wkgPtr->timeLeft);
|
|
||||||
// check to see if the shortest job time changed, if it did, change the process number
|
|
||||||
if(shortestJob == wkgPtr->timeLeft)
|
|
||||||
{
|
|
||||||
// change process number, or leave it unchanged.
|
|
||||||
shortestJobProcNum = wkgPtr->uniquePid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// move to next pointer
|
|
||||||
wkgPtr = wkgPtr->nextPtr;
|
|
||||||
}
|
|
||||||
// check the number of processes, if there is one left, then
|
|
||||||
wkgPtr = headPointer->headPtr;
|
|
||||||
if(processCount == 1)
|
|
||||||
{
|
|
||||||
// find the last process that is READY but not TERMINATED, set it's PID as the return.
|
|
||||||
while(wkgPtr != NULL)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
if (wkgPtr->process_state != PROCESS_STATE_TERMINATED)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
shortestJobProcNum = wkgPtr->uniquePid;
|
|
||||||
shortestJob = wkgPtr->timeLeft;
|
|
||||||
}
|
|
||||||
wkgPtr = wkgPtr->nextPtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(processCount != 0)
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
returnPid = shortestJobProcNum;
|
|
||||||
break;
|
|
||||||
case CPU_SCHED_SRTF_P_CODE:
|
|
||||||
// TODO: Shortest Run-time First Scheduling
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// return returnPid
|
|
||||||
return returnPid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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: pthreads, runTimer
|
|
||||||
*/
|
|
||||||
void *simThread(int milSec)
|
|
||||||
{
|
|
||||||
runTimer(milSec);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
@ -1,231 +0,0 @@
|
||||||
#ifndef SIMULATORX
|
|
||||||
#define SIMULATORX
|
|
||||||
|
|
||||||
#include "StandardConstants.h"
|
|
||||||
#include "configops.h"
|
|
||||||
#include "metadataops.h"
|
|
||||||
#include "simtimer.h"
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
// data structures
|
|
||||||
|
|
||||||
typedef enum{
|
|
||||||
PROCESS_STATE_NEW = 0,
|
|
||||||
PROCESS_STATE_READY,
|
|
||||||
PROCESS_STATE_RUNNING,
|
|
||||||
PROCESS_STATE_BLOCKED,
|
|
||||||
PROCESS_STATE_TERMINATED
|
|
||||||
} PROCESS_STATES;
|
|
||||||
|
|
||||||
typedef enum{
|
|
||||||
MEMORY_INITIALIZE = 0,
|
|
||||||
MEMORY_ACCESS,
|
|
||||||
MEMORY_ALLOCATE,
|
|
||||||
MEMORY_DEALLOCATE
|
|
||||||
} MEMORY_SIGNALS;
|
|
||||||
|
|
||||||
typedef struct ProcessControlBlockStruct
|
|
||||||
{
|
|
||||||
int uniquePid;
|
|
||||||
PROCESS_STATES process_state;
|
|
||||||
// need a process start ptr for where the process starts.
|
|
||||||
// this will be a mini loop within the master loop that goes until it
|
|
||||||
// hits the app end command.
|
|
||||||
// it may hold the next opcode, since you don't need to traverse backward
|
|
||||||
OpCodeType *nextOpCode;
|
|
||||||
// have an IO cycle count here
|
|
||||||
int ioCycles;
|
|
||||||
// have a CPU cycle count here
|
|
||||||
int cpuCycles;
|
|
||||||
// maybe have a total cycle count here
|
|
||||||
int totalCycles;
|
|
||||||
// time left could be calculated from these.
|
|
||||||
// potentially could change the cycles or have a 'left' variable to
|
|
||||||
// see how many are left.
|
|
||||||
// also need a time left state here?
|
|
||||||
double timeLeft;
|
|
||||||
// allocated memory array (stores the offsets)
|
|
||||||
int *allocatedMemOffsets;
|
|
||||||
// allocated memory array sizes (stores the sizes for each offset)
|
|
||||||
int *allocatedMemSizes;
|
|
||||||
// connect to the next process control block here
|
|
||||||
struct ProcessControlBlockStruct *nextPtr;
|
|
||||||
} ProcessControlBlock;
|
|
||||||
|
|
||||||
typedef struct ProcessControlBlockLLStruct
|
|
||||||
{
|
|
||||||
// holds the head ptr for PCBs
|
|
||||||
ProcessControlBlock *headPtr;
|
|
||||||
} ProcessControlBlockLL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: ???
|
|
||||||
Process: ???
|
|
||||||
Function Input/Parameters: ???
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: ???
|
|
||||||
Process: ???
|
|
||||||
Function Input/Parameters: ???
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: addProcess
|
|
||||||
Process: allocates the memory for the pcb, grabs the data from the created PCB,
|
|
||||||
dumps the data so that the node can be linked correctly.
|
|
||||||
Function Input/Parameters: source PCB (ProcessControlBlock)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: filled PCB (ProcessControlBlock *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: malloc, sizeof, ???
|
|
||||||
*/
|
|
||||||
ProcessControlBlock *addProcess(const ProcessControlBlock source);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: createProcessList
|
|
||||||
Process: initializes head pointer to the 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();
|
|
||||||
|
|
||||||
/*
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: fillProcessList
|
|
||||||
Process: iterates through the metadata LL, fills out each process as needed.
|
|
||||||
Function Input/Parameters: metadata (OpCodeType *),
|
|
||||||
headPointer (ProcessControlBlockLL *)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: pointer to filled PCB (ProcessControlBlockLL *)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
ProcessControlBlockLL *fillProcessList(ConfigDataType *configPtr, OpCodeType *metadataPtr, ProcessControlBlockLL *headPointer);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: findMin
|
|
||||||
Process: compares two values, returns the smaller of the two.
|
|
||||||
Function Input/Parameters: two integer values (int)
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: minimum of the two input integer values (int)
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: none
|
|
||||||
*/
|
|
||||||
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 *),
|
|
||||||
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, ???
|
|
||||||
*/
|
|
||||||
void logOutput(ConfigDataType *configPtr, char *logStr, bool isEnd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: runCPU
|
|
||||||
Process: runs the CPU operations for however long it takes
|
|
||||||
Function Input/Parameters: ???
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
void runCPU(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Name: runIO
|
|
||||||
Process: runs the IO operations for however long it takes
|
|
||||||
Function Input/Parameters: ???
|
|
||||||
Function Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
void runIO(char *command, char *argument, int intArg, ConfigDataType *configPtr, int processId);
|
|
||||||
/*
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
|
||||||
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 Output/Parameters: none
|
|
||||||
Function Output/Returned: none
|
|
||||||
Device Input/Device: none
|
|
||||||
Device Output/Device: none
|
|
||||||
Dependencies: ???
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
#endif // SIMULATORX
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
Start Program Meta-Data Code:
|
|
||||||
|
|
||||||
# starting the master loop
|
|
||||||
sys start
|
|
||||||
|
|
||||||
# process 0 start
|
|
||||||
app start, 0
|
|
||||||
# process 0 I/O (run HDD for 18 cycles)
|
|
||||||
dev in, hard drive, 18
|
|
||||||
# process 0 CPU (run CPU for 9 cycles 3 times)
|
|
||||||
cpu process, 9
|
|
||||||
cpu process, 9
|
|
||||||
cpu process, 9
|
|
||||||
# process 0 I/O (run monitor for 60 cycles)
|
|
||||||
dev out, monitor, 60
|
|
||||||
# process 0 end
|
|
||||||
app end
|
|
||||||
|
|
||||||
# P0 total cycles ran: 105
|
|
||||||
|
|
||||||
# process 1 start
|
|
||||||
app start, 0
|
|
||||||
# process 1 I/O (run sound for 40 cycles, HDD for 30 cycles, sound for 25 cycles)
|
|
||||||
dev in, sound signal, 40
|
|
||||||
dev in, hard drive, 30
|
|
||||||
dev in, sound signal, 25
|
|
||||||
# process 1 CPU (run CPU for 6 cycles)
|
|
||||||
cpu process, 6
|
|
||||||
# process 1 I/O (run USB for 10 cycles)
|
|
||||||
dev out, usb, 10
|
|
||||||
# process 1 end
|
|
||||||
app end
|
|
||||||
|
|
||||||
# P1 total cycles ran: 111
|
|
||||||
|
|
||||||
# process 2 start
|
|
||||||
app start, 0
|
|
||||||
# process 2 I/O (run video for 70 cycles)
|
|
||||||
dev in, video signal, 70
|
|
||||||
# process 2 CPU (run CPU for 10 cycles)
|
|
||||||
cpu process, 10
|
|
||||||
# process 2 I/O (run monitor for 70 cycles, HDD for 18 cycles)
|
|
||||||
dev out, monitor, 70
|
|
||||||
dev in, hard drive, 18
|
|
||||||
# process 2 CPU (run CPU for 9 cycles)
|
|
||||||
cpu process, 9
|
|
||||||
# process 2 end
|
|
||||||
app end
|
|
||||||
|
|
||||||
# P2 total cycles ran: 177
|
|
||||||
|
|
||||||
# process 3 start
|
|
||||||
app start, 0
|
|
||||||
# process 3 I/O (run sound for 35 cycles, monitor for 100 cycles, keyboard for 50 cycles)
|
|
||||||
dev in, sound signal, 35
|
|
||||||
dev out, monitor, 100
|
|
||||||
dev in, keyboard, 50
|
|
||||||
# process 3 CPU (run CPU for 9 cycles)
|
|
||||||
cpu process, 9
|
|
||||||
# process 3 I/O (run video for 49 cycles)
|
|
||||||
dev out, video signal, 49
|
|
||||||
# process 3 end
|
|
||||||
app end
|
|
||||||
|
|
||||||
# P3 total cycles ran: 243
|
|
||||||
|
|
||||||
# process 4 start
|
|
||||||
app start, 0
|
|
||||||
# process 4 I/O (run keyboard for 90 cycles, sound for 40 cycles, serial for 32 cycles)
|
|
||||||
dev in, keyboard, 90
|
|
||||||
dev out, sound signal, 40
|
|
||||||
dev out, serial, 32
|
|
||||||
# process 4 CPU (run CPU for 10 cycles)
|
|
||||||
cpu process, 10
|
|
||||||
# process 4 I/O (run HDD for 15 cycles)
|
|
||||||
dev in, hard drive, 15
|
|
||||||
# process 4 end
|
|
||||||
app end
|
|
||||||
|
|
||||||
# P4 total cycles ran: 187
|
|
||||||
|
|
||||||
# master loop ends
|
|
||||||
sys end
|
|
||||||
|
|
||||||
End Program Meta-Data Code.
|
|
||||||
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
Start Simulator Configuration File:
|
|
||||||
Version/Phase : 1.00
|
|
||||||
File Path : testfile.mdf
|
|
||||||
CPU Scheduling Code : FCFS-N
|
|
||||||
Quantum Time (cycles) : 55
|
|
||||||
Memory Available (KB) : 12000
|
|
||||||
Memory Display (On/Off) : On
|
|
||||||
Processor Cycle Time (msec) : 10
|
|
||||||
I/O Cycle Time (msec) : 20
|
|
||||||
Log To : Monitor
|
|
||||||
Log File Path : logfile_1.lgf
|
|
||||||
End Simulator Configuration File.
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
Start Program Meta-Data Code:
|
|
||||||
sys start
|
|
||||||
app start, 0
|
|
||||||
dev in, hard drive, 18
|
|
||||||
cpu process, 9
|
|
||||||
cpu process, 9
|
|
||||||
cpu process, 9
|
|
||||||
dev out, monitor, 60
|
|
||||||
app end
|
|
||||||
app start, 0
|
|
||||||
dev in, sound signal, 40
|
|
||||||
dev in, hard drive, 30
|
|
||||||
dev in, sound signal, 25
|
|
||||||
cpu process, 6
|
|
||||||
dev out, usb, 10
|
|
||||||
app end
|
|
||||||
app start, 0
|
|
||||||
dev in, video signal, 70
|
|
||||||
cpu process, 10
|
|
||||||
dev out, monitor, 70
|
|
||||||
dev in, hard drive, 18
|
|
||||||
cpu process, 9
|
|
||||||
app end
|
|
||||||
app start, 0
|
|
||||||
dev in, sound signal, 35
|
|
||||||
dev out, monitor, 100
|
|
||||||
dev in, keyboard, 50
|
|
||||||
cpu process, 9
|
|
||||||
dev out, video signal, 49
|
|
||||||
app end
|
|
||||||
app start, 0
|
|
||||||
dev in, keyboard, 90
|
|
||||||
dev out, sound signal, 40
|
|
||||||
dev out, serial, 32
|
|
||||||
cpu process, 10
|
|
||||||
dev in, hard drive, 15
|
|
||||||
app end
|
|
||||||
sys end
|
|
||||||
End Program Meta-Data Code.
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue