[rtems commit] sapi: Add SMP lock profiling app. level data

Sebastian Huber sebh at rtems.org
Fri Mar 14 07:42:46 UTC 2014


Module:    rtems
Branch:    master
Commit:    350f88dc6e8e5dc86a875796a938529ebbe8d549
Changeset: http://git.rtems.org/rtems/commit/?id=350f88dc6e8e5dc86a875796a938529ebbe8d549

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Mar 10 10:20:40 2014 +0100

sapi: Add SMP lock profiling app. level data

---

 cpukit/sapi/include/rtems/profiling.h |   99 ++++++++++++++++++++++++++++++++-
 cpukit/sapi/src/profilingreportxml.c  |   78 ++++++++++++++++++++++++++
 2 files changed, 176 insertions(+), 1 deletions(-)

diff --git a/cpukit/sapi/include/rtems/profiling.h b/cpukit/sapi/include/rtems/profiling.h
index 3bc5921..133d164 100644
--- a/cpukit/sapi/include/rtems/profiling.h
+++ b/cpukit/sapi/include/rtems/profiling.h
@@ -66,7 +66,14 @@ typedef enum {
    *
    * @see rtems_profiling_per_cpu.
    */
-  RTEMS_PROFILING_PER_CPU
+  RTEMS_PROFILING_PER_CPU,
+
+  /**
+   * @brief Type of SMP lock profiling data.
+   *
+   * @see rtems_profiling_smp_lock.
+   */
+  RTEMS_PROFILING_SMP_LOCK
 } rtems_profiling_type;
 
 /**
@@ -170,6 +177,91 @@ typedef struct {
 } rtems_profiling_per_cpu;
 
 /**
+ * @brief Count of lock contention counters for SMP lock profiling.
+ */
+#define RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS 4
+
+/**
+ * @brief SMP lock profiling data.
+ *
+ * The lock acquire attempt instant is the point in time right after the
+ * interrupt disable action in the lock acquire sequence.
+ *
+ * The lock acquire instant is the point in time right after the lock
+ * acquisition.  This is the begin of the critical section code execution.
+ *
+ * The lock acquire time is the time elapsed between the lock acquire attempt
+ * instant and the lock acquire instant.
+ *
+ * The lock release instant is the point in time right before the interrupt
+ * enable action in the lock release sequence.
+ *
+ * The lock section time is the time elapsed between the lock acquire instant
+ * and the lock release instant.
+ */
+typedef struct {
+  /**
+   * @brief The profiling data header.
+   */
+  rtems_profiling_header header;
+
+  /**
+   * @brief The lock name.
+   */
+  const char *name;
+
+  /**
+   * @brief The maximum lock acquire time in nanoseconds.
+   */
+  uint32_t max_acquire_time;
+
+  /**
+   * @brief The maximum lock section time in nanoseconds.
+   */
+  uint32_t max_section_time;
+
+  /**
+   * @brief The count of lock uses.
+   *
+   * This value may overflow.
+   */
+  uint64_t usage_count;
+
+  /**
+   * @brief Total lock acquire time in nanoseconds.
+   *
+   * The average lock acquire time is the total acquire time divided by the
+   * lock usage count.  The ration of the total section and total acquire times
+   * gives a measure for the lock contention.
+   *
+   * This value may overflow.
+   */
+  uint64_t total_acquire_time;
+
+  /**
+   * @brief Total lock section time in nanoseconds.
+   *
+   * The average lock section time is the total section time divided by the
+   * lock usage count.
+   *
+   * This value may overflow.
+   */
+  uint64_t total_section_time;
+
+  /**
+   * @brief The counts of lock acquire operations by contention.
+   *
+   * The contention count for index N corresponds to a lock acquire attempt
+   * with an initial queue length of N.  The last index corresponds to all
+   * lock acquire attempts with an initial queue length greater than or equal
+   * to RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS minus one.
+   *
+   * The values may overflow.
+   */
+  uint64_t contention_counts[RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS];
+} rtems_profiling_smp_lock;
+
+/**
  * @brief Collection of profiling data.
  */
 typedef union {
@@ -182,6 +274,11 @@ typedef union {
    * @brief Per-CPU profiling data if indicated by the header.
    */
   rtems_profiling_per_cpu per_cpu;
+
+  /**
+   * @brief SMP lock profiling data if indicated by the header.
+   */
+  rtems_profiling_smp_lock smp_lock;
 } rtems_profiling_data;
 
 /**
diff --git a/cpukit/sapi/src/profilingreportxml.c b/cpukit/sapi/src/profilingreportxml.c
index 409fe3d..8ca6971 100644
--- a/cpukit/sapi/src/profilingreportxml.c
+++ b/cpukit/sapi/src/profilingreportxml.c
@@ -130,6 +130,81 @@ static void report_per_cpu(context *ctx, const rtems_profiling_per_cpu *per_cpu)
   update_retval(ctx, rv);
 }
 
+static void report_smp_lock(context *ctx, const rtems_profiling_smp_lock *smp_lock)
+{
+  rtems_profiling_printf printf_func = ctx->printf_func;
+  void *printf_arg = ctx->printf_arg;
+  int rv;
+  uint32_t i;
+
+  indent(ctx, 1);
+  rv = (*printf_func)(
+    printf_arg,
+    "<SMPLockProfilingReport name=\"%s\">\n",
+    smp_lock->name
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<MaxAcquireTime unit=\"ns\">%" PRIu32 "</MaxAcquireTime>\n",
+    smp_lock->max_acquire_time
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<MaxSectionTime unit=\"ns\">%" PRIu32 "</MaxSectionTime>\n",
+    smp_lock->max_section_time
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<UsageCount>%" PRIu64 "</UsageCount>\n",
+    smp_lock->usage_count
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<TotalAcquireTime unit=\"ns\">%" PRIu64 "</TotalAcquireTime>\n",
+    smp_lock->total_acquire_time
+  );
+  update_retval(ctx, rv);
+
+  indent(ctx, 2);
+  rv = (*printf_func)(
+    printf_arg,
+    "<TotalSectionTime unit=\"ns\">%" PRIu64 "</TotalSectionTime>\n",
+    smp_lock->total_section_time
+  );
+  update_retval(ctx, rv);
+
+  for (i = 0; i < RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS; ++i) {
+    indent(ctx, 2);
+    rv = (*printf_func)(
+      printf_arg,
+      "<ContentionCount initialQueueLength=\"%" PRIu32 "\">%"
+        PRIu64 "</ContentionCount>\n",
+      i,
+      smp_lock->contention_counts[i]
+    );
+    update_retval(ctx, rv);
+  }
+
+  indent(ctx, 1);
+  rv = (*printf_func)(
+    printf_arg,
+    "</SMPLockProfilingReport>\n"
+  );
+  update_retval(ctx, rv);
+}
+
 static void report(void *arg, const rtems_profiling_data *data)
 {
   context *ctx = arg;
@@ -138,6 +213,9 @@ static void report(void *arg, const rtems_profiling_data *data)
     case RTEMS_PROFILING_PER_CPU:
       report_per_cpu(ctx, &data->per_cpu);
       break;
+    case RTEMS_PROFILING_SMP_LOCK:
+      report_smp_lock(ctx, &data->smp_lock);
+      break;
   }
 }
 




More information about the vc mailing list