iPXE
Data Structures | Defines | 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...

Defines

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

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
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.


Define Documentation

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

Profiler table.

Definition at line 54 of file profile.h.

Referenced by profstat().

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.

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

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

                                                                        {
        unsigned int sample_msb;
        unsigned int mean_shift;
        unsigned int delta_shift;
        signed long pre_delta;
        signed long post_delta;
        signed long long accvar_delta;
        unsigned int accvar_delta_shift;
        unsigned int accvar_delta_msb;
        unsigned int accvar_shift;

        /* Our scaling logic assumes that sample values never overflow
         * a signed long (i.e. that the high bit is always zero).
         */
        assert ( ( ( signed ) sample ) >= 0 );

        /* Update sample count, limiting to avoid signed overflow */
        if ( profiler->count < INT_MAX )
                profiler->count++;

        /* Adjust mean sample value scale if necessary.  Skip if
         * sample is zero (in which case flsl(sample)-1 would
         * underflow): in the case of a zero sample we have no need to
         * adjust the scale anyway.
         */
        if ( sample ) {
                sample_msb = ( flsl ( sample ) - 1 );
                if ( profiler->mean_msb < sample_msb ) {
                        profiler->mean >>= ( sample_msb - profiler->mean_msb );
                        profiler->mean_msb = sample_msb;
                }
        }

        /* Scale sample to internal units */
        mean_shift = profile_mean_shift ( profiler );
        sample <<= mean_shift;

        /* Update mean */
        pre_delta = ( sample - profiler->mean );
        profiler->mean += ( pre_delta / ( ( signed ) profiler->count ) );
        post_delta = ( sample - profiler->mean );
        delta_shift = mean_shift;
        DBGC ( profiler, "PROFILER %p sample %#lx mean %s", profiler,
               ( sample >> mean_shift ),
                profile_hex_fraction ( profiler->mean, mean_shift ) );
        DBGC ( profiler, " pre %s",
               profile_hex_fraction ( pre_delta, delta_shift ) );
        DBGC ( profiler, " post %s\n",
               profile_hex_fraction ( post_delta, delta_shift ) );

        /* Scale both deltas to fit in half of an unsigned long long
         * to avoid potential overflow on multiplication.  Note that
         * shifting a signed quantity is "implementation-defined"
         * behaviour in the C standard, but gcc documents that it will
         * always perform sign extension.
         */
        if ( sizeof ( pre_delta ) > ( sizeof ( accvar_delta ) / 2 ) ) {
                unsigned int shift = ( 8 * ( sizeof ( pre_delta ) -
                                             ( sizeof ( accvar_delta ) / 2 ) ));
                pre_delta >>= shift;
                post_delta >>= shift;
                delta_shift -= shift;
        }

        /* Update variance, if applicable.  Skip if either delta is
         * zero (in which case flsl(delta)-1 would underflow): in the
         * case of a zero delta there is no change to the accumulated
         * variance anyway.
         */
        if ( pre_delta && post_delta ) {

                /* Calculate variance delta */
                accvar_delta = ( ( ( signed long long ) pre_delta ) *
                                 ( ( signed long long ) post_delta ) );
                accvar_delta_shift = ( 2 * delta_shift );
                assert ( accvar_delta > 0 );

                /* Calculate variance delta MSB, using flsl() on each
                 * delta individually to provide an upper bound rather
                 * than requiring the existence of flsll().
                 */
                accvar_delta_msb = ( flsll ( accvar_delta ) - 1 );
                if ( accvar_delta_msb > accvar_delta_shift ) {
                        accvar_delta_msb -= accvar_delta_shift;
                } else {
                        accvar_delta_msb = 0;
                }

                /* Adjust scales as necessary */
                if ( profiler->accvar_msb < accvar_delta_msb ) {
                        /* Rescale accumulated variance */
                        profiler->accvar >>= ( accvar_delta_msb -
                                               profiler->accvar_msb );
                        profiler->accvar_msb = accvar_delta_msb;
                } else {
                        /* Rescale variance delta */
                        accvar_delta >>= ( profiler->accvar_msb -
                                           accvar_delta_msb );
                        accvar_delta_shift -= ( profiler->accvar_msb -
                                                accvar_delta_msb );
                }

                /* Scale delta to internal units */
                accvar_shift = profile_accvar_shift ( profiler );
                accvar_delta <<= ( accvar_shift - accvar_delta_shift );

                /* Accumulate variance */
                profiler->accvar += accvar_delta;

                /* Adjust scale if necessary */
                if ( profiler->accvar &
                     ( 1ULL << ( ( 8 * sizeof ( profiler->accvar ) ) - 1 ) ) ) {
                        profiler->accvar >>= 1;
                        profiler->accvar_msb++;
                        accvar_delta >>= 1;
                        accvar_shift--;
                }

                DBGC ( profiler, "PROFILER %p accvar %s", profiler,
                       profile_hex_fraction ( profiler->accvar, accvar_shift ));
                DBGC ( profiler, " delta %s\n",
                       profile_hex_fraction ( accvar_delta, accvar_shift ) );
        }
}
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.

