mirror of
https://github.com/apache/nuttx.git
synced 2026-05-24 16:11:56 +08:00
libc: add instrument api support
Add registration function instrumentation API, which can achieve instrumentation of entering and exiting functions through the compiler's functionality. We can use CONFIG_ARCH_INSTRUMENT_ALL to add instrumentation for all source, or add '-finstrument-functions' to CFLAGS for Part of the source. Notice: 1. use CONFIG_ARCH_INSTRUMENT_ALL must mark _start or entry noinstrument_function, becuase bss not set. 2. Make sure your callbacks are not instrumented recursively. use instrument_register to register entry function and exit function. They will be called by the instrumented function Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
+43
-23
@@ -40,9 +40,14 @@
|
||||
#include <nuttx/note/notelog_driver.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/sched_note.h>
|
||||
#include <nuttx/instrument.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_DRIVERS_NOTERAM) + defined(CONFIG_DRIVERS_NOTELOG) + \
|
||||
defined(CONFIG_DRIVERS_NOTESNAP) + defined(CONFIG_DRIVERS_NOTERTT) + \
|
||||
defined(CONFIG_SEGGER_SYSVIEW) > CONFIG_DRIVERS_NOTE_MAX
|
||||
@@ -150,6 +155,18 @@ struct note_taskname_s
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_FUNCTION
|
||||
static void note_driver_instrument_enter(FAR void *this_fn,
|
||||
FAR void *call_site, FAR void *arg) noinstrument_function;
|
||||
static void note_driver_instrument_leave(FAR void *this_fn,
|
||||
FAR void *call_site, FAR void *arg) noinstrument_function;
|
||||
static struct instrument_s g_note_instrument =
|
||||
{
|
||||
.entry = note_driver_instrument_enter,
|
||||
.exit = note_driver_instrument_leave,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
|
||||
static struct note_filter_s g_note_filter =
|
||||
{
|
||||
@@ -1924,6 +1941,22 @@ FAR const char *note_get_taskname(pid_t pid)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_FUNCTION
|
||||
static void note_driver_instrument_enter(FAR void *this_fn,
|
||||
FAR void *call_site,
|
||||
FAR void *arg)
|
||||
{
|
||||
sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "B");
|
||||
}
|
||||
|
||||
static void note_driver_instrument_leave(FAR void *this_fn,
|
||||
FAR void *call_site,
|
||||
FAR void *arg)
|
||||
{
|
||||
sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "E");
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: note_driver_register
|
||||
****************************************************************************/
|
||||
@@ -1931,8 +1964,17 @@ FAR const char *note_get_taskname(pid_t pid)
|
||||
int note_driver_register(FAR struct note_driver_s *driver)
|
||||
{
|
||||
int i;
|
||||
DEBUGASSERT(driver);
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_FUNCTION
|
||||
static bool initialized;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
instrument_register(g_note_instrument)
|
||||
initialized = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(driver);
|
||||
for (i = 0; i < CONFIG_DRIVERS_NOTE_MAX; i++)
|
||||
{
|
||||
if (g_note_drivers[i] == NULL)
|
||||
@@ -1945,25 +1987,3 @@ int note_driver_register(FAR struct note_driver_s *driver)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_FUNCTION
|
||||
|
||||
/****************************************************************************
|
||||
* Name: __cyg_profile_func_enter
|
||||
****************************************************************************/
|
||||
|
||||
void noinstrument_function
|
||||
__cyg_profile_func_enter(void *this_fn, void *call_site)
|
||||
{
|
||||
sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "B");
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: __cyg_profile_func_exit
|
||||
****************************************************************************/
|
||||
|
||||
void noinstrument_function
|
||||
__cyg_profile_func_exit(void *this_fn, void *call_site)
|
||||
{
|
||||
sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "E");
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user