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)
 
 FILE_SECBOOT (PERMITTED)
 
unsigned long profile_timestamp (void)
 
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 20 of file profile.h.

◆ PROFILERS

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

Profiler table.

Definition at line 55 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.

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

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 -
203  profiler->accvar_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;
224  profiler->accvar_msb++;
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 }
static unsigned int profile_mean_shift(struct profiler *profiler)
Calculate bit shift for mean sample value.
Definition: profile.c:85
#define DBGC(...)
Definition: compiler.h:505
unsigned long long accvar
Accumulated variance (scaled)
Definition: profile.h:45
#define flsll(x)
Find last (i.e.
Definition: strings.h:149
A data structure for storing profiling information.
Definition: profile.h:27
unsigned int mean_msb
Mean sample value MSB.
Definition: profile.h:43
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int count
Number of samples.
Definition: profile.h:35
#define flsl(x)
Find last (i.e.
Definition: strings.h:158
#define INT_MAX
Definition: limits.h:37
unsigned int accvar_msb
Accumulated variance MSB.
Definition: profile.h:51
unsigned long mean
Mean sample value (scaled)
Definition: profile.h:37
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_accvar_shift(struct profiler *profiler)
Calculate bit shift for accumulated variance value.
Definition: profile.c:98

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 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 }
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 long mean
Mean sample value (scaled)
Definition: profile.h:37

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 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 }
unsigned long long accvar
Accumulated variance (scaled)
Definition: profile.h:45
A data structure for storing profiling information.
Definition: profile.h:27
unsigned int count
Number of samples.
Definition: profile.h:35
static unsigned int profile_accvar_shift(struct profiler *profiler)
Calculate bit shift for accumulated variance value.
Definition: profile.c:98

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 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
A data structure for storing profiling information.
Definition: profile.h:27
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()

static 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 }
A data structure for storing profiling information.
Definition: profile.h:27
#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()

static 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 }
A data structure for storing profiling information.
Definition: profile.h:27
#define PROFILING
Definition: profile.h:20
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition: profile.c:50
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()

static 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
A data structure for storing profiling information.
Definition: profile.h:27
#define PROFILING
Definition: profile.h:20
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()

static 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 }
A data structure for storing profiling information.
Definition: profile.h:27
static int started
"startup() has been called" flag
Definition: init.c:38
#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, 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 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 }
A data structure for storing profiling information.
Definition: profile.h:27
#define PROFILING
Definition: profile.h:20
static unsigned long profile_elapsed(struct profiler *profiler)
Get elapsed time.
Definition: profile.h:114
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition: profile.c:50
void profile_update(struct profiler *profiler, unsigned long sample)
Update profiler with a new sample.
Definition: profile.c:111
unsigned long stopped
Stop timestamp.
Definition: profile.h:33

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 161 of file profile.h.

161  {
162 
163  /* If profiling is active then record start timestamp */
164  if ( PROFILING )
166 }
A data structure for storing profiling information.
Definition: profile.h:27
#define PROFILING
Definition: profile.h:20
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()

static 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 }
A data structure for storing profiling information.
Definition: profile.h:27
static void profile_stop_at(struct profiler *profiler, unsigned long stopped)
Stop profiling.
Definition: profile.h:146
#define PROFILING
Definition: profile.h:20
unsigned long profile_timestamp(void)

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

static 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 }
A data structure for storing profiling information.
Definition: profile.h:27
#define PROFILING
Definition: profile.h:20
static unsigned long profile_elapsed(struct profiler *profiler)
Get elapsed time.
Definition: profile.h:114
unsigned long profile_excluded
Accumulated time excluded from profiling.
Definition: profile.c:50

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 201 of file profile.h.

201  {
202 
203  /* If profiling is active then update stats */
204  if ( PROFILING )
205  profile_update ( profiler, sample );
206 }
A data structure for storing profiling information.
Definition: profile.h:27
#define PROFILING
Definition: profile.h:20
void profile_update(struct profiler *profiler, unsigned long sample)
Update profiler with a new sample.
Definition: profile.c:111

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 50 of file profile.c.

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