References profiler::mean, and profile_mean_shift().

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

                                                         {
        unsigned int mean_shift = profile_mean_shift ( profiler );

        /* Round to nearest and scale down to original units */
        return ( ( profiler->mean + ( 1UL << ( mean_shift - 1 ) ) )
                 >> mean_shift );
}
unsigned long profile_variance ( struct profiler profiler)

Get sample variance.

Parameters:
profilerProfiler
Return values:
varianceSample variance

Definition at line 255 of file profile.c.

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

Referenced by profile_stddev().

                                                             {
        unsigned int accvar_shift = profile_accvar_shift ( profiler );

        /* Variance is zero if fewer than two samples exist (avoiding
         * division by zero error).
         */
        if ( profiler->count < 2 )
                return 0;

        /* Calculate variance, round to nearest, and scale to original units */
        return ( ( ( profiler->accvar / ( profiler->count - 1 ) )
                   + ( 1ULL << ( accvar_shift - 1 ) ) ) >> accvar_shift );
}
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.

References isqrt(), and profile_variance().

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

                                                           {

        return isqrt ( profile_variance ( profiler ) );
}
static unsigned long profile_started ( struct profiler profiler) [inline, static]

Get start time.

Parameters:
profilerProfiler
Return values:
startedStart time

Definition at line 77 of file profile.h.

References profile_excluded.

Referenced by profile_elapsed(), and undinet_call().

                                              {

        /* If profiling is active then return start time */
        if ( PROFILING ) {
                return ( profiler->started + profile_excluded );
        } else {
                return 0;
        }
}
static unsigned long profile_stopped ( struct profiler profiler) [inline, static]

Get stop time.

Parameters:
profilerProfiler
Return values:
stoppedStop time

Definition at line 94 of file profile.h.

References profile_excluded.

Referenced by profile_elapsed(), and undinet_call().

                                              {

        /* If profiling is active then return start time */
        if ( PROFILING ) {
                return ( profiler->stopped + profile_excluded );
        } else {
                return 0;
        }
}
static unsigned long profile_elapsed ( struct profiler profiler) [inline, static]

Get elapsed time.

Parameters:
profilerProfiler
Return values:
elapsedElapsed time

Definition at line 111 of file profile.h.

References profile_started(), and profile_stopped().

Referenced by profile_exclude(), and profile_stop_at().

                                              {

        /* If profiling is active then return elapsed time */
        if ( PROFILING ) {
                return ( profile_stopped ( profiler ) -
                         profile_started ( profiler ) );
        } else {
                return 0;
        }
}
static void profile_start_at ( struct profiler profiler,
unsigned long  started 
) [inline, static]

Start profiling.

Parameters:
profilerProfiler
startedStart timestamp

Definition at line 129 of file profile.h.

References profile_excluded.

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

                                                                      {

        /* If profiling is active then record start timestamp */
        if ( PROFILING )
                profiler->started = ( started - profile_excluded );
}
static void profile_stop_at ( struct profiler profiler,
unsigned long  stopped 
) [inline, static]

Stop profiling.

Parameters:
profilerProfiler
stoppedStop timestamp

Definition at line 143 of file profile.h.

References profile_elapsed(), profile_excluded, and profile_update().

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

                                                                     {

        /* If profiling is active then record end timestamp and update stats */
        if ( PROFILING ) {
                profiler->stopped = ( stopped - profile_excluded );
                profile_update ( profiler, profile_elapsed ( profiler ) );
        }
}
static void profile_start ( struct profiler profiler) [inline, static]
static void profile_stop ( struct profiler profiler) [inline, static]
static void profile_exclude ( struct profiler profiler) [inline, static]

Exclude time from other ongoing profiling results.

Parameters:
profilerProfiler

Definition at line 184 of file profile.h.

References profile_elapsed(), and profile_excluded.

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

                                              {

        /* If profiling is active then update accumulated excluded time */
        if ( PROFILING )
                profile_excluded += profile_elapsed ( profiler );
}
static void profile_custom ( struct profiler profiler,
unsigned long  sample 
) [inline, static]

Record profiling sample in custom units.

Parameters:
profilerProfiler
sampleProfiling sample

Definition at line 198 of file profile.h.

References profile_update().

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

                                                                   {

        /* If profiling is active then update stats */
        if ( PROFILING )
                profile_update ( profiler, sample );
}

Variable Documentation

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