[PATCH 03/11] sapi: Add per-CPU profiling application level data

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Mar 10 13:28:25 UTC 2014


---
 cpukit/sapi/include/rtems/profiling.h              |   83 ++++++++++++++++++
 cpukit/sapi/src/profilingreportxml.c               |   89 ++++++++++++++++++++
 testsuites/sptests/spprofiling01/spprofiling01.scn |   10 ++-
 3 files changed, 181 insertions(+), 1 deletions(-)

diff --git a/cpukit/sapi/include/rtems/profiling.h b/cpukit/sapi/include/rtems/profiling.h
index ee56a03..ecb3ff7 100644
--- a/cpukit/sapi/include/rtems/profiling.h
+++ b/cpukit/sapi/include/rtems/profiling.h
@@ -61,6 +61,12 @@ extern "C" {
  * @brief Type of profiling data.
  */
 typedef enum {
+  /**
+   * @brief Type of per-CPU profiling data.
+   *
+   * @see rtems_profiling_per_cpu.
+   */
+  RTEMS_PROFILING_PER_CPU
 } rtems_profiling_type;
 
 /**
@@ -74,6 +80,78 @@ typedef struct {
 } rtems_profiling_header;
 
 /**
+ * @brief Per-CPU profiling data.
+ */
+typedef struct {
+  /**
+   * @brief The profiling data header.
+   */
+  rtems_profiling_header header;
+
+  /**
+   * @brief The processor index of this profiling data.
+   */
+  uint32_t processor_index;
+
+  /**
+   * @brief The maximum time of disabled thread dispatching in nanoseconds.
+   */
+  uint32_t max_thread_dispatch_disabled_time;
+
+  /**
+   * @brief Count of times when the thread dispatch disable level changes from
+   * zero to one in thread context.
+   *
+   * This value may overflow.
+   */
+  uint64_t thread_dispatch_disabled_count;
+
+  /**
+   * @brief Total time of disabled thread dispatching in nanoseconds.
+   *
+   * The average time of disabled thread dispatching is the total time of
+   * disabled thread dispatching divided by the thread dispatch disabled
+   * count.
+   *
+   * This value may overflow.
+   */
+  uint64_t total_thread_dispatch_disabled_time;
+
+  /**
+   * @brief The maximum interrupt delay in nanoseconds if supported by the
+   * hardware.
+   */
+  uint32_t max_interrupt_delay;
+
+  /**
+   * @brief The maximum time spent to process a single sequence of nested
+   * interrupts in nanoseconds.
+   *
+   * This is the time interval between the change of the interrupt nest level
+   * from zero to one and the change back from one to zero.
+   */
+  uint32_t max_interrupt_time;
+
+  /**
+   * @brief Count of times when the interrupt nest level changes from zero to
+   * one.
+   *
+   * This value may overflow.
+   */
+  uint64_t interrupt_count;
+
+  /**
+   * @brief Total time of interrupt processing in nanoseconds.
+   *
+   * The average time of interrupt processing is the total time of interrupt
+   * processing divided by the interrupt count.
+   *
+   * This value may overflow.
+   */
+  uint64_t total_interrupt_time;
+} rtems_profiling_per_cpu;
+
+/**
  * @brief Collection of profiling data.
  */
 typedef union {
@@ -81,6 +159,11 @@ typedef union {
    * @brief Header to specify the actual profiling data.
    */
   rtems_profiling_header header;
+
+  /**
+   * @brief Per-CPU profiling data if indicated by the header.
+   */
+  rtems_profiling_per_cpu per_cpu;
 } rtems_profiling_data;
 
 /**
diff --git a/cpukit/sapi/src/profilingreportxml.c b/cpukit/sapi/src/profilingreportxml.c
index a80cd16..f0a6fd6 100644
--- a/cpukit/sapi/src/profilingreportxml.c
+++ b/cpukit/sapi/src/profilingreportxml.c
@@ -18,6 +18,8 @@
 
 #include <rtems/profiling.h>
 
+#include <inttypes.h>
+
 typedef struct {
   rtems_profiling_printf printf_func;
   void *printf_arg;
@@ -45,9 +47,96 @@ static void indent(context *ctx, uint32_t indentation_level)
   }
 }
 
+static void report_per_cpu(context *ctx, const rtems_profiling_per_cpu *per_cpu)
+{
+  rtems_profiling_printf printf_func = ctx->printf_func;
+  void *printf_arg = ctx->printf_arg;
+  int rv;
+
+  indent(ctx, 1);
+  rv = (*printf_func)(
+    printf_arg,
+    "<PerCPUProfilingReport processorIndex=\"%" PRIu32 "\">\n",
+    per_cpu->processor_index
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<MaxThreadDispatchDisabledTime unit=\"ns\">%" PRIu32
+      "</MaxThreadDispatchDisabledTime>\n",
+    per_cpu->max_thread_dispatch_disabled_time
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<ThreadDispatchDisabledCount>%" PRIu64 "</ThreadDispatchDisabledCount>\n",
+    per_cpu->thread_dispatch_disabled_count
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<TotalThreadDispatchDisabledTime unit=\"ns\">%" PRIu64
+      "</TotalThreadDispatchDisabledTime>\n",
+    per_cpu->total_thread_dispatch_disabled_time
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<MaxInterruptTime unit=\"ns\">%" PRIu32
+      "</MaxInterruptTime>\n",
+    per_cpu->max_interrupt_time
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<MaxInterruptDelay unit=\"ns\">%" PRIu32 "</MaxInterruptDelay>\n",
+    per_cpu->max_interrupt_delay
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<InterruptCount>%" PRIu64 "</InterruptCount>\n",
+    per_cpu->interrupt_count
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<TotalInterruptTime unit=\"ns\">%" PRIu64 "</TotalInterruptTime>\n",
+    per_cpu->total_interrupt_time
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 1);
+  rv = (*printf_func)(
+    printf_arg,
+    "</PerCPUProfilingReport>\n"
+  );
+  update_retval(ctx, rv);
+}
+
 static void report(void *arg, const rtems_profiling_data *data)
 {
   context *ctx = arg;
+
+  switch (data->header.type) {
+    case RTEMS_PROFILING_PER_CPU:
+      report_per_cpu(ctx, &data->per_cpu);
+      break;
+  }
 }
 
 int rtems_profiling_report_xml(
diff --git a/testsuites/sptests/spprofiling01/spprofiling01.scn b/testsuites/sptests/spprofiling01/spprofiling01.scn
index 2c289db..a00baa1 100644
--- a/testsuites/sptests/spprofiling01/spprofiling01.scn
+++ b/testsuites/sptests/spprofiling01/spprofiling01.scn
@@ -1,5 +1,13 @@
 *** TEST SPPROFILING 1 ***
   <ProfilingReport name="X">
+    <PerCPUProfilingReport processorIndex="0">
+      <MaxInterruptDelay unit="ns">0</MaxInterruptDelay>
+      <MaxThreadDispatchDisabledTime unit="ns">0</MaxThreadDispatchDisabledTime>
+      <ThreadDispatchDisabledCount>0</ThreadDispatchDisabledCount>
+      <TotalThreadDispatchDisabledTime unit="ns">0</TotalThreadDispatchDisabledTime>
+      <InterruptCount>0</InterruptCount>
+      <TotalInterruptTime unit="ns">0</TotalInterruptTime>
+    </PerCPUProfilingReport>
   </ProfilingReport>
-characters produced by rtems_profiling_report_xml(): 50
+characters produced by rtems_profiling_report_xml(): 516
 *** END OF TEST SPPROFILING 1 ***
-- 
1.7.7




More information about the devel mailing list