feat(profiler_builtin): support nanosecond accuracy (#7415)

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
VIFEX
2024-12-06 09:41:15 +08:00
committed by GitHub
parent 945064f6ea
commit 58990cdb5b
5 changed files with 38 additions and 25 deletions

View File

@@ -45,12 +45,13 @@ To enable the profiler, set :c:macro:`LV_USE_PROFILER` in ``lv_conf.h`` and conf
#include <sys/syscall.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
static uint32_t my_get_tick_us_cb(void)
static uint64_t my_get_tick_us_cb(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
return ts.tv_sec * 1000000000 + ts.tv_nsec;
}
static int my_get_tid_cb(void)
@@ -69,7 +70,7 @@ To enable the profiler, set :c:macro:`LV_USE_PROFILER` in ``lv_conf.h`` and conf
{
lv_profiler_builtin_config_t config;
lv_profiler_builtin_config_init(&config);
config.tick_per_sec = 1000000; /* One second is equal to 1000000 microseconds */
config.tick_per_sec = 1000000000; /* One second is equal to 1000000000 nanoseconds */
config.tick_get_cb = my_get_tick_us_cb;
config.tid_get_cb = my_get_tid_cb;
config.cpu_get_cb = my_get_cpu_cb;
@@ -80,12 +81,18 @@ To enable the profiler, set :c:macro:`LV_USE_PROFILER` in ``lv_conf.h`` and conf
.. code-block:: c
static uint64_t my_get_tick_us_cb(void)
{
/* Use the microsecond time stamp provided by Arduino */
return micros();
}
void my_profiler_init(void)
{
lv_profiler_builtin_config_t config;
lv_profiler_builtin_config_init(&config);
config.tick_per_sec = 1000000; /* One second is equal to 1000000 microseconds */
config.tick_get_cb = micros; /* Use the microsecond time stamp provided by Arduino */
config.tick_get_cb = my_get_tick_us_cb;
lv_profiler_builtin_init(&config);
}

View File

@@ -19,7 +19,7 @@
* DEFINES
*********************/
#define TICK_TO_USEC(tick) ((tick) / cpu_freq)
#define TICK_TO_NSEC(tick) ((tick) * 1000 / cpu_freq)
/**********************
* TYPEDEFS
@@ -35,7 +35,7 @@ static uint32_t cpu_freq = 0; /* MHz */
* STATIC VARIABLES
**********************/
static uint32_t tick_get_cb(void);
static uint64_t tick_get_cb(void);
static void flush_cb(const char * buf);
/**********************
@@ -57,7 +57,7 @@ void lv_nuttx_profiler_init(void)
lv_profiler_builtin_config_t config;
lv_profiler_builtin_config_init(&config);
config.tick_per_sec = 1000000; /* 1 sec = 1000000 usec */
config.tick_per_sec = 1000000000; /* 1 sec = 1000000000 nsec */
config.tick_get_cb = tick_get_cb;
config.flush_cb = flush_cb;
lv_profiler_builtin_init(&config);
@@ -67,10 +67,10 @@ void lv_nuttx_profiler_init(void)
* STATIC FUNCTIONS
**********************/
static uint32_t tick_get_cb(void)
static uint64_t tick_get_cb(void)
{
static uint32_t prev_tick = 0;
static uint32_t cur_tick_us = 0;
static uint64_t cur_tick_ns = 0;
uint32_t act_time = up_perf_gettime();
uint32_t elaps;
@@ -83,9 +83,9 @@ static uint32_t tick_get_cb(void)
elaps += act_time;
}
cur_tick_us += TICK_TO_USEC(elaps);
cur_tick_ns += TICK_TO_NSEC(elaps);
prev_tick = act_time;
return cur_tick_us;
return cur_tick_ns;
}
static void flush_cb(const char * buf)

View File

@@ -20,7 +20,7 @@
#define profiler_ctx LV_GLOBAL_DEFAULT()->profiler_context
#define LV_PROFILER_STR_MAX_LEN 128
#define LV_PROFILER_TICK_PER_SEC_MAX 1000000
#define LV_PROFILER_TICK_PER_SEC_MAX 1000000000 /* Maximum accuracy: 1 nanosecond */
#if LV_USE_OS
#define LV_PROFILER_MULTEX_INIT lv_mutex_init(&profiler_ctx->mutex)
@@ -42,8 +42,8 @@
* @brief Structure representing a built-in profiler item in LVGL
*/
typedef struct {
uint64_t tick; /**< The tick value of the profiler item */
char tag; /**< The tag of the profiler item */
uint32_t tick; /**< The tick value of the profiler item */
const char * func; /**< A pointer to the function associated with the profiler item */
#if LV_USE_OS
int tid; /**< The thread ID of the profiler item */
@@ -69,6 +69,7 @@ typedef struct _lv_profiler_builtin_ctx_t {
* STATIC PROTOTYPES
**********************/
static uint64_t default_tick_get_cb(void);
static void default_flush_cb(const char * buf);
static int default_tid_get_cb(void);
static int default_cpu_get_cb(void);
@@ -92,7 +93,7 @@ void lv_profiler_builtin_config_init(lv_profiler_builtin_config_t * config)
lv_memzero(config, sizeof(lv_profiler_builtin_config_t));
config->buf_size = LV_PROFILER_BUILTIN_BUF_SIZE;
config->tick_per_sec = 1000;
config->tick_get_cb = lv_tick_get;
config->tick_get_cb = default_tick_get_cb;
config->flush_cb = default_flush_cb;
config->tid_get_cb = default_tid_get_cb;
config->cpu_get_cb = default_cpu_get_cb;
@@ -208,6 +209,11 @@ void lv_profiler_builtin_write(const char * func, char tag)
* STATIC FUNCTIONS
**********************/
static uint64_t default_tick_get_cb(void)
{
return lv_tick_get();
}
static void default_flush_cb(const char * buf)
{
LV_LOG("%s", buf);
@@ -236,22 +242,22 @@ static void flush_no_lock(void)
while(cur < profiler_ctx->cur_index) {
lv_profiler_builtin_item_t * item = &profiler_ctx->item_arr[cur++];
uint32_t sec = item->tick / tick_per_sec;
uint32_t usec = (item->tick % tick_per_sec) * (LV_PROFILER_TICK_PER_SEC_MAX / tick_per_sec);
uint32_t nsec = (item->tick % tick_per_sec) * (LV_PROFILER_TICK_PER_SEC_MAX / tick_per_sec);
#if LV_USE_OS
lv_snprintf(buf, sizeof(buf),
" LVGL-%d [%d] %" LV_PRIu32 ".%06" LV_PRIu32 ": tracing_mark_write: %c|1|%s\n",
" LVGL-%d [%d] %" LV_PRIu32 ".%09" LV_PRIu32 ": tracing_mark_write: %c|1|%s\n",
item->tid,
item->cpu,
sec,
usec,
nsec,
item->tag,
item->func);
#else
lv_snprintf(buf, sizeof(buf),
" LVGL-1 [0] %" LV_PRIu32 ".%06" LV_PRIu32 ": tracing_mark_write: %c|1|%s\n",
" LVGL-1 [0] %" LV_PRIu32 ".%09" LV_PRIu32 ": tracing_mark_write: %c|1|%s\n",
sec,
usec,
nsec,
item->tag,
item->func);
#endif

View File

@@ -32,7 +32,7 @@ extern "C" {
struct _lv_profiler_builtin_config_t {
size_t buf_size; /**< The size of the buffer used for profiling data */
uint32_t tick_per_sec; /**< The number of ticks per second */
uint32_t (*tick_get_cb)(void); /**< Callback function to get the current tick count */
uint64_t (*tick_get_cb)(void); /**< Callback function to get the current tick count */
void (*flush_cb)(const char * buf); /**< Callback function to flush the profiling data */
int (*tid_get_cb)(void); /**< Callback function to get the current thread ID */
int (*cpu_get_cb)(void); /**< Callback function to get the current CPU */

View File

@@ -12,7 +12,7 @@ static uint32_t profiler_tick = 0;
static int output_line = 0;
static char output_buf[OUTPUT_LINE_MAX][OUTPUT_BUF_MAX];
static uint32_t get_tick_cb(void)
static uint64_t get_tick_cb(void)
{
return profiler_tick++;
}
@@ -64,10 +64,10 @@ void test_profiler_normal(void)
/* check output */
TEST_ASSERT_EQUAL_INT(output_line, 4);
TEST_ASSERT_EQUAL_INT(profiler_tick, 4);
TEST_ASSERT_EQUAL_STRING(output_buf[0], " LVGL-1 [0] 0.000000: tracing_mark_write: B|1|test_profiler_normal\n");
TEST_ASSERT_EQUAL_STRING(output_buf[1], " LVGL-1 [0] 1.000000: tracing_mark_write: E|1|test_profiler_normal\n");
TEST_ASSERT_EQUAL_STRING(output_buf[2], " LVGL-1 [0] 2.000000: tracing_mark_write: B|1|custom_tag\n");
TEST_ASSERT_EQUAL_STRING(output_buf[3], " LVGL-1 [0] 3.000000: tracing_mark_write: E|1|custom_tag\n");
TEST_ASSERT_EQUAL_STRING(output_buf[0], " LVGL-1 [0] 0.000000000: tracing_mark_write: B|1|test_profiler_normal\n");
TEST_ASSERT_EQUAL_STRING(output_buf[1], " LVGL-1 [0] 1.000000000: tracing_mark_write: E|1|test_profiler_normal\n");
TEST_ASSERT_EQUAL_STRING(output_buf[2], " LVGL-1 [0] 2.000000000: tracing_mark_write: B|1|custom_tag\n");
TEST_ASSERT_EQUAL_STRING(output_buf[3], " LVGL-1 [0] 3.000000000: tracing_mark_write: E|1|custom_tag\n");
}
void test_profiler_disable(void)