summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe
diff options
context:
space:
mode:
authorMichael Brown2014-05-04 12:45:11 +0200
committerMichael Brown2014-05-04 14:39:42 +0200
commit6f410a16d946d7015eaa11c1b255c28debb0d8b5 (patch)
tree854316bd29bdc637ee09951452c1cb12c7b197a3 /src/include/ipxe
parent[undi] Place an upper limit on the number of PXENV_UNDI_ISR calls per poll (diff)
downloadipxe-6f410a16d946d7015eaa11c1b255c28debb0d8b5.tar.gz
ipxe-6f410a16d946d7015eaa11c1b255c28debb0d8b5.tar.xz
ipxe-6f410a16d946d7015eaa11c1b255c28debb0d8b5.zip
[profile] Allow interrupts to be excluded from profiling results
Interrupt processing adds noise to profiling results. Allow interrupts (from within protected mode) to be profiled separately, with time spent within the interrupt handler being excluded from any other profiling currently in progress. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe')
-rw-r--r--src/include/ipxe/profile.h91
1 files changed, 79 insertions, 12 deletions
diff --git a/src/include/ipxe/profile.h b/src/include/ipxe/profile.h
index d4fc4f90..3a745fcf 100644
--- a/src/include/ipxe/profile.h
+++ b/src/include/ipxe/profile.h
@@ -58,12 +58,66 @@ struct profiler {
#define __profiler
#endif
+extern unsigned long profile_excluded;
+
extern void profile_update ( struct profiler *profiler, unsigned long sample );
extern unsigned long profile_mean ( struct profiler *profiler );
extern unsigned long profile_variance ( struct profiler *profiler );
extern unsigned long profile_stddev ( struct profiler *profiler );
/**
+ * Get start time
+ *
+ * @v profiler Profiler
+ * @ret started Start time
+ */
+static inline __attribute__ (( always_inline )) unsigned long
+profile_started ( struct profiler *profiler ) {
+
+ /* If profiling is active then return start time */
+ if ( PROFILING ) {
+ return ( profiler->started + profile_excluded );
+ } else {
+ return 0;
+ }
+}
+
+/**
+ * Get stop time
+ *
+ * @v profiler Profiler
+ * @ret stopped Stop time
+ */
+static inline __attribute__ (( always_inline )) unsigned long
+profile_stopped ( struct profiler *profiler ) {
+
+ /* If profiling is active then return start time */
+ if ( PROFILING ) {
+ return ( profiler->stopped + profile_excluded );
+ } else {
+ return 0;
+ }
+}
+
+/**
+ * Get elapsed time
+ *
+ * @v profiler Profiler
+ * @ret elapsed Elapsed time
+ */
+static inline __attribute__ (( always_inline )) unsigned long
+profile_elapsed ( struct profiler *profiler ) {
+
+ /* If profiling is active then return elapsed time */
+ if ( PROFILING ) {
+ return ( profile_stopped ( profiler ) -
+ profile_started ( profiler ) );
+ } else {
+ return 0;
+ }
+}
+
+/**
* Start profiling
*
* @v profiler Profiler
@@ -74,7 +128,23 @@ profile_start_at ( struct profiler *profiler, unsigned long started ) {
/* If profiling is active then record start timestamp */
if ( PROFILING )
- profiler->started = started;
+ profiler->started = ( started - profile_excluded );
+}
+
+/**
+ * Stop profiling
+ *
+ * @v profiler Profiler
+ * @v stopped Stop timestamp
+ */
+static inline __attribute__ (( always_inline )) void
+profile_stop_at ( struct profiler *profiler, unsigned long stopped ) {
+
+ /* If profiling is active then record end timestamp and update stats */
+ if ( PROFILING ) {
+ profiler->stopped = ( stopped - profile_excluded );
+ profile_update ( profiler, profile_elapsed ( profiler ) );
+ }
}
/**
@@ -91,32 +161,29 @@ profile_start ( struct profiler *profiler ) {
}
/**
- * Record profiling result
+ * Stop profiling
*
* @v profiler Profiler
- * @v stopped Stop timestamp
*/
static inline __attribute__ (( always_inline )) void
-profile_stop_at ( struct profiler *profiler, unsigned long stopped ) {
+profile_stop ( struct profiler *profiler ) {
/* If profiling is active then record end timestamp and update stats */
- if ( PROFILING ) {
- profiler->stopped = stopped;
- profile_update ( profiler, ( stopped - profiler->started ) );
- }
+ if ( PROFILING )
+ profile_stop_at ( profiler, profile_timestamp() );
}
/**
- * Record profiling result
+ * Exclude time from other ongoing profiling results
*
* @v profiler Profiler
*/
static inline __attribute__ (( always_inline )) void
-profile_stop ( struct profiler *profiler ) {
+profile_exclude ( struct profiler *profiler ) {
- /* If profiling is active then record end timestamp and update stats */
+ /* If profiling is active then update accumulated excluded time */
if ( PROFILING )
- profile_stop_at ( profiler, profile_timestamp() );
+ profile_excluded += profile_elapsed ( profiler );
}
#endif /* _IPXE_PROFILE_H */