Add profiler method.

Add a standardized mechanism to add profiling points to the Kernel
with a single interface for the user to collect the profiling data.

Change-Id: I4fa34ac1b42f73a73ba1fd805e755ee2fd00dff7
Signed-off-by: Yonattan Louise <yonattan.a.louise.mendoza@intel.com>
This commit is contained in:
Yonattan Louise 2015-07-31 15:58:09 -05:00 committed by Anas Nashif
commit efd8e246cc
7 changed files with 249 additions and 0 deletions

View file

@ -14,6 +14,8 @@ CONFIG_SYS_CLOCK_EXISTS=y
CONFIG_XIP=y CONFIG_XIP=y
# CONFIG_ENHANCED_SECURITY is not set # CONFIG_ENHANCED_SECURITY is not set
# CONFIG_EVENT_LOGGER is not set # CONFIG_EVENT_LOGGER is not set
# CONFIG_KERNEL_PROFILER is not set
# CONFIG_PROFILER_BUFFER_SIZE is not set
# #
# Nanokernel Options # Nanokernel Options

View file

@ -15,6 +15,8 @@ CONFIG_SYS_CLOCK_EXISTS=y
CONFIG_XIP=y CONFIG_XIP=y
# CONFIG_ENHANCED_SECURITY is not set # CONFIG_ENHANCED_SECURITY is not set
# CONFIG_EVENT_LOGGER is not set # CONFIG_EVENT_LOGGER is not set
# CONFIG_KERNEL_PROFILER is not set
# CONFIG_PROFILER_BUFFER_SIZE is not set
# #
# Nanokernel Options # Nanokernel Options

View file

@ -17,6 +17,8 @@ CONFIG_SYS_CLOCK_EXISTS=y
# CONFIG_XIP is not set # CONFIG_XIP is not set
CONFIG_ENHANCED_SECURITY=y CONFIG_ENHANCED_SECURITY=y
# CONFIG_EVENT_LOGGER is not set # CONFIG_EVENT_LOGGER is not set
# CONFIG_KERNEL_PROFILER is not set
# CONFIG_PROFILER_BUFFER_SIZE is not set
# #
# Security Options # Security Options

152
include/misc/profiler.h Normal file
View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2015 Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* @file
* @brief Profiler support.
*/
#include <misc/event_logger.h>
#ifndef __PROFILE_H__
#define __PROFILE_H__
#ifdef CONFIG_KERNEL_PROFILER
/**
* Global variable of the ring buffer that allows user to implement
* their own reading routine.
*/
struct event_logger sys_profiler_logger;
/**
* @brief Sends a profile event message to the profiler.
*
* @details Sends a profile message to the profiler logger
* and informs that there are messages available.
*
* @param event_id The identification of the profiler event.
* @param data Pointer to the data of the message.
* @param data_size Size of the data in 32-bit words.
*
* @return No return value.
*/
#define sys_profiler_put(event_id, data, data_size) \
sys_event_logger_put(&sys_profiler_logger, event_id, data, data_size)
/**
* @brief Sends a profile event message to the profiler with the current
* timestamp.
*
* @details Sends a profile message to the profiler logger and informs that
* there messages available. The timestamp when the event occurred is stored
* as part of the event message.
*
* @param event_id The identification of the profiler event.
*
* @return No return value.
*/
void sys_profiler_put_timed(uint16_t event_id);
/**
* @brief Retrieves a profiler event message.
*
* @details Retrieves a profiler event message copying it to the provided
* buffer. If the buffer is smaller than the message size the function returns
* an error. The function retrieves messages in FIFO order.
*
* @param buffer Pointer to the buffer where the message will be copied.
* @param buffer_size Size of the buffer in 32-bit words.
*
* @return -EMSGSIZE if the buffer size is smaller than the message size,
* the amount of 32-bit words copied or zero if there are no profile event
* messages available.
*/
#define sys_profiler_get(buffer, buffer_size) \
sys_event_logger_get(&sys_profiler_logger, buffer, buffer_size)
/**
* @brief Retrieves a profiler event message, wait if there is no message
* available.
*
* @details Retrieves a profiler event message copying it to the provided
* buffer. If the buffer is smaller than the message size the function returns
* an error. The function retrieves messages in FIFO order. If there is no
* profiler event message available the caller pends until a new message is
* logged.
*
* @param buffer Pointer to the buffer where the message will be copied.
* @param buffer_size Size of the buffer in 32-bit words.
*
* @return -EMSGSIZE if the buffer size is smaller than the message size, or
* the amount of 32-bit words copied.
*/
#define sys_profiler_get_wait(buffer, buffer_size) \
sys_event_logger_get_wait(&sys_profiler_logger, buffer, buffer_size)
#ifdef CONFIG_NANO_TIMEOUTS
/**
* @brief Retrieves a profiler event message, wait with a timeout if there is
* no profiling event messages available.
*
* @details Retrieves a profiler event message copying it to the provided
* buffer. If the buffer is smaller than the message size the function returns
* an error. The function retrieves messages in FIFO order. If there are no
* profiler event messages available the caller pends until a new message is
* logged or the timeout expires.
*
* @param buffer Pointer to the buffer where the message will be copied.
* @param buffer_size Size of the buffer in 32-bit words.
* @param timeout Timeout in ticks.
*
* @return -EMSGSIZE if the buffer size is smaller than the message size, the
* amount of 32-bit words copied or zero if the timeout expires and the was no
* message available.
*/
#define sys_profiler_get_wait_timeout(buffer, buffer_size, timeout) \
sys_event_logger_get_wait_timeout(&sys_profiler_logger, buffer, \
buffer_size, timeout)
#endif /* CONFIG_NANO_TIMEOUTS */
#else /* !CONFIG_KERNEL_PROFILER */
static inline void sys_profiler_put(uint16_t event_id, uint32_t *event_data,
uint8_t data_size) {};
static inline void sys_profiler_put_timed(uint16_t event_id) {};
#endif /* CONFIG_KERNEL_PROFILER */
#endif /* __PROFILE_H__ */

