blob: 0bc2389eaf028bcd11cea9d9aaaa8788e0c3a164 [file] [log] [blame]
mostang.com!davidm12876ef2003-09-24 05:02:14 +00001#include <stdio.h>
2#include <stdlib.h>
3
4#include <sys/time.h>
5
6#include <libunwind.h>
7
hp.com!davidm5e446b22003-11-27 06:52:54 +00008#define ITERATIONS 10000
9
mostang.com!davidm12876ef2003-09-24 05:02:14 +000010#define panic(args...) \
11 do { fprintf (stderr, args); exit (-1); } while (0)
12
hp.com!davidm5e446b22003-11-27 06:52:54 +000013static int maxlevel = 100;
14
mostang.com!davidm12876ef2003-09-24 05:02:14 +000015static inline double
16gettime (void)
17{
18 struct timeval tv;
19
20 gettimeofday(&tv, NULL);
21 return tv.tv_sec + 1e-6*tv.tv_usec;
22}
23
24static int
hp.com!davidm5e446b22003-11-27 06:52:54 +000025measure_unwind (int maxlevel, double *init, double *step)
mostang.com!davidm12876ef2003-09-24 05:02:14 +000026{
27 double stop, mid, start;
28 unw_cursor_t cursor;
29 unw_context_t uc;
30 int ret, level = 0;
31
32 start = gettime ();
33
34 unw_getcontext (&uc);
35 if (unw_init_local (&cursor, &uc) < 0)
36 panic ("unw_init_local() failed\n");
37
38 mid = gettime ();
39
40 do
41 {
42 ret = unw_step (&cursor);
43 if (ret < 0)
44 panic ("unw_step() failed\n");
45 ++level;
46 }
47 while (ret > 0);
48
49 stop = gettime ();
50
51 if (level <= maxlevel)
52 panic ("Unwound only %d levels, expected at least %d levels",
53 level, maxlevel);
54
hp.com!davidm5e446b22003-11-27 06:52:54 +000055 *init = mid - start;
56 *step = (stop - mid) / (double) level;
hp.com!davidm29f2f892003-09-25 05:29:14 +000057 return 0;
mostang.com!davidm12876ef2003-09-24 05:02:14 +000058}
59
60static int
hp.com!davidm5e446b22003-11-27 06:52:54 +000061f1 (int level, int maxlevel, double *init, double *step)
mostang.com!davidm12876ef2003-09-24 05:02:14 +000062{
63 if (level == maxlevel)
hp.com!davidm5e446b22003-11-27 06:52:54 +000064 return measure_unwind (maxlevel, init, step);
mostang.com!davidm12876ef2003-09-24 05:02:14 +000065 else
66 /* defeat last-call/sibcall optimization */
hp.com!davidm5e446b22003-11-27 06:52:54 +000067 return f1 (level + 1, maxlevel, init, step) + level;
68}
69
70static void
71doit (const char *label)
72{
73 double init, step, min_init, first_init, min_step, first_step, sum_init, sum_step;
74 int i;
75
76 sum_init = sum_step = first_init = first_step = 0.0;
77 min_init = min_step = 1e99;
78 for (i = 0; i < ITERATIONS; ++i)
79 {
80 f1 (0, maxlevel, &init, &step);
81
82 sum_init += init;
83 sum_step += step;
84
85 if (init < min_init)
86 min_init = init;
87 if (step < min_step)
88 min_step = step;
89
90 if (i == 0)
91 {
92 first_init = init;
93 first_step = step;
94 }
95 }
96 printf ("%s:\n"
97 " unw_{getcontext+init_local}: first=%9.3f min=%9.3f avg=%9.3f nsec\n"
98 " unw_step : first=%9.3f min=%9.3f avg=%9.3f nsec\n",
99 label,
100 1e9*first_init, 1e9*min_init, 1e9*sum_init/ITERATIONS,
101 1e9*first_step, 1e9*min_step, 1e9*sum_step/ITERATIONS);
mostang.com!davidm12876ef2003-09-24 05:02:14 +0000102}
103
104int
105main (int argc, char **argv)
106{
mostang.com!davidm12876ef2003-09-24 05:02:14 +0000107 if (argc > 1)
108 maxlevel = atol (argv[1]);
109
mostang.com!davidm7a346fb2003-11-20 01:10:03 +0000110 unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE);
hp.com!davidm5e446b22003-11-27 06:52:54 +0000111 doit ("Caching: none");
mostang.com!davidm7a346fb2003-11-20 01:10:03 +0000112
mostang.com!davidm7a346fb2003-11-20 01:10:03 +0000113 unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL);
hp.com!davidm5e446b22003-11-27 06:52:54 +0000114 doit ("Caching: global");
mostang.com!davidm7a346fb2003-11-20 01:10:03 +0000115
mostang.com!davidm7a346fb2003-11-20 01:10:03 +0000116 unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
hp.com!davidm5e446b22003-11-27 06:52:54 +0000117 doit ("Caching: per-thread");
118
mostang.com!davidm12876ef2003-09-24 05:02:14 +0000119 return 0;
120}