]> mj.ucw.cz Git - libucw.git/blob - lib/profile.h
fixed missing includes
[libucw.git] / lib / profile.h
1 /*
2  *      Sherlock Library -- Poor Man's Profiler
3  *
4  *      (c) 2001 Martin Mares <mj@ucw.cz>
5  */
6
7 /*
8  *  Usage:
9  *              #define PROFILE_xxx
10  *              #include "lib/profile.h"
11  *              prof_t cnt;
12  *              prof_init(&cnt);
13  *              ...
14  *              prof_start(&cnt);
15  *              ...
16  *              prof_stop(&cnt);
17  *              printf("%s\n", PROF_STRING(&cnt));
18  */
19
20 #include <string.h>
21
22 /* PROFILE_TOD: gettimeofday() profiler */
23
24 struct prof_tod {
25   u32 start_sec, start_usec;
26   s32 sec, usec;
27 };
28
29 void prof_tod_init(struct prof_tod *);
30 void prof_tod_switch(struct prof_tod *, struct prof_tod *);
31 int prof_tod_format(char *, struct prof_tod *);
32
33 /* PROFILE_TSC: i386 TSC profiler */
34
35 #ifdef CPU_I386
36
37 struct prof_tsc {
38   u64 start_tsc;
39   u64 ticks;
40 };
41
42 void prof_tsc_init(struct prof_tsc *);
43 int prof_tsc_format(char *, struct prof_tsc *);
44
45 #endif
46
47 /* PROFILE_KTSC: Linux kernel TSC profiler */
48
49 #ifdef CONFIG_LINUX
50
51 struct prof_ktsc {
52   u64 start_user, start_sys;
53   u64 ticks_user, ticks_sys;
54 };
55
56 void prof_ktsc_init(struct prof_ktsc *);
57 void prof_ktsc_switch(struct prof_ktsc *, struct prof_ktsc *);
58 int prof_ktsc_format(char *, struct prof_ktsc *);
59
60 #endif
61
62 /* Select the right profiler */
63
64 #if defined(PROFILE_TOD)
65
66 #define PROFILER
67 #define PROF_STR_SIZE 21
68 typedef struct prof_tod prof_t;
69 #define prof_init prof_tod_init
70 #define prof_switch prof_tod_switch
71 #define prof_format prof_tod_format
72
73 #elif defined(PROFILE_TSC)
74
75 #define PROFILER
76 #define PROFILER_INLINE
77 #define PROF_STR_SIZE 24
78
79 typedef struct prof_tsc prof_t;
80 #define prof_init prof_tsc_init
81 #define prof_format prof_tsc_format
82
83 #define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
84
85 static inline void prof_start(prof_t *c)
86 {
87   rdtscll(c->start_tsc);
88 }
89
90 static inline void prof_stop(prof_t *c)
91 {
92   u64 tsc;
93   rdtscll(tsc);
94   tsc -= c->start_tsc;
95   c->ticks += tsc;
96 }
97
98 static inline void prof_switch(prof_t *o, prof_t *n)
99 {
100   u64 tsc;
101   rdtscll(tsc);
102   n->start_tsc = tsc;
103   tsc -= o->start_tsc;
104   o->ticks += tsc;
105 }
106
107 #elif defined(PROFILE_KTSC)
108
109 #define PROFILER
110 #define PROF_STR_SIZE 50
111 typedef struct prof_ktsc prof_t;
112 #define prof_init prof_ktsc_init
113 #define prof_switch prof_ktsc_switch
114 #define prof_format prof_ktsc_format
115
116 #endif
117
118 #ifdef PROFILER
119
120 /* Stuff common for all profilers */
121 #ifndef PROFILER_INLINE
122 static inline void prof_start(prof_t *c) { prof_switch(NULL, c); }
123 static inline void prof_stop(prof_t *c) { prof_switch(c, NULL); }
124 #endif
125 #define PROF_STR(c) ({ static byte _x[PROF_STR_SIZE]; prof_format(_x, &(C)); _x })
126
127 #else
128
129 /* Dummy profiler with no output */
130 typedef struct { } prof_t;
131 static inline void prof_init(prof_t *c UNUSED) { }
132 static inline void prof_start(prof_t *c UNUSED) { }
133 static inline void prof_stop(prof_t *c UNUSED) { }
134 static inline void prof_switch(prof_t *c UNUSED, prof_t *d UNUSED) { }
135 static inline void prof_format(char *b, prof_t *c UNUSED) { strcpy(b, "?"); }
136 #define PROF_STR_SIZE 2
137
138 #endif