View file

@ -111,6 +111,25 @@ config EVENT_LOGGER
Enable event logging feature. Allow the usage of a ring buffer to Enable event logging feature. Allow the usage of a ring buffer to
transmit event messages with a single interface to collect them. transmit event messages with a single interface to collect them.
config KERNEL_PROFILER
bool
prompt "Enable profiler features"
default n
select EVENT_LOGGER
help
This feature enables the usage of the profiling logger. Provides the
logging of sleep events (either entering or leaving low power conditions),
context switch events, interrupt events, boot events and a method to
collect these profile messages.
config PROFILER_BUFFER_SIZE
int
prompt "Profiler buffer size"
default 128
depends on KERNEL_PROFILER
help
Buffer size in 32-bit words.
menu "Security Options" menu "Security Options"
depends on ENHANCED_SECURITY depends on ENHANCED_SECURITY

View file

@ -14,3 +14,4 @@ obj-$(CONFIG_INT_LATENCY_BENCHMARK) += int_latency_bench.o
obj-$(CONFIG_ADVANCED_POWER_MANAGEMENT) += idle.o obj-$(CONFIG_ADVANCED_POWER_MANAGEMENT) += idle.o
obj-$(CONFIG_NANO_TIMERS) += nano_timer.o obj-$(CONFIG_NANO_TIMERS) += nano_timer.o
obj-$(CONFIG_EVENT_LOGGER) += event_logger.o obj-$(CONFIG_EVENT_LOGGER) += event_logger.o
obj-$(CONFIG_KERNEL_PROFILER) += profiler.o

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2015 Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* @file
* @brief Profiler support.
*/
#include <misc/profiler.h>
#include <misc/util.h>
#include <init.h>
uint32_t _sys_profiler_buffer[CONFIG_PROFILER_BUFFER_SIZE];
/**
* @brief Initialize the profiler system.
*
* @details Initialize the ring buffer and the sync semaphore.
*
* @return No return value.
*/
static int _sys_profiler_init(struct device *arg)
{
ARG_UNUSED(arg);
sys_event_logger_init(&sys_profiler_logger, _sys_profiler_buffer,
CONFIG_PROFILER_BUFFER_SIZE);
return 0;
}
DECLARE_DEVICE_INIT_CONFIG(profiler_0, "", _sys_profiler_init, NULL);
nano_early_init(profiler_0, NULL);
void sys_profiler_put_timed(uint16_t event_id)
{
uint32_t data[1];
data[0] = nano_tick_get_32();
sys_event_logger_put(&sys_profiler_logger, event_id, data,
ARRAY_SIZE(data));
}