diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-03-10 10:20:40 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-03-14 08:46:49 +0100 |
commit | 350f88dc6e8e5dc86a875796a938529ebbe8d549 (patch) | |
tree | cf768303c7acdd2372a6b3805f09f4d61f646cc1 | |
parent | sapi: Add per-CPU profiling application level data (diff) | |
download | rtems-350f88dc6e8e5dc86a875796a938529ebbe8d549.tar.bz2 |
sapi: Add SMP lock profiling app. level data
-rw-r--r-- | cpukit/sapi/include/rtems/profiling.h | 99 | ||||
-rw-r--r-- | 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 3bc59217b9..133d16489a 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 409fe3d7eb..8ca6971f16 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; } } |