Started outlining the CS480 Simulator 2 project, analyzed a testfile, and added SimTimer stuff
++ simtimer.c/h ++ testfile-dnw.mdf +- simulator.c/h -- Sim01 Grading
This commit is contained in:
parent
460705a9e1
commit
93904cb2f3
6 changed files with 415 additions and 3 deletions
Binary file not shown.
231
Sim02/simtimer.c
Normal file
231
Sim02/simtimer.c
Normal file
|
|
@ -0,0 +1,231 @@
|
||||||
|
// 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 = '.';
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double accessTimer( int controlCode, char *timeStr )
|
||||||
|
{
|
||||||
|
static Boolean 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
45
Sim02/simtimer.h
Normal file
45
Sim02/simtimer.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
// 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 SPACE;
|
||||||
|
|
||||||
|
// Function Prototyp /////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void runTimer( int milliSeconds );
|
||||||
|
double accessTimer( int controlCode, char *timeStr );
|
||||||
|
double processTime( double startSec, double endSec,
|
||||||
|
double startUSec, double endUSec, char *timeStr );
|
||||||
|
void timeToString( int secTime, int uSecTime, char *timeStr );
|
||||||
|
|
||||||
|
#endif // ifndef SIMTIMER_H
|
||||||
|
|
||||||
|
|
@ -15,6 +15,29 @@ Dependencies: ???
|
||||||
*/
|
*/
|
||||||
void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
|
void runSim(ConfigDataType *configPtr, OpCodeType *metaDataMstrPtr)
|
||||||
{
|
{
|
||||||
|
// initialize function/variables
|
||||||
|
// need a FILE * for file operations
|
||||||
|
// need two working pointers, one for master loop, one for internal loop
|
||||||
|
// currentTime variable that stores the time.
|
||||||
|
// create the process list with createProcessList
|
||||||
|
// function holds master loop, loops until sys end opcode found OR PCB List != NULL
|
||||||
|
// will have a loop that goes from app start to app end for a PCB
|
||||||
|
// (checks to see if the next instruction is NOT app end), using getNextProcess?
|
||||||
|
// this will getNextOpCode
|
||||||
|
// this will checkForIO and run the IO operations, outputting to FILE * and/or monitor
|
||||||
|
// checkForIO will need the FILE * passed, will need timer access, and ???
|
||||||
|
// this will checkForCPU and run the CPU operations, outputting to FILE * and/or monitor
|
||||||
|
// checkForCPU will need the FILE * passed, will need timer access, and ???
|
||||||
|
//
|
||||||
|
// deallocate the process list with destroyProcessList
|
||||||
printf("runSim called here");
|
printf("runSim called here");
|
||||||
// void function, no return.
|
// void function, no return.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getNextProcess/scheduler/dispatcher run here, loads/"runs" the process
|
||||||
|
// getNextOpCode, not needed for Sim02 apparently, keep in mind.
|
||||||
|
// checkForIO, I think this gets passed the current process and runs the IO ops
|
||||||
|
// checkForCPU, I think this gets passed the current process and runs the CPU ops
|
||||||
|
// checkForMemory, I think this gets passed the current process
|
||||||
|
// and runs mem ops (not needed for Sim02)
|
||||||
|
// cpuIdler (not needed for Sim02)
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "StandardConstants.h"
|
#include "StandardConstants.h"
|
||||||
#include "configops.h"
|
#include "configops.h"
|
||||||
#include "metadataops.h"
|
#include "metadataops.h"
|
||||||
|
#include "simtimer.h"
|
||||||
|
|
||||||
// data structures
|
// data structures
|
||||||
|
|
||||||
|
|
@ -19,7 +20,17 @@ typedef struct ProcessControlBlockStruct
|
||||||
{
|
{
|
||||||
int uniquePid;
|
int uniquePid;
|
||||||
PROCESS_STATES process_state;
|
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
|
||||||
|
// have an IO cycle count here
|
||||||
|
// have a CPU cycle count here
|
||||||
|
// maybe have a total cycle count here
|
||||||
|
// 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?
|
||||||
} ProcessControlBlock;
|
} ProcessControlBlock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -33,6 +44,9 @@ Device Output/Device: none
|
||||||
Dependencies: ???
|
Dependencies: ???
|
||||||
*/
|
*/
|
||||||
// need a function (or functions) to handle FILE I/O?
|
// need a function (or functions) to handle FILE I/O?
|
||||||
|
// runSim function will have a FILE *
|
||||||
|
// will have a function that gets the FILE * and
|
||||||
|
// adds whatever operation occurred
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Name: ???
|
Name: ???
|
||||||
|
|
@ -44,7 +58,20 @@ Device Input/Device: none
|
||||||
Device Output/Device: none
|
Device Output/Device: none
|
||||||
Dependencies: ???
|
Dependencies: ???
|
||||||
*/
|
*/
|
||||||
// need a function to ???
|
// need a function for the global/local timer (given??? may need to just import)
|
||||||
|
|
||||||
|
// need a function for scheduler/dispatcher
|
||||||
|
// this could use a switch statement to tell which scheduling method to choose from.
|
||||||
|
// Sim02 only requires FCFS working atm.
|
||||||
|
|
||||||
|
// need a function called createProcessList
|
||||||
|
// this makes a linked list of PCBs, loads the first instruction after app start
|
||||||
|
// and ...
|
||||||
|
|
||||||
|
// need a function called destroyProcessList
|
||||||
|
// deallocated the ll of PCBs recursively, frees the rest of the struct.
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Name: runSim
|
Name: runSim
|
||||||
|
|
|
||||||
86
Sim02/testfile-dnw.mdf
Normal file
86
Sim02/testfile-dnw.mdf
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
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.
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue