iPXE
Data Structures | Macros | Functions | Variables
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. More...
 
#define __profiler   __table_entry ( PROFILERS, 01 )
 Declare a profiler. More...
 

Functions

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

Variables

unsigned long profile_excluded
 Accumulated time excluded from profiling. More...
 

Detailed Description

Profiling.

Definition in file profile.h.

Macro Definition Documentation

◆ PROFILING

#define PROFILING   1

Definition at line 19 of file profile.h.

◆ PROFILERS

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

Profiler table.

Definition at line 54 of file profile.h.

◆ __profiler

static struct undinet_profiler undinet_misc_profiler __profiler   __table_entry ( PROFILERS, 01 )

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.

Modular multiplication subtract step profiler.

Modular multiplication rescale step profiler.

Modular multiplication multiply step 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 58 of file profile.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ profile_update()

void profile_update ( struct profiler profiler,
unsigned long  sample 
)

Update profiler with a new sample.

Parameters
profilerProfiler
sampleSample value

Definition at line 110 of file profile.c.

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

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)

Get mean sample value.

Parameters
profilerProfiler
Return values
meanMean sample value

Definition at line 241 of file profile.c.

241  {
242  unsigned int mean_shift = profile_mean_shift ( profiler );
243 
244  /* Round to nearest and scale down to original units */
245  return ( ( profiler->mean + ( 1UL << ( mean_shift - 1 ) ) )
246  >> mean_shift );
247 }
static unsigned int profile_mean_shift(struct profiler *profiler)
Calculate bit shift for mean sample value.
Definition: profile.c:84
A data structure for storing profiling information.
Definition: profile.h:26
unsigned long mean
Mean sample value (scaled)
Definition: profile.h:36

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)

Get sample variance.

Parameters
profilerProfiler
Return values
varianceSample variance

Definition at line 255 of file profile.c.

255  {
256  unsigned int accvar_shift = profile_accvar_shift ( profiler );
257 
258  /* Variance is zero if fewer than two samples exist (avoiding
259  * division by zero error).
260  */
261  if ( profiler->count < 2 )
262  return 0;
263 
264  /* Calculate variance, round to nearest, and scale to original units */
265  return ( ( ( profiler->accvar / ( profiler->count - 1 ) )
266  + ( 1ULL << ( accvar_shift - 1 ) ) ) >> accvar_shift );
267 }
unsigned long long accvar
Accumulated variance (scaled)
Definition: profile.h:44
A data structure for storing profiling information.
Definition: profile.h:26
unsigned int count
Number of samples.
Definition: profile.h:34
static unsigned int profile_accvar_shift(struct profiler *profiler)
Calculate bit shift for accumulated variance value.
Definition: profile.c:97

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

Referenced by profile_stddev().

◆ profile_stddev()

unsigned long profile_stddev ( struct profiler profiler)

Get sample standard deviation.

Parameters
profilerProfiler
Return values
stddevSample standard deviation

Definition at line 275 of file profile.c.

275  {
276 
277  return isqrt ( profile_variance ( profiler ) );
278 }
unsigned long isqrt(unsigned long value)
Find integer square root.
Definition: isqrt.c:40
A data structure for storing profiling information.
Definition: profile.h:26
unsigned long profile_variance(struct profiler *profiler)
Get sample variance.
Definition: profile.c:255

References isqrt(), and profile_variance().

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

◆ profile_started()

static unsigned long profile_started ( struct profiler profiler)
inlinestatic

Get start time.

Parameters
profilerProfiler
Return values
startedStart time

Definition at line 77 of file profile.h.

77  {
78 
79  /* If profiling is active then return start time */
80  if ( PROFILING ) {
81  return ( profiler->started + profile_excluded );
82  } else {
83  return 0;
84  }
85 }
A data structure for storing profiling information.
Definition: profile.h:26
#define PROFILING
Definition: profile.h:19
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition: profile.c:49
unsigned long started
Start timestamp.
Definition: profile.h:30

References profile_excluded, PROFILING, and profiler::started.

Referenced by profile_elapsed(), and undinet_call().

◆ profile_stopped()

static unsigned long profile_stopped ( struct profiler profiler)
inlinestatic

Get stop time.

Parameters
profilerProfiler
Return values
stoppedStop time

Definition at line 94 of file profile.h.

94  {
95 
96  /* If profiling is active then return start time */
97  if ( PROFILING ) {
98  return ( profiler->stopped + profile_excluded );
99  } else {
100  return 0;
101  }
102 }
A data structure for storing profiling information.
Definition: profile.h:26
#define PROFILING
Definition: profile.h:19
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition: profile.c:49
unsigned long stopped
Stop timestamp.
Definition: profile.h:32

References profile_excluded, PROFILING, and profiler::stopped.

Referenced by profile_elapsed(), and undinet_call().

◆ profile_elapsed()

static unsigned long profile_elapsed ( struct profiler profiler)
inlinestatic

Get elapsed time.

Parameters
profilerProfiler
Return values
elapsedElapsed time

Definition at line 111 of file profile.h.

111  {
112 
113  /* If profiling is active then return elapsed time */
114  if ( PROFILING ) {
115  return ( profile_stopped ( profiler ) -
117  } else {
118  return 0;
119  }
120 }
static unsigned long profile_started(struct profiler *profiler)
Get start time.
Definition: profile.h:77
A data structure for storing profiling information.
Definition: profile.h:26
#define PROFILING
Definition: profile.h:19
static unsigned long profile_stopped(struct profiler *profiler)
Get stop time.
Definition: profile.h:94

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

Referenced by profile_exclude(), and profile_stop_at().

◆ profile_start_at()

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

Start profiling.

Parameters
profilerProfiler
startedStart timestamp

Definition at line 129 of file profile.h.

129  {
130 
131  /* If profiling is active then record start timestamp */
132  if ( PROFILING )
134 }
A data structure for storing profiling information.
Definition: profile.h:26
static int started
"startup() has been called" flag
Definition: init.c:37
#define PROFILING
Definition: profile.h:19
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition: profile.c:49
unsigned long started
Start timestamp.
Definition: profile.h:30

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

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

◆ profile_stop_at()

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

Stop profiling.

Parameters
profilerProfiler
stoppedStop timestamp

Definition at line 143 of file profile.h.

143  {
144 
145  /* If profiling is active then record end timestamp and update stats */
146  if ( PROFILING ) {
147  profiler->stopped = ( stopped - profile_excluded );
149  }
150 }
A data structure for storing profiling information.
Definition: profile.h:26
#define PROFILING
Definition: profile.h:19
static unsigned long profile_elapsed(struct profiler *profiler)
Get elapsed time.
Definition: profile.h:111
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition: profile.c:49
void profile_update(struct profiler *profiler, unsigned long sample)
Update profiler with a new sample.
Definition: profile.c:110
unsigned long stopped
Stop timestamp.
Definition: profile.h:32

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

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

◆ profile_start()

static void profile_start ( struct profiler profiler)
inlinestatic

Start profiling.

Parameters
profilerProfiler

Definition at line 158 of file profile.h.

158  {
159 
160  /* If profiling is active then record start timestamp */
161  if ( PROFILING )
162  profile_start_at ( profiler, profile_timestamp() );
163 }
A data structure for storing profiling information.
Definition: profile.h:26
#define PROFILING
Definition: profile.h:19
static void profile_start_at(struct profiler *profiler, unsigned long started)
Start profiling.
Definition: profile.h:129

References profile_start_at(), and PROFILING.

Referenced by acm_in_complete(), acm_intr_complete(), acm_out_transmit(), axge_in_complete(), axge_intr_complete(), axge_out_transmit(), bigint_mod_multiply_raw(), 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()

static void profile_stop ( struct profiler profiler)
inlinestatic

Stop profiling.

Parameters
profilerProfiler

Definition at line 171 of file profile.h.

171  {
172 
173  /* If profiling is active then record end timestamp and update stats */
174  if ( PROFILING )
175  profile_stop_at ( profiler, profile_timestamp() );
176 }
A data structure for storing profiling information.
Definition: profile.h:26
static void profile_stop_at(struct profiler *profiler, unsigned long stopped)
Stop profiling.
Definition: profile.h:143
#define PROFILING
Definition: profile.h:19

References profile_stop_at(), and PROFILING.

Referenced by acm_in_complete(), acm_intr_complete(), acm_out_transmit(), axge_in_complete(), axge_intr_complete(), axge_out_transmit(), bigint_mod_multiply_raw(), 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()

static void profile_exclude ( struct profiler profiler)
inlinestatic

Exclude time from other ongoing profiling results.

Parameters
profilerProfiler

Definition at line 184 of file profile.h.

184  {
185 
186  /* If profiling is active then update accumulated excluded time */
187  if ( PROFILING )
189 }
A data structure for storing profiling information.
Definition: profile.h:26
#define PROFILING
Definition: profile.h:19
static unsigned long profile_elapsed(struct profiler *profiler)
Get elapsed time.
Definition: profile.h:111
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition: profile.c:49

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()

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

Record profiling sample in custom units.

Parameters
profilerProfiler
sampleProfiling sample

Definition at line 198 of file profile.h.

198  {
199 
200  /* If profiling is active then update stats */
201  if ( PROFILING )
202  profile_update ( profiler, sample );
203 }
A data structure for storing profiling information.
Definition: profile.h:26
#define PROFILING
Definition: profile.h:19
void profile_update(struct profiler *profiler, unsigned long sample)
Update profiler with a new sample.
Definition: profile.c:110

References profile_update(), and PROFILING.

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

Variable Documentation

◆ profile_excluded

unsigned long profile_excluded

Accumulated time excluded from profiling.

Definition at line 49 of file profile.c.

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