forked from Imagelibrary/rtems
sapi: Add profiling application level support
This commit is contained in:
@@ -14,6 +14,7 @@ include_rtems_HEADERS += include/rtems/init.h
|
||||
include_rtems_HEADERS += include/rtems/io.h
|
||||
include_rtems_HEADERS += include/rtems/mptables.h
|
||||
include_rtems_HEADERS += include/rtems/cbs.h
|
||||
include_rtems_HEADERS += include/rtems/profiling.h
|
||||
include_rtems_HEADERS += include/rtems/rbheap.h
|
||||
include_rtems_HEADERS += include/rtems/rbtree.h
|
||||
include_rtems_HEADERS += include/rtems/sptables.h
|
||||
@@ -36,6 +37,8 @@ libsapi_a_SOURCES += src/chainsmp.c
|
||||
libsapi_a_SOURCES += src/cpucounterconverter.c
|
||||
libsapi_a_SOURCES += src/delayticks.c
|
||||
libsapi_a_SOURCES += src/delaynano.c
|
||||
libsapi_a_SOURCES += src/profilingiterate.c
|
||||
libsapi_a_SOURCES += src/profilingreportxml.c
|
||||
libsapi_a_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
|
||||
include $(srcdir)/preinstall.am
|
||||
|
||||
148
cpukit/sapi/include/rtems/profiling.h
Normal file
148
cpukit/sapi/include/rtems/profiling.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup Profiling
|
||||
*
|
||||
* @brief Profiling API
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_PROFILING_H
|
||||
#define _RTEMS_PROFILING_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @defgroup Profiling Profiling Support
|
||||
*
|
||||
* @brief The profiling support offers functions to report profiling
|
||||
* information available in the system.
|
||||
*
|
||||
* Profiling support is by default disabled. It must be enabled via the
|
||||
* configure command line with the <tt>--enable-profiling</tt> option. In this
|
||||
* case the RTEMS_PROFILING pre-processor symbol is defined and profiling
|
||||
* statistics will be gathered during system run-time. The profiling support
|
||||
* increases the time of critical sections and has some memory overhead. The
|
||||
* overhead should be acceptable for most applications. The aim of the
|
||||
* profiling implementation is to be available even for production systems so
|
||||
* that verification is simplified.
|
||||
*
|
||||
* Profiling information includes critical timing values such as the maximum
|
||||
* time of disabled thread dispatching which is a measure for the thread
|
||||
* dispatch latency. On SMP configurations statistics of all SMP locks in the
|
||||
* system are available.
|
||||
*
|
||||
* Profiling information can be retrieved via rtems_profiling_iterate() and
|
||||
* reported as an XML dump via rtems_profiling_report_xml(). These functions
|
||||
* are always available, but actual profiling data is only available if enabled
|
||||
* at build configuration time.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Type of profiling data.
|
||||
*/
|
||||
typedef enum {
|
||||
} rtems_profiling_type;
|
||||
|
||||
/**
|
||||
* @brief The profiling data header.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief The profiling data type.
|
||||
*/
|
||||
rtems_profiling_type type;
|
||||
} rtems_profiling_header;
|
||||
|
||||
/**
|
||||
* @brief Collection of profiling data.
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief Header to specify the actual profiling data.
|
||||
*/
|
||||
rtems_profiling_header header;
|
||||
} rtems_profiling_data;
|
||||
|
||||
/**
|
||||
* @brief Visitor function for the profiling iteration.
|
||||
*
|
||||
* @param[in, out] arg The visitor argument.
|
||||
* @param[in] data The current profiling data.
|
||||
*
|
||||
* @see rtems_profiling_iterate().
|
||||
*/
|
||||
typedef void (*rtems_profiling_visitor)(
|
||||
void *arg,
|
||||
const rtems_profiling_data *data
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Iterates through all profiling data of the system.
|
||||
*
|
||||
* @param[in] visitor The visitor.
|
||||
* @param[in, out] visitor_arg The visitor argument.
|
||||
*/
|
||||
void rtems_profiling_iterate(
|
||||
rtems_profiling_visitor visitor,
|
||||
void *visitor_arg
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Function for formatted output.
|
||||
*
|
||||
* @param[in, out] arg Some argument.
|
||||
* @param[in] format The output format as specified by printf().
|
||||
* @param[in] ... More parameters according to format.
|
||||
*
|
||||
* @returns As specified by printf().
|
||||
*
|
||||
* @see rtems_profiling_report_xml().
|
||||
*/
|
||||
typedef int (*rtems_profiling_printf)(void *arg, const char *format, ...);
|
||||
|
||||
/**
|
||||
* @brief Reports profiling data as XML.
|
||||
*
|
||||
* @param[in] name The name of the profiling report.
|
||||
* @param[in] printf_func The formatted output function.
|
||||
* @param[in, out] printf_arg The formatted output function argument.
|
||||
* @param[in] indentation_level The current indentation level.
|
||||
* @param[in] indentation The string used for indentation.
|
||||
*
|
||||
* @returns As specified by printf().
|
||||
*/
|
||||
int rtems_profiling_report_xml(
|
||||
const char *name,
|
||||
rtems_profiling_printf printf_func,
|
||||
void *printf_arg,
|
||||
uint32_t indentation_level,
|
||||
const char *indentation
|
||||
);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _RTEMS_PROFILING_H */
|
||||
@@ -72,6 +72,10 @@ $(PROJECT_INCLUDE)/rtems/cbs.h: include/rtems/cbs.h $(PROJECT_INCLUDE)/rtems/$(d
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/cbs.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/cbs.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/profiling.h: include/rtems/profiling.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/profiling.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/profiling.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/rbheap.h: include/rtems/rbheap.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rbheap.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rbheap.h
|
||||
|
||||
26
cpukit/sapi/src/profilingiterate.c
Normal file
26
cpukit/sapi/src/profilingiterate.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/profiling.h>
|
||||
|
||||
void rtems_profiling_iterate(
|
||||
rtems_profiling_visitor visitor,
|
||||
void *visitor_arg
|
||||
)
|
||||
{
|
||||
}
|
||||
96
cpukit/sapi/src/profilingreportxml.c
Normal file
96
cpukit/sapi/src/profilingreportxml.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/profiling.h>
|
||||
|
||||
#ifdef RTEMS_PROFILING
|
||||
|
||||
typedef struct {
|
||||
rtems_profiling_printf printf_func;
|
||||
void *printf_arg;
|
||||
uint32_t indentation_level;
|
||||
const char *indentation;
|
||||
int retval;
|
||||
} context;
|
||||
|
||||
static void update_retval(context *ctx, int rv)
|
||||
{
|
||||
if (rv > 0 && ctx->retval >= 0) {
|
||||
ctx->retval += rv;
|
||||
}
|
||||
}
|
||||
|
||||
static void indent(context *ctx, uint32_t indentation_level)
|
||||
{
|
||||
uint32_t n = ctx->indentation_level + indentation_level;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
int rv = (*ctx->printf_func)(ctx->printf_arg, "%s", ctx->indentation);
|
||||
|
||||
update_retval(ctx, rv);
|
||||
}
|
||||
}
|
||||
|
||||
static void report(void *arg, const rtems_profiling_data *data)
|
||||
{
|
||||
context *ctx = arg;
|
||||
}
|
||||
|
||||
#endif /* RTEMS_PROFILING */
|
||||
|
||||
int rtems_profiling_report_xml(
|
||||
const char *name,
|
||||
rtems_profiling_printf printf_func,
|
||||
void *printf_arg,
|
||||
uint32_t indentation_level,
|
||||
const char *indentation
|
||||
)
|
||||
{
|
||||
#ifdef RTEMS_PROFILING
|
||||
context ctx_instance = {
|
||||
.printf_func = printf_func,
|
||||
.printf_arg = printf_arg,
|
||||
.indentation_level = indentation_level,
|
||||
.indentation = indentation,
|
||||
.retval = 0
|
||||
};
|
||||
context *ctx = &ctx_instance;
|
||||
int rv;
|
||||
|
||||
indent(ctx, 0);
|
||||
rv = (*printf_func)(printf_arg, "<ProfilingReport name=\"%s\">\n", name);
|
||||
update_retval(ctx, rv);
|
||||
|
||||
rtems_profiling_iterate(report, ctx);
|
||||
|
||||
indent(ctx, 0);
|
||||
rv = (*printf_func)(printf_arg, "</ProfilingReport>\n");
|
||||
update_retval(ctx, rv);
|
||||
|
||||
return ctx->retval;
|
||||
#else /* RTEMS_PROFILING */
|
||||
(void) name;
|
||||
(void) printf_func;
|
||||
(void) printf_arg;
|
||||
(void) indentation_level;
|
||||
(void) indentation;
|
||||
|
||||
return 0;
|
||||
#endif /* RTEMS_PROFILING */
|
||||
}
|
||||
@@ -30,6 +30,7 @@ SUBDIRS = \
|
||||
spsimplesched03 spnsext01 spedfsched01 spedfsched02 spedfsched03 \
|
||||
spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01 \
|
||||
spregion_err01 sppartition_err01
|
||||
SUBDIRS += spprofiling01
|
||||
SUBDIRS += spcache01
|
||||
SUBDIRS += sptls03
|
||||
SUBDIRS += spcpucounter01
|
||||
|
||||
@@ -36,6 +36,7 @@ AM_CONDITIONAL(HAS_CPUSET,test x"${ac_cv_header_sys_cpuset_h}" = x"yes")
|
||||
|
||||
# Explicitly list all Makefiles here
|
||||
AC_CONFIG_FILES([Makefile
|
||||
spprofiling01/Makefile
|
||||
spcache01/Makefile
|
||||
sptls03/Makefile
|
||||
spcpucounter01/Makefile
|
||||
|
||||
19
testsuites/sptests/spprofiling01/Makefile.am
Normal file
19
testsuites/sptests/spprofiling01/Makefile.am
Normal file
@@ -0,0 +1,19 @@
|
||||
rtems_tests_PROGRAMS = spprofiling01
|
||||
spprofiling01_SOURCES = init.c
|
||||
|
||||
dist_rtems_tests_DATA = spprofiling01.scn spprofiling01.doc
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../automake/compile.am
|
||||
include $(top_srcdir)/../automake/leaf.am
|
||||
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
||||
|
||||
LINK_OBJS = $(spprofiling01_OBJECTS)
|
||||
LINK_LIBS = $(spprofiling01_LDLIBS)
|
||||
|
||||
spprofiling01$(EXEEXT): $(spprofiling01_OBJECTS) $(spprofiling01_DEPENDENCIES)
|
||||
@rm -f spprofiling01$(EXEEXT)
|
||||
$(make-exe)
|
||||
|
||||
include $(top_srcdir)/../automake/local.am
|
||||
63
testsuites/sptests/spprofiling01/init.c
Normal file
63
testsuites/sptests/spprofiling01/init.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/profiling.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tmacros.h"
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
int rv;
|
||||
|
||||
sc = rtems_task_wake_after(3);
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
|
||||
rv = rtems_profiling_report_xml("X", rtems_printf_plugin, NULL, 1, " ");
|
||||
printf("characters produced by rtems_profiling_report_xml(): %i\n", rv);
|
||||
}
|
||||
|
||||
static void Init(rtems_task_argument arg)
|
||||
{
|
||||
puts("\n\n*** TEST SPPROFILING 1 ***");
|
||||
|
||||
test();
|
||||
|
||||
puts("*** END OF TEST SPPROFILING 1 ***");
|
||||
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||
|
||||
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
||||
|
||||
#define CONFIGURE_MAXIMUM_TASKS 1
|
||||
|
||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||
|
||||
#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
#include <rtems/confdefs.h>
|
||||
11
testsuites/sptests/spprofiling01/spprofiling01.doc
Normal file
11
testsuites/sptests/spprofiling01/spprofiling01.doc
Normal file
@@ -0,0 +1,11 @@
|
||||
This file describes the directives and concepts tested by this test set.
|
||||
|
||||
test set name: spprofiling01
|
||||
|
||||
directives:
|
||||
|
||||
- rtems_profiling_report_xml()
|
||||
|
||||
concepts:
|
||||
|
||||
- Ensure that rtems_profiling_report_xml() yields the expected output.
|
||||
5
testsuites/sptests/spprofiling01/spprofiling01.scn
Normal file
5
testsuites/sptests/spprofiling01/spprofiling01.scn
Normal file
@@ -0,0 +1,5 @@
|
||||
*** TEST SPPROFILING 1 ***
|
||||
<ProfilingReport name="X">
|
||||
</ProfilingReport>
|
||||
characters produced by rtems_profiling_report_xml(): 50
|
||||
*** END OF TEST SPPROFILING 1 ***
|
||||
Reference in New Issue
Block a user