// 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 * runTimerThread( void *timerThreadDataPtr )// void *milliSeconds ) { threadInfo *timerThreadData = (( threadInfo * )timerThreadDataPtr); 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; //fprintf( stderr, "thread still running\n" ); //fprintf( stderr, "milliseconds:\t%ld\n", (timerThreadData->milliseconds) ); while( timeDiff < (timerThreadData->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; // fprintf( stderr, "secDiff:\t%d\tmSecDiff:\t%d\n", secDiff, mSecDiff ); timeDiff = secDiff + mSecDiff; //pthread_mutex_lock( &( timerThreadData->mutex ) ); timeToString( secDiff, mSecDiff, timerThreadData->timeString ); //pthread_mutex_unlock( &( timerThreadData->mutex ) ); } return NULL; // temporary stub return } 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 ) { 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 ) { gettimeofday( &endData, NULL ); //running = false; endSec = endData.tv_sec; endUSec = endData.tv_usec; fpTime = processTime( startSec, endSec, startUSec, endUSec, timeStr ); } case GET_TIME: running = true; fpTime = processTime( startSec, lapSec, startUSec, lapUSec, timeStr ); break; // // 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