From ThirdMartini
I have been playing around with some gcc attribute functionality recently ( Specifically the cleanup attribute ) and had an interesting idea. Often times I've needed to be able to time how long a function took to execute. I've done this in the past using a couple of custom functions and calling them at the start and finish of said function. But cleanup makes it a bit easier.
The sample code below creates a generic function timer, and all that is needed to use it is to add a TIME_FUNCTION; call after your variable definitions. The timing and reporting is taken care of for you.
Sample Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned long long uint64_t;
typedef struct func_time_s{
uint64_t start;
const char *name;
}func_time_t;
void
timerStart(func_time_t *tf, const char *name)
{
struct timeval tm;
gettimeofday(&tm, NULL);
tf->start = (tm.tv_sec * 1000000) + tm.tv_usec;
tf->name = name;
}
void
timerStop(func_time_t * tf)
{
struct timeval tm;
uint64_t elapsed;
gettimeofday(&tm, NULL);
elapsed = ((tm.tv_sec * 1000000) + tm.tv_usec) - tf->start;
printf("%s: elapsed %llu\n", tf->name, elapsed);
}
#define TIME_FUNCTION func_time_t tm __attribute__ ((cleanup(timerStop))); timerStart(&tm, __FUNCTION__);
void func_f1()
{
int counter;
int loop;
TIME_FUNCTION;
for (loop=0; loop<2;loop++) {
sleep(1);
}
}
int main(void)
{
func_f1();
}
Running the function will yield:
./a.out func_f1: elapsed 2000123
The magic comes from the __attribute__ ((cleanup(timerStop))) line. When this stack variable leaves context/scope, our cleanup function will be called for us. This in turn just prints the time difference before the scope is destroyed.