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:
parent
8c85c15a2f
commit
efd8e246cc
7 changed files with 249 additions and 0 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
152
include/misc/profiler.h
Normal 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__ */
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
71
kernel/nanokernel/profiler.c
Normal file
71
kernel/nanokernel/profiler.c
Normal 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));
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue