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.

Personal tools