Created
January 12, 2012 16:17
-
-
Save bmnick/1601394 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/****************************************************************************** | |
* Module (there is no .c file, only this header) to provide timing | |
* instrumentation macros. The timing instrumentation macros can be | |
* globally enabled and controlled as using the EN TIME macro. This macro | |
* can be defined or un-defined within a source code file (even within this | |
* file). If this is done then the timers cannot be controlled from the | |
* compiler command line. Since it will often be the case that the | |
* application would be built with and without the timers it is recommended | |
* that the EN TIME macro *not* be defined or un-defined directly in the | |
* source code. Instead, by using the “-D” command line option to gcc (as | |
* in “gcc -DEN TIME ...”) the timers can be enabled as needed. A compiler | |
* warning will be issued when the timers are enabled. All timer output is | |
* performed to stderr. | |
******************************************************************************/ | |
#ifndef _TIMERS_H | |
#define _TIMERS_H | |
/****************************************************************************** | |
* It is important that the user know that the timers are enabled when the | |
* code is compiled. The following pre-processor code issues a warning and | |
* includes the necessary system header files when the timers are enabled. | |
******************************************************************************/ | |
#if defined(EN_TIME) | |
#include <stdio.h> | |
#include <time.h> | |
#if defined(WARNING_MSG) | |
#warning Timers enabled! Execution could be adversly effected. | |
#endif | |
#endif | |
/****************************************************************************** | |
* The time instrumentation macro definitions. If EN TIME is *not* defined | |
* the macros are defined as null comments to allow the code to correctly | |
* compiled and to ensure that the timers have no effect on program | |
* execution. Proper use of the macros require that the timer be declared | |
* before used and that the declaration occur at the same scope as the use | |
* of timer (or globally as may be necessary when instrumenting functions | |
* and printing timing results elsewhere). The timer should be stopped | |
* before being printed (although a running timer will be stopped | |
* automatically just prior to being printed). The timer need not be | |
* explicitely started (the implied starting point is the same as the | |
* declaration if the timer is not explicitely started). All timers | |
* declared at the same level of scope must have unique names. Previously | |
* stopped timers must be started in order to accumulate time values across | |
* multiple stop/run sessions, restarting a timer is performed only to | |
* re-stablish the starting point. | |
******************************************************************************/ | |
#if defined(EN_TIME) | |
/**************************************************************************** | |
* Declare the timer. Initialize the timer (particularly the accumulated | |
* elapsed time and the timer state). | |
****************************************************************************/ | |
#define DECLARE_TIMER(A) \ | |
struct { \ | |
/* Start Time - set when the timer is started */ \ | |
clock t Start; \ | |
/* Stop Time - set when the timer is stopped */ \ | |
clock t Stop; \ | |
/* Elapsed Time - Accumulated when the timer is stopped */ \ | |
clock t Elapsed; \ | |
/* Timer State - Set automatically: 0=stopped / 1=running */ \ | |
int State; \ | |
} A = { /* Elapsed Time and State must be initialized to zero */\ | |
/* Start = */ 0, \ | |
/* Stop = */ 0, \ | |
/* Elapsed = */ 0, \ | |
/* State = */ 0, \ | |
}; /* Timer has been declared and defined */ | |
/**************************************************************************** | |
* Start the timer. Print an error if it is already running, set the state | |
* to running and then start the timer. | |
****************************************************************************/ | |
#define START_TIMER(A) \ | |
{ \ | |
/* It is an error if the timer is currently running */ \ | |
if (1 == A.State) \ | |
fprintf(stderr, "Error, running timer "#A" started.\n"); \ | |
/* Set the state to running */ \ | |
A.State = 1; \ | |
/* Set the start time, done last to maximize accuracy */ \ | |
A.Start = clock(); \ | |
} /* START TIMER() */ | |
/**************************************************************************** | |
* Reset the timer. Clear the elapsed time. | |
****************************************************************************/ | |
#define RESET_TIMER(A) \ | |
{ \ | |
/* Reset the elapsed time to zero */ \ | |
A.Elapsed = 0; \ | |
} /* RESET TIMER() */ | |
/**************************************************************************** | |
* Stop the timer. Set the stop time, print an error message if the timer | |
* is already stopped otherwise accumulate the elapsed time (works for | |
* both one-time and repeating timing operations), set the state to | |
* stopped. | |
****************************************************************************/ | |
#define STOP_TIMER(A) \ | |
{ \ | |
/* Set the stop time, done first to maximize accuracy */ \ | |
A.Stop = clock(); \ | |
/* It is an error if the timer is currently stopped */ \ | |
if (0 == A.State) \ | |
fprintf(stderr, "Error, stopped timer "#A" stopped again.\n"); \ | |
else /* accumulate running total only if previously running */ \ | |
A.Elapsed += A.Stop − A.Start; \ | |
/* Set the state to stopped */ \ | |
A.State = 0; \ | |
} /* STOP TIMER() */ | |
/**************************************************************************** | |
* Print the timer. Check the timer state and stop it if necessary, print | |
* the elapsed time (in seconds). | |
****************************************************************************/ | |
#define PRINT TIMER(A) \ | |
{ \ | |
/* Stop the timer (silently) if it is currently running */ \ | |
if (1 == A.State) \ | |
STOP TIMER(A); /* no error possible in this case */ \ | |
fprintf(stderr, "Elapsed CPU Time ("#A") = %g sec.\n", \ | |
(double)A.Elapsed / (double)CLOCKS PER SEC); \ | |
} /*PRINT TIMER() */ | |
#else /* not defined(EN TIME) */ | |
/* Declare null macros for error-free compilation */ | |
#define DECLARE TIMER(A) /* Null Macro */ | |
#define START TIMER(A) /* Null Macro */ | |
#define RESET TIMER(A) /* Null Macro */ | |
#define STOP TIMER(A) /* Null Macro */ | |
#define PRINT TIMER(A) /* Null Macro */ | |
#endif /* defined(EN TIME) */ | |
#endif /* TIMERS H */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment