iPXE
profile.h File Reference

Profiling. More...

#include <bits/profile.h>
#include <ipxe/tables.h>

Go to the source code of this file.

Data Structures

struct  profiler
 A data structure for storing profiling information. More...

Macros

#define PROFILING   1
#define PROFILERS   __table ( struct profiler, "profilers" )
 Profiler table.
#define __profiler
 Declare a profiler.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
unsigned long profile_timestamp (void)
void profile_update (struct profiler *profiler, unsigned long sample)
 Update profiler with a new sample.
unsigned long profile_mean (struct profiler *profiler)
 Get mean sample value.
unsigned long profile_variance (struct profiler *profiler)
 Get sample variance.
unsigned long profile_stddev (struct profiler *profiler)
 Get sample standard deviation.
static unsigned long profile_started (struct profiler *profiler)
 Get start time.
static unsigned long profile_stopped (struct profiler *profiler)
 Get stop time.
static unsigned long profile_elapsed (struct profiler *profiler)
 Get elapsed time.
static void profile_start_at (struct profiler *profiler, unsigned long started)
 Start profiling.
static void profile_stop_at (struct profiler *profiler, unsigned long stopped)
 Stop profiling.
static void profile_start (struct profiler *profiler)
 Start profiling.
static void profile_stop (struct profiler *profiler)
 Stop profiling.
static void profile_exclude (struct profiler *profiler)
 Exclude time from other ongoing profiling results.
static void profile_custom (struct profiler *profiler, unsigned long sample)
 Record profiling sample in custom units.

Variables

unsigned long profile_excluded
 Accumulated time excluded from profiling.

Detailed Description

Profiling.

Definition in file profile.h.

Macro Definition Documentation

◆ PROFILING

◆ PROFILERS

#define PROFILERS   __table ( struct profiler, "profilers" )

Profiler table.

Definition at line 55 of file profile.h.

Referenced by profstat().

◆ __profiler

struct undinet_profiler undinet_misc_profiler __profiler
Value:
=
{ .name = "xferbuf.write" }

Declare a profiler.

PXENV_UNDI_ISR profiler.

PXENV_UNDI_TRANSMIT profiler.

Virtual call profiler.

Real-mode call profiler.

Real-to-protected mode transition profiler.

Other interrupt profiler.

Miscellaneous PXE API call profiler.

PXE unknown API call profiler.

PXENV_UNDI_ISR API call profiler.

Transfer event profiler.

Event ring profiler.

Stream transfer profiler.

VM event profiler.

VM transmit profiler.

Bulk IN per-datagram profiler.

VM poll profiler.

VM receive refill profiler.

Bulk OUT profiler.

Bulk IN completion profiler.

Server profiler.

Data transfer profiler.

PeerDist block download discovery timeout profiler.

PeerDist block download discovery success profiler.

PeerDist block download attempt timeout profiler.

PeerDist block download attempt failure profiler.

PeerDist block download attempt success profiler.

Network transmit profiler.

Network receive profiler.

Receive profiler.

Post receive work queue entry profiler.

Data read profiler.

Data write profiler.

This profiler can be used to measure the overhead of a dummy PXE API call.

Note that this profiler will not see calls to PXENV_UNDI_ISR_IN_START, which are handled by the UNDI ISR and do not go via undinet_call().

Definition at line 61 of file profile.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ profile_timestamp()

unsigned long profile_timestamp ( void )

◆ profile_update()

void profile_update ( struct profiler * profiler,
unsigned long sample )
extern

Update profiler with a new sample.

Parameters
profilerProfiler
sampleSample value

Definition at line 111 of file profile.c.

111 {
112 unsigned int sample_msb;
113 unsigned int mean_shift;
114 unsigned int delta_shift;
115 signed long pre_delta;
116 signed long post_delta;
117 signed long long accvar_delta;
118 unsigned int accvar_delta_shift;
119 unsigned int accvar_delta_msb;
120 unsigned int accvar_shift;
121
122 /* Our scaling logic assumes that sample values never overflow
123 * a signed long (i.e. that the high bit is always zero).
124 */
125 assert ( ( ( signed ) sample ) >= 0 );
126
127 /* Update sample count, limiting to avoid signed overflow */
128 if ( profiler->count < INT_MAX )
129 profiler->count++;
130
131 /* Adjust mean sample value scale if necessary. Skip if
132 * sample is zero (in which case flsl(sample)-1 would
133 * underflow): in the case of a zero sample we have no need to
134 * adjust the scale anyway.
135 */
136 if ( sample ) {
137 sample_msb = ( flsl ( sample ) - 1 );
138 if ( profiler->mean_msb < sample_msb ) {
139 profiler->mean >>= ( sample_msb - profiler->mean_msb );
140 profiler->mean_msb = sample_msb;
141 }
142 }
143
144 /* Scale sample to internal units */
145 mean_shift = profile_mean_shift ( profiler );
146 sample <<= mean_shift;
147
148 /* Update mean */
149 pre_delta = ( sample - profiler->mean );
150 profiler->mean += ( pre_delta / ( ( signed ) profiler->count ) );
151 post_delta = ( sample - profiler->mean );
152 delta_shift = mean_shift;
153 DBGC ( profiler, "PROFILER %p sample %#lx mean %s", profiler,
154 ( sample >> mean_shift ),
155 profile_hex_fraction ( profiler->mean, mean_shift ) );
156 DBGC ( profiler, " pre %s",
157 profile_hex_fraction ( pre_delta, delta_shift ) );
158 DBGC ( profiler, " post %s\n",
159 profile_hex_fraction ( post_delta, delta_shift ) );
160
161 /* Scale both deltas to fit in half of an unsigned long long
162 * to avoid potential overflow on multiplication. Note that
163 * shifting a signed quantity is "implementation-defined"
164 * behaviour in the C standard, but gcc documents that it will
165 * always perform sign extension.
166 */
167 if ( sizeof ( pre_delta ) > ( sizeof ( accvar_delta ) / 2 ) ) {
168 unsigned int shift = ( 8 * ( sizeof ( pre_delta ) -
169 ( sizeof ( accvar_delta ) / 2 ) ));
170 pre_delta >>= shift;
171 post_delta >>= shift;
172 delta_shift -= shift;
173 }
174
175 /* Update variance, if applicable. Skip if either delta is
176 * zero (in which case flsl(delta)-1 would underflow): in the
177 * case of a zero delta there is no change to the accumulated
178 * variance anyway.
179 */
180 if ( pre_delta && post_delta ) {
181
182 /* Calculate variance delta */
183 accvar_delta = ( ( ( signed long long ) pre_delta ) *
184 ( ( signed long long ) post_delta ) );
185 accvar_delta_shift = ( 2 * delta_shift );
186 assert ( accvar_delta > 0 );
187
188 /* Calculate variance delta MSB, using flsl() on each
189 * delta individually to provide an upper bound rather
190 * than requiring the existence of flsll().
191 */
192 accvar_delta_msb = ( flsll ( accvar_delta ) - 1 );
193 if ( accvar_delta_msb > accvar_delta_shift ) {
194 accvar_delta_msb -= accvar_delta_shift;
195 } else {
196 accvar_delta_msb = 0;
197 }
198
199 /* Adjust scales as necessary */
200 if ( profiler->accvar_msb < accvar_delta_msb ) {
201 /* Rescale accumulated variance */
202 profiler->accvar >>= ( accvar_delta_msb -
204 profiler->accvar_msb = accvar_delta_msb;
205 } else {
206 /* Rescale variance delta */
207 accvar_delta >>= ( profiler->accvar_msb -
208 accvar_delta_msb );
209 accvar_delta_shift -= ( profiler->accvar_msb -
210 accvar_delta_msb );
211 }
212
213 /* Scale delta to internal units */
214 accvar_shift = profile_accvar_shift ( profiler );
215 accvar_delta <<= ( accvar_shift - accvar_delta_shift );
216
217 /* Accumulate variance */
218 profiler->accvar += accvar_delta;
219
220 /* Adjust scale if necessary */
221 if ( profiler->accvar &
222 ( 1ULL << ( ( 8 * sizeof ( profiler->accvar ) ) - 1 ) ) ) {
223 profiler->accvar >>= 1;
225 accvar_delta >>= 1;
226 accvar_shift--;
227 }
228
229 DBGC ( profiler, "PROFILER %p accvar %s", profiler,
230 profile_hex_fraction ( profiler->accvar, accvar_shift ));
231 DBGC ( profiler, " delta %s\n",
232 profile_hex_fraction ( accvar_delta, accvar_shift ) );
233 }
234}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define DBGC(...)
Definition compiler.h:505
#define flsll(x)
Find last (i.e.
Definition strings.h:149
#define flsl(x)
Find last (i.e.
Definition strings.h:158
#define INT_MAX
Definition limits.h:30
static unsigned int profile_accvar_shift(struct profiler *profiler)
Calculate bit shift for accumulated variance value.
Definition profile.c:98
static const char * profile_hex_fraction(signed long long value, unsigned int shift)
Format a hex fraction (for debugging)
Definition profile.c:59
static unsigned int profile_mean_shift(struct profiler *profiler)
Calculate bit shift for mean sample value.
Definition profile.c:85
A data structure for storing profiling information.
Definition profile.h:27
unsigned int count
Number of samples.
Definition profile.h:35
unsigned long mean
Mean sample value (scaled)
Definition profile.h:37
unsigned long long accvar
Accumulated variance (scaled)
Definition profile.h:45
unsigned int mean_msb
Mean sample value MSB.
Definition profile.h:43
unsigned int accvar_msb
Accumulated variance MSB.
Definition profile.h:51

References profiler::accvar, profiler::accvar_msb, assert, profiler::count, DBGC, flsl, flsll, INT_MAX, profiler::mean, profiler::mean_msb, profile_accvar_shift(), profile_hex_fraction(), and profile_mean_shift().

Referenced by profile_custom(), profile_okx(), and profile_stop_at().

◆ profile_mean()

unsigned long profile_mean ( struct profiler * profiler)
extern

Get mean sample value.

Parameters
profilerProfiler
Return values
meanMean sample value

Definition at line 242 of file profile.c.

242 {
243 unsigned int mean_shift = profile_mean_shift ( profiler );
244
245 /* Round to nearest and scale down to original units */
246 return ( ( profiler->mean + ( 1UL << ( mean_shift - 1 ) ) )
247 >> mean_shift );
248}

References profiler::mean, and profile_mean_shift().

Referenced by cipher_cost(), digest_cost(), memcpy_test_speed(), profile_okx(), profstat(), and tcpip_random_okx().

◆ profile_variance()

unsigned long profile_variance ( struct profiler * profiler)
extern

Get sample variance.

Parameters
profilerProfiler
Return values
varianceSample variance

Definition at line 256 of file profile.c.

256 {
257 unsigned int accvar_shift = profile_accvar_shift ( profiler );
258
259 /* Variance is zero if fewer than two samples exist (avoiding
260 * division by zero error).
261 */
262 if ( profiler->count < 2 )
263 return 0;
264
265 /* Calculate variance, round to nearest, and scale to original units */
266 return ( ( ( profiler->accvar / ( profiler->count - 1 ) )
267 + ( 1ULL << ( accvar_shift - 1 ) ) ) >> accvar_shift );
268}

References profiler::accvar, profiler::count, and profile_accvar_shift().

Referenced by profile_stddev().

◆ profile_stddev()

unsigned long profile_stddev ( struct profiler * profiler)
extern

Get sample standard deviation.

Parameters
profilerProfiler
Return values
stddevSample standard deviation

Definition at line 276 of file profile.c.

276 {
277
278 return isqrt ( profile_variance ( profiler ) );
279}
unsigned long isqrt(unsigned long value)
Find integer square root.
Definition isqrt.c:41
unsigned long profile_variance(struct profiler *profiler)
Get sample variance.
Definition profile.c:256

References isqrt(), and profile_variance().

Referenced by memcpy_test_speed(), profile_okx(), profstat(), and tcpip_random_okx().

◆ profile_started()

unsigned long profile_started ( struct profiler * profiler)
inlinestatic

Get start time.

Parameters
profilerProfiler
Return values
startedStart time

Definition at line 80 of file profile.h.

80 {
81
82 /* If profiling is active then return start time */
83 if ( PROFILING ) {
84 return ( profiler->started + profile_excluded );
85 } else {
86 return 0;
87 }
88}
#define PROFILING
Definition profile.h:20
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition profile.c:50
unsigned long started
Start timestamp.
Definition profile.h:31

References profile_excluded, PROFILING, and profiler::started.

Referenced by profile_elapsed(), and undinet_call().

◆ profile_stopped()

unsigned long profile_stopped ( struct profiler * profiler)
inlinestatic

Get stop time.

Parameters
profilerProfiler
Return values
stoppedStop time

Definition at line 97 of file profile.h.

97 {
98
99 /* If profiling is active then return start time */
100 if ( PROFILING ) {
101 return ( profiler->stopped + profile_excluded );
102 } else {
103 return 0;
104 }
105}
unsigned long stopped
Stop timestamp.
Definition profile.h:33

References profile_excluded, PROFILING, and profiler::stopped.

Referenced by profile_elapsed(), and undinet_call().

◆ profile_elapsed()

unsigned long profile_elapsed ( struct profiler * profiler)
inlinestatic

Get elapsed time.

Parameters
profilerProfiler
Return values
elapsedElapsed time

Definition at line 114 of file profile.h.

114 {
115
116 /* If profiling is active then return elapsed time */
117 if ( PROFILING ) {
118 return ( profile_stopped ( profiler ) -
120 } else {
121 return 0;
122 }
123}
static unsigned long profile_started(struct profiler *profiler)
Get start time.
Definition profile.h:80
static unsigned long profile_stopped(struct profiler *profiler)
Get stop time.
Definition profile.h:97

References profile_started(), profile_stopped(), and PROFILING.

Referenced by profile_exclude(), and profile_stop_at().

◆ profile_start_at()

void profile_start_at ( struct profiler * profiler,
unsigned long started )
inlinestatic

Start profiling.

Parameters
profilerProfiler
startedStart timestamp

Definition at line 132 of file profile.h.

132 {
133
134 /* If profiling is active then record start timestamp */
135 if ( PROFILING )
137}
static int started
"startup() has been called" flag
Definition init.c:38

References profile_excluded, PROFILING, profiler::started, and started.

Referenced by librm_test_exec(), profile_start(), and undinet_call().

◆ profile_stop_at()

void profile_stop_at ( struct profiler * profiler,
unsigned long stopped )
inlinestatic

Stop profiling.

Parameters
profilerProfiler
stoppedStop timestamp

Definition at line 146 of file profile.h.

146 {
147
148 /* If profiling is active then record end timestamp and update stats */
149 if ( PROFILING ) {
150 profiler->stopped = ( stopped - profile_excluded );
152 }
153}
static unsigned long profile_elapsed(struct profiler *profiler)
Get elapsed time.
Definition profile.h:114
void profile_update(struct profiler *profiler, unsigned long sample)
Update profiler with a new sample.
Definition profile.c:111

References profile_elapsed(), profile_excluded, profile_update(), PROFILING, and profiler::stopped.

Referenced by librm_test_exec(), profile_stop(), and undinet_call().

◆ profile_start()

void profile_start ( struct profiler * profiler)
inlinestatic

Start profiling.

Parameters
profilerProfiler

Definition at line 161 of file profile.h.

161 {
162
163 /* If profiling is active then record start timestamp */
164 if ( PROFILING )
166}
static void profile_start_at(struct profiler *profiler, unsigned long started)
Start profiling.
Definition profile.h:132
unsigned long profile_timestamp(void)

References profile_start_at(), profile_timestamp(), and PROFILING.

Referenced by acm_in_complete(), acm_intr_complete(), acm_out_transmit(), axge_in_complete(), axge_intr_complete(), axge_out_transmit(), cipher_cost(), digest_cost(), ecm_in_complete(), ecm_intr_complete(), ecm_out_transmit(), http_conn_deliver(), http_content_deliver(), ib_post_recv(), ib_post_send(), intel_poll(), intel_refill_rx(), intel_transmit(), interrupt(), iphone_in_complete(), iphone_out_transmit(), ipv4_rx(), ipv4_tx(), librm_test_exec(), memcpy_test_speed(), ncm_in_complete(), ncm_intr_complete(), ncm_out_transmit(), net_poll(), netdev_tx(), pxe_api_call(), pxenv_undi_transmit(), smsc75xx_in_complete(), smsc75xx_out_transmit(), smsc95xx_in_complete(), smsc95xx_out_transmit(), smscusb_intr_complete(), tcp_rx(), tcp_rx_data(), tcp_xmit_sack(), tcpip_random_okx(), tftp_rx(), tftp_rx_data(), undinet_call(), undinet_poll(), vmxnet3_command(), vmxnet3_poll_events(), vmxnet3_refill_rx(), vmxnet3_transmit(), xferbuf_deliver(), xferbuf_read(), xferbuf_write(), xhci_endpoint_message(), xhci_endpoint_stream(), xhci_event_poll(), and xhci_transfer().

◆ profile_stop()

void profile_stop ( struct profiler * profiler)
inlinestatic

Stop profiling.

Parameters
profilerProfiler

Definition at line 174 of file profile.h.

174 {
175
176 /* If profiling is active then record end timestamp and update stats */
177 if ( PROFILING )
179}
static void profile_stop_at(struct profiler *profiler, unsigned long stopped)
Stop profiling.
Definition profile.h:146

References profile_stop_at(), profile_timestamp(), and PROFILING.

Referenced by acm_in_complete(), acm_intr_complete(), acm_out_transmit(), axge_in_complete(), axge_intr_complete(), axge_out_transmit(), cipher_cost(), digest_cost(), ecm_in_complete(), ecm_intr_complete(), ecm_out_transmit(), http_conn_deliver(), http_content_deliver(), ib_post_recv(), ib_post_send(), intel_poll(), intel_refill_rx(), intel_transmit(), interrupt(), iphone_in_complete(), iphone_out_transmit(), ipv4_rx(), ipv4_tx(), librm_test_exec(), memcpy_test_speed(), ncm_in_complete(), ncm_intr_complete(), ncm_out_transmit(), net_poll(), netdev_tx(), pxe_api_call(), pxenv_undi_transmit(), smsc75xx_in_complete(), smsc75xx_out_transmit(), smsc95xx_in_complete(), smsc95xx_out_transmit(), smscusb_intr_complete(), tcp_rx(), tcp_rx_data(), tcp_xmit_sack(), tcpip_random_okx(), tftp_rx_data(), undinet_call(), undinet_poll(), vmxnet3_command(), vmxnet3_poll_events(), vmxnet3_refill_rx(), vmxnet3_transmit(), xferbuf_deliver(), xferbuf_read(), xferbuf_write(), xhci_endpoint_message(), xhci_endpoint_stream(), xhci_event_poll(), and xhci_transfer().

◆ profile_exclude()

void profile_exclude ( struct profiler * profiler)
inlinestatic

Exclude time from other ongoing profiling results.

Parameters
profilerProfiler

Definition at line 187 of file profile.h.

187 {
188
189 /* If profiling is active then update accumulated excluded time */
190 if ( PROFILING )
192}

References profile_elapsed(), profile_excluded, and PROFILING.

Referenced by intel_poll(), intel_refill_rx(), intel_transmit(), interrupt(), vmxnet3_command(), vmxnet3_poll_events(), vmxnet3_refill_rx(), and vmxnet3_transmit().

◆ profile_custom()

void profile_custom ( struct profiler * profiler,
unsigned long sample )
inlinestatic

Record profiling sample in custom units.

Parameters
profilerProfiler
sampleProfiling sample

Definition at line 201 of file profile.h.

201 {
202
203 /* If profiling is active then update stats */
204 if ( PROFILING )
205 profile_update ( profiler, sample );
206}

References profile_update(), and PROFILING.

Referenced by peerblk_close(), peerblk_discovered(), peerblk_done(), and peerblk_expired().

Variable Documentation

◆ profile_excluded

unsigned long profile_excluded
extern

Accumulated time excluded from profiling.

Definition at line 50 of file profile.c.

Referenced by profile_exclude(), profile_start_at(), profile_started(), profile_stop_at(), profile_stopped(), and profile_timestamp().