Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / profile.h
1 #ifndef _IPXE_PROFILE_H
2 #define _IPXE_PROFILE_H
3
4 /** @file
5  *
6  * Profiling
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER );
11
12 #include <bits/profile.h>
13 #include <ipxe/tables.h>
14
15 #ifdef NDEBUG
16 #define PROFILING 0
17 #else
18 #define PROFILING 1
19 #endif
20
21 /**
22  * A data structure for storing profiling information
23  */
24 struct profiler {
25         /** Name */
26         const char *name;
27         /** Start timestamp */
28         unsigned long started;
29         /** Stop timestamp */
30         unsigned long stopped;
31         /** Number of samples */
32         unsigned int count;
33         /** Mean sample value (scaled) */
34         unsigned long mean;
35         /** Mean sample value MSB
36          *
37          * This is the highest bit set in the raw (unscaled) value
38          * (i.e. one less than would be returned by flsl(raw_mean)).
39          */
40         unsigned int mean_msb;
41         /** Accumulated variance (scaled) */
42         unsigned long long accvar;
43         /** Accumulated variance MSB
44          *
45          * This is the highest bit set in the raw (unscaled) value
46          * (i.e. one less than would be returned by flsll(raw_accvar)).
47          */
48         unsigned int accvar_msb;
49 };
50
51 /** Profiler table */
52 #define PROFILERS __table ( struct profiler, "profilers" )
53
54 /** Declare a profiler */
55 #if PROFILING
56 #define __profiler __table_entry ( PROFILERS, 01 )
57 #else
58 #define __profiler
59 #endif
60
61 extern unsigned long profile_excluded;
62
63 extern void profile_update ( struct profiler *profiler, unsigned long sample );
64 extern unsigned long profile_mean ( struct profiler *profiler );
65 extern unsigned long profile_variance ( struct profiler *profiler );
66 extern unsigned long profile_stddev ( struct profiler *profiler );
67
68 /**
69  * Get start time
70  *
71  * @v profiler          Profiler
72  * @ret started         Start time
73  */
74 static inline __attribute__ (( always_inline )) unsigned long
75 profile_started ( struct profiler *profiler ) {
76
77         /* If profiling is active then return start time */
78         if ( PROFILING ) {
79                 return ( profiler->started + profile_excluded );
80         } else {
81                 return 0;
82         }
83 }
84
85 /**
86  * Get stop time
87  *
88  * @v profiler          Profiler
89  * @ret stopped         Stop time
90  */
91 static inline __attribute__ (( always_inline )) unsigned long
92 profile_stopped ( struct profiler *profiler ) {
93
94         /* If profiling is active then return start time */
95         if ( PROFILING ) {
96                 return ( profiler->stopped + profile_excluded );
97         } else {
98                 return 0;
99         }
100 }
101
102 /**
103  * Get elapsed time
104  *
105  * @v profiler          Profiler
106  * @ret elapsed         Elapsed time
107  */
108 static inline __attribute__ (( always_inline )) unsigned long
109 profile_elapsed ( struct profiler *profiler ) {
110
111         /* If profiling is active then return elapsed time */
112         if ( PROFILING ) {
113                 return ( profile_stopped ( profiler ) -
114                          profile_started ( profiler ) );
115         } else {
116                 return 0;
117         }
118 }
119
120 /**
121  * Start profiling
122  *
123  * @v profiler          Profiler
124  * @v started           Start timestamp
125  */
126 static inline __attribute__ (( always_inline )) void
127 profile_start_at ( struct profiler *profiler, unsigned long started ) {
128
129         /* If profiling is active then record start timestamp */
130         if ( PROFILING )
131                 profiler->started = ( started - profile_excluded );
132 }
133
134 /**
135  * Stop profiling
136  *
137  * @v profiler          Profiler
138  * @v stopped           Stop timestamp
139  */
140 static inline __attribute__ (( always_inline )) void
141 profile_stop_at ( struct profiler *profiler, unsigned long stopped ) {
142
143         /* If profiling is active then record end timestamp and update stats */
144         if ( PROFILING ) {
145                 profiler->stopped = ( stopped - profile_excluded );
146                 profile_update ( profiler, profile_elapsed ( profiler ) );
147         }
148 }
149
150 /**
151  * Start profiling
152  *
153  * @v profiler          Profiler
154  */
155 static inline __attribute__ (( always_inline )) void
156 profile_start ( struct profiler *profiler ) {
157
158         /* If profiling is active then record start timestamp */
159         if ( PROFILING )
160                 profile_start_at ( profiler, profile_timestamp() );
161 }
162
163 /**
164  * Stop profiling
165  *
166  * @v profiler          Profiler
167  */
168 static inline __attribute__ (( always_inline )) void
169 profile_stop ( struct profiler *profiler ) {
170
171         /* If profiling is active then record end timestamp and update stats */
172         if ( PROFILING )
173                 profile_stop_at ( profiler, profile_timestamp() );
174 }
175
176 /**
177  * Exclude time from other ongoing profiling results
178  *
179  * @v profiler          Profiler
180  */
181 static inline __attribute__ (( always_inline )) void
182 profile_exclude ( struct profiler *profiler ) {
183
184         /* If profiling is active then update accumulated excluded time */
185         if ( PROFILING )
186                 profile_excluded += profile_elapsed ( profiler );
187 }
188
189 #endif /* _IPXE_PROFILE_H */