Gperf-simple.c revision 29f2f89a8fc3cd7f103fb7ed7e1c9f79adfd59b8
1#include <stdio.h>
2#include <stdlib.h>
3
4#include <sys/time.h>
5
6#include <libunwind.h>
7
8#define panic(args...)							  \
9	do { fprintf (stderr, args); exit (-1); } while (0)
10
11static inline double
12gettime (void)
13{
14  struct timeval tv;
15
16  gettimeofday(&tv, NULL);
17  return tv.tv_sec + 1e-6*tv.tv_usec;
18}
19
20static int
21measure_unwind (int maxlevel)
22{
23  double stop, mid, start;
24  unw_cursor_t cursor;
25  unw_context_t uc;
26  int ret, level = 0;
27
28  start = gettime ();
29
30  unw_getcontext (&uc);
31  if (unw_init_local (&cursor, &uc) < 0)
32    panic ("unw_init_local() failed\n");
33
34  mid = gettime ();
35
36  do
37    {
38      ret = unw_step (&cursor);
39      if (ret < 0)
40	panic ("unw_step() failed\n");
41      ++level;
42    }
43  while (ret > 0);
44
45  stop = gettime ();
46
47  if (level <= maxlevel)
48    panic ("Unwound only %d levels, expected at least %d levels",
49	   level, maxlevel);
50
51  printf ("initialization time = %gnsec, time per unwind-step = %gnsec\n",
52	  1e9*(mid - start), 1e9*(stop - mid)/level);
53  return 0;
54}
55
56static int
57f1 (int level, int maxlevel)
58{
59  if (level == maxlevel)
60    return measure_unwind (maxlevel);
61  else
62    /* defeat last-call/sibcall optimization */
63    return f1 (level + 1, maxlevel) + level;
64}
65
66int
67main (int argc, char **argv)
68{
69  int i, maxlevel = 100;
70
71  if (argc > 1)
72    maxlevel = atol (argv[1]);
73
74  for (i = 0; i < 20; ++i)
75    f1 (0, maxlevel);
76  return 0;
77}
78