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