diff --git a/Documentation/components/drivers/special/segger.rst b/Documentation/components/drivers/special/segger.rst index 29097de3b82ac..e22a420afd6d8 100644 --- a/Documentation/components/drivers/special/segger.rst +++ b/Documentation/components/drivers/special/segger.rst @@ -17,7 +17,7 @@ Supported Segger drivers: Segger SystemView ================= -Steps to enable SystemView support: +1. Steps to enable SystemView support: #. Make sure your architecture supports a high-performance counter. In most cases it will be: @@ -62,3 +62,14 @@ Steps to enable SystemView support: In case SystemView returns buffer overflow errors, you should increase ``CONFIG_NOTE_RTT_BUFFER_SIZE_UP``. + +2. Use SystemView for heap tracing: + +Refer to example configuration at ``stm32f429i-disco/configs/systemview``. +Make sure that ``CONFIG_SCHED_INSTRUMENTATION_HEAP`` is enabled. + +Example of screenshot from SystemView: + +.. image:: sysview.png + :width: 800px + :align: center diff --git a/Documentation/components/drivers/special/sysview.png b/Documentation/components/drivers/special/sysview.png new file mode 100644 index 0000000000000..d5f8709631504 Binary files /dev/null and b/Documentation/components/drivers/special/sysview.png differ diff --git a/arch/arm/include/cxd56xx/crashdump.h b/arch/arm/include/cxd56xx/crashdump.h index 72dd29644b3fc..6bb852aa9d5c6 100644 --- a/arch/arm/include/cxd56xx/crashdump.h +++ b/arch/arm/include/cxd56xx/crashdump.h @@ -100,19 +100,17 @@ typedef enum typedef struct { - struct timespec ts; /* timestamp */ - fault_flags_t flags; /* What is in the dump */ - uintptr_t current_regs; /* Used to validate the dump */ - int lineno; /* __LINE__ to up_assert */ - pid_t pid; /* Process ID */ - uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ - crash_stack_t stacks; /* Stack info */ -#if CONFIG_TASK_NAME_SIZE > 0 - char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL - * terminator) */ -#endif - char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in - * __FILE__ to up_assert */ + struct timespec ts; /* timestamp */ + fault_flags_t flags; /* What is in the dump */ + uintptr_t current_regs; /* Used to validate the dump */ + int lineno; /* __LINE__ to up_assert */ + pid_t pid; /* Process ID */ + uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ + crash_stack_t stacks; /* Stack info */ + char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL + * terminator) */ + char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in + * __FILE__ to up_assert */ } info_t; typedef struct diff --git a/arch/risc-v/src/bl602/bl602_start.c b/arch/risc-v/src/bl602/bl602_start.c index 104a72bc2f56f..c3ecc556afe89 100644 --- a/arch/risc-v/src/bl602/bl602_start.c +++ b/arch/risc-v/src/bl602/bl602_start.c @@ -99,28 +99,21 @@ __cyg_profile_func_enter(void *this_fn, void *call_site) if (sp < stack_base) { -#if CONFIG_TASK_NAME_SIZE > 0 struct tcb_s *rtcb; -#endif + __asm volatile("csrc mstatus, 8"); __asm__("li s11, 0"); -#if CONFIG_TASK_NAME_SIZE > 0 /* get current task */ rtcb = running_task(); syslog(LOG_EMERG, "task %s stack overflow detected! base:0x%x >= sp:0x%x\n", - rtcb->name, - stack_base, - sp); -#else - syslog(LOG_EMERG, - "stack overflow detected! base:0x%x >= sp:0x%x\n", + get_task_name(rtcb), stack_base, sp); -#endif + /* PANIC(); */ while (1) diff --git a/arch/risc-v/src/common/riscv_exception.c b/arch/risc-v/src/common/riscv_exception.c index 1995f12ada22b..482bc8975f387 100644 --- a/arch/risc-v/src/common/riscv_exception.c +++ b/arch/risc-v/src/common/riscv_exception.c @@ -103,11 +103,8 @@ int riscv_exception(int mcause, void *regs, void *args) #ifdef CONFIG_ARCH_KERNEL_STACK if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) { -# if CONFIG_TASK_NAME_SIZE > 0 - _alert("Segmentation fault in PID %d: %s\n", tcb->pid, tcb->name); -# else - _alert("Segmentation fault in PID %d\n", tcb->pid); -# endif + _alert("Segmentation fault in PID %d: %s\n", + tcb->pid, get_task_name(tcb)); tcb->flags |= TCB_FLAG_FORCED_CANCEL; diff --git a/arch/sim/src/sim/sim_heap.c b/arch/sim/src/sim/sim_heap.c index a3ccb2bb406c3..e95b559ff1213 100644 --- a/arch/sim/src/sim/sim_heap.c +++ b/arch/sim/src/sim/sim_heap.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "sim_internal.h" @@ -185,6 +186,7 @@ static void mm_delayfree(struct mm_heap_s *heap, void *mem, bool delay) int size = host_mallocsize(mem); atomic_fetch_sub(&heap->aordblks, 1); atomic_fetch_sub(&heap->uordblks, size); + sched_note_heap(NOTE_HEAP_FREE, heap, mem, size, 0); host_free(mem); } } @@ -228,9 +230,37 @@ struct mm_heap_s *mm_initialize(const char *name, procfs_register_meminfo(&heap->mm_procfs); #endif + sched_note_heap(NOTE_HEAP_ADD, heap, heap_start, heap_size, 0); return heap; } +/**************************************************************************** + * Name: mm_uninitialize + * + * Description: + * Uninitialize the selected heap data structures + * + * Input Parameters: + * heap - The selected heap + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +void mm_uninitialize(struct mm_heap_s *heap) +{ + sched_note_heap(NOTE_HEAP_REMOVE, heap, NULL, 0, 0); + +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO) + procfs_unregister_meminfo(&heap->mm_procfs); +#endif + mm_free_delaylist(heap); + host_free(heap); +} + /**************************************************************************** * Name: mm_addregion * @@ -339,6 +369,7 @@ void *mm_realloc(struct mm_heap_s *heap, void *oldmem, int uordblks; int usmblks; int newsize; + int oldsize; free_delaylist(heap, false); @@ -348,13 +379,23 @@ void *mm_realloc(struct mm_heap_s *heap, void *oldmem, return NULL; } - atomic_fetch_sub(&heap->uordblks, host_mallocsize(oldmem)); + oldsize = host_mallocsize(oldmem); + atomic_fetch_sub(&heap->uordblks, oldsize); mem = host_realloc(oldmem, size); atomic_fetch_add(&heap->aordblks, oldmem == NULL && mem != NULL); newsize = host_mallocsize(mem ? mem : oldmem); atomic_fetch_add(&heap->uordblks, newsize); usmblks = atomic_load(&heap->usmblks); + if (mem != NULL) + { + if (oldmem != NULL) + { + sched_note_heap(NOTE_HEAP_FREE, heap, oldmem, oldsize, 0); + } + + sched_note_heap(NOTE_HEAP_ALLOC, heap, mem, newsize, 0); + } do { @@ -445,6 +486,7 @@ void *mm_memalign(struct mm_heap_s *heap, size_t alignment, size_t size) } size = host_mallocsize(mem); + sched_note_heap(NOTE_HEAP_ALLOC, heap, mem, size, 0); atomic_fetch_add(&heap->aordblks, 1); atomic_fetch_add(&heap->uordblks, size); usmblks = atomic_load(&heap->usmblks); diff --git a/arch/xtensa/src/common/xtensa_assert.c b/arch/xtensa/src/common/xtensa_assert.c index 54dfebff2dd6a..0b51bd603ac20 100644 --- a/arch/xtensa/src/common/xtensa_assert.c +++ b/arch/xtensa/src/common/xtensa_assert.c @@ -75,11 +75,8 @@ void xtensa_panic(int xptcode, uint32_t *regs) syslog_flush(); -#if CONFIG_TASK_NAME_SIZE > 0 - _alert("Unhandled Exception %d task: %s\n", xptcode, running_task()->name); -#else - _alert("Unhandled Exception %d\n", xptcode); -#endif + _alert("Unhandled Exception %d task: %s\n", xptcode, + get_task_name(running_task())); PANIC_WITH_REGS("panic", regs); /* Should not return */ for (; ; ); @@ -177,12 +174,8 @@ void xtensa_user_panic(int exccause, uint32_t *regs) syslog_flush(); -#if CONFIG_TASK_NAME_SIZE > 0 _alert("User Exception: EXCCAUSE=%04x task: %s\n", - exccause, running_task()->name); -#else - _alert("User Exception: EXCCAUSE=%04x\n", exccause); -#endif + exccause, get_task_name(running_task())); PANIC_WITH_REGS("user panic", regs); /* Should not return */ for (; ; ); diff --git a/binfmt/libelf/libelf_coredump.c b/binfmt/libelf/libelf_coredump.c index 568654b3b5562..a37bbdeada00c 100644 --- a/binfmt/libelf/libelf_coredump.c +++ b/binfmt/libelf/libelf_coredump.c @@ -248,11 +248,11 @@ static void elf_emit_tcb_note(FAR struct elf_dumpinfo_s *cinfo, elf_emit(cinfo, &nhdr, sizeof(nhdr)); - strlcpy(name, tcb->name, sizeof(name)); + strlcpy(name, get_task_name(tcb), sizeof(name)); elf_emit(cinfo, name, sizeof(name)); info.pr_pid = tcb->pid; - strlcpy(info.pr_fname, tcb->name, sizeof(info.pr_fname)); + strlcpy(info.pr_fname, get_task_name(tcb), sizeof(info.pr_fname)); elf_emit(cinfo, &info, sizeof(info)); /* Fill Process status */ diff --git a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c index c3c37a164c93d..38a0a70f313fc 100644 --- a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c +++ b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c @@ -149,9 +149,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, /* Save Context */ -#if CONFIG_TASK_NAME_SIZE > 0 - strlcpy(pdump->info.name, tcb->name, sizeof(pdump->info.name)); -#endif + strlcpy(pdump->info.name, get_task_name(tcb), sizeof(pdump->info.name)); pdump->info.pid = tcb->pid; diff --git a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c index 9f4c643368f04..982dcca93927d 100644 --- a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c +++ b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c @@ -232,18 +232,16 @@ typedef enum typedef struct { - fault_flags_t flags; /* What is in the dump */ - uintptr_t current_regs; /* Used to validate the dump */ - int lineno; /* __LINE__ to up_assert */ - pid_t pid; /* Process ID */ - uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ - stacks_t stacks; /* Stack info */ -#if CONFIG_TASK_NAME_SIZE > 0 - char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL - * terminator) */ -#endif - char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in - * __FILE__ to up_assert */ + fault_flags_t flags; /* What is in the dump */ + uintptr_t current_regs; /* Used to validate the dump */ + int lineno; /* __LINE__ to up_assert */ + pid_t pid; /* Process ID */ + uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ + stack_t stacks; /* Stack info */ + char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL + * terminator) */ + char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in + * __FILE__ to up_assert */ } info_t; typedef struct @@ -420,9 +418,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, /* Save Context */ -#if CONFIG_TASK_NAME_SIZE > 0 - strlcpy(pdump->info.name, tcb->name, sizeof(pdump->info.name)); -#endif + strlcpy(pdump->info.name, get_task_name(tcb), sizeof(pdump->info.name)); pdump->info.pid = tcb->pid; diff --git a/boards/arm/stm32/stm32f429i-disco/configs/systemview/defconfig b/boards/arm/stm32/stm32f429i-disco/configs/systemview/defconfig index 075534e939ea8..24953158ccf9f 100644 --- a/boards/arm/stm32/stm32f429i-disco/configs/systemview/defconfig +++ b/boards/arm/stm32/stm32f429i-disco/configs/systemview/defconfig @@ -7,6 +7,8 @@ # # CONFIG_ARCH_FPU is not set # CONFIG_DRIVERS_NOTERAM is not set +# CONFIG_SERIAL_RTT_CONSOLE is not set +# CONFIG_STANDARD_SERIAL is not set # CONFIG_STM32_FLASH_PREFETCH is not set CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="stm32f429i-disco" @@ -38,8 +40,10 @@ CONFIG_RAM_START=0x20000000 CONFIG_RAW_BINARY=y CONFIG_RR_INTERVAL=200 CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_HEAP=y CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER=y CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_INSTRUMENTATION_WDOG=y CONFIG_SEGGER_SYSVIEW=y CONFIG_SERIAL_RTT0=y CONFIG_SPI=y @@ -51,8 +55,10 @@ CONFIG_STM32_EXTERNAL_RAM=y CONFIG_STM32_FMC=y CONFIG_STM32_JTAG_SW_ENABLE=y CONFIG_STM32_PWR=y +CONFIG_STM32_USART1=y CONFIG_SYSLOG_CHAR=y CONFIG_SYSLOG_RTT=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_SYSTEM=y CONFIG_TASK_NAME_SIZE=0 +CONFIG_USART1_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c b/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c index 9e11adaaa69be..be29fb27d85b0 100644 --- a/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c +++ b/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c @@ -232,18 +232,16 @@ typedef enum typedef struct { - fault_flags_t flags; /* What is in the dump */ - uintptr_t current_regs; /* Used to validate the dump */ - int lineno; /* __LINE__ to up_assert */ - int pid; /* Process ID */ - uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ - stacks_t stacks; /* Stack info */ -#if CONFIG_TASK_NAME_SIZE > 0 - char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL - * terminator) */ -#endif - char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in - * __FILE__ to up_assert */ + fault_flags_t flags; /* What is in the dump */ + uintptr_t current_regs; /* Used to validate the dump */ + int lineno; /* __LINE__ to up_assert */ + int pid; /* Process ID */ + uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ + stack_t stacks; /* Stack info */ + char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL + * terminator) */ + char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in + * __FILE__ to up_assert */ } info_t; typedef struct @@ -420,9 +418,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, /* Save Context */ -#if CONFIG_TASK_NAME_SIZE > 0 - strlcpy(pdump->info.name, tcb->name, sizeof(pdump->info.name)); -#endif + strlcpy(pdump->info.name, get_task_name(tcb), sizeof(pdump->info.name)); pdump->info.pid = tcb->pid; diff --git a/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c b/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c index 881c785040f5b..601e228567688 100644 --- a/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c +++ b/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c @@ -181,18 +181,16 @@ typedef enum typedef struct { - fault_flags_t flags; /* What is in the dump */ - uintptr_t current_regs; /* Used to validate the dump */ - int lineno; /* __LINE__ to up_assert */ - pid_t pid; /* Process ID */ - uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ - stack_t stacks; /* Stack info */ -#if CONFIG_TASK_NAME_SIZE > 0 - char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL - * terminator) */ -#endif - char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in - * __FILE__ to up_assert */ + fault_flags_t flags; /* What is in the dump */ + uintptr_t current_regs; /* Used to validate the dump */ + int lineno; /* __LINE__ to up_assert */ + pid_t pid; /* Process ID */ + uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ + stack_t stacks; /* Stack info */ + char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL + * terminator) */ + char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in + * __FILE__ to up_assert */ } info_t; struct fullcontext @@ -374,9 +372,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, /* Save Context */ -#if CONFIG_TASK_NAME_SIZE > 0 - strlcpy(pdump->info.name, tcb->name, sizeof(pdump->info.name)); -#endif + strlcpy(pdump->info.name, get_task_name(tcb), sizeof(pdump->info.name)); pdump->info.pid = tcb->pid; diff --git a/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c b/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c index f5918bb850ceb..1925632a4b220 100644 --- a/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c +++ b/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c @@ -181,18 +181,16 @@ typedef enum typedef struct { - fault_flags_t flags; /* What is in the dump */ - uintptr_t current_regs; /* Used to validate the dump */ - int lineno; /* __LINE__ to up_assert */ - pid_t pid; /* Process ID */ - uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ - stack_t stacks; /* Stack info */ -#if CONFIG_TASK_NAME_SIZE > 0 - char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL - * terminator) */ -#endif - char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in - * __FILE__ to up_assert */ + fault_flags_t flags; /* What is in the dump */ + uintptr_t current_regs; /* Used to validate the dump */ + int lineno; /* __LINE__ to up_assert */ + pid_t pid; /* Process ID */ + uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ + stack_t stacks; /* Stack info */ + char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL + * terminator) */ + char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in + * __FILE__ to up_assert */ } info_t; struct fullcontext @@ -372,9 +370,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, /* Save Context */ -#if CONFIG_TASK_NAME_SIZE > 0 - strlcpy(pdump->info.name, tcb->name, sizeof(pdump->info.name)); -#endif + strlcpy(pdump->info.name, get_task_name(tcb), sizeof(pdump->info.name)); pdump->info.pid = tcb->pid; diff --git a/drivers/note/Kconfig b/drivers/note/Kconfig index 49248bd121c63..e5469b6ab9eb0 100644 --- a/drivers/note/Kconfig +++ b/drivers/note/Kconfig @@ -87,6 +87,11 @@ config DRIVERS_NOTERAM_CRASH_DUMP endif # DRIVERS_NOTERAM +config DRIVERS_NOTE_STRIP_FORMAT + bool "Strip sched_note_printf format string" + ---help--- + Strip sched_note_printf format string. + config DRIVERS_NOTELOG bool "Note syslog driver" ---help--- diff --git a/drivers/note/note_driver.c b/drivers/note/note_driver.c index 70c8c2dd035e7..0b4d725c67cdf 100644 --- a/drivers/note/note_driver.c +++ b/drivers/note/note_driver.c @@ -92,14 +92,14 @@ #define note_irqhandler(drv, irq, handler, enter) \ ((drv)->ops->irqhandler && \ ((drv)->ops->irqhandler(drv, irq, handler, enter), true)) -#define note_string(drv, ip, buf) \ - ((drv)->ops->string && ((drv)->ops->string(drv, ip, buf), true)) +#define note_heap(drv, event, data, mem, size, used) \ + ((drv)->ops->heap && ((drv)->ops->heap(drv, event, data, mem, size, used), true)) +#define note_wdog(drv, event, handler, arg) \ + ((drv)->ops->wdog && ((drv)->ops->wdog(drv, event, handler, arg), true)) #define note_event(drv, ip, event, buf, len) \ ((drv)->ops->event && ((drv)->ops->event(drv, ip, event, buf, len), true)) #define note_vprintf(drv, ip, fmt, va) \ ((drv)->ops->vprintf && ((drv)->ops->vprintf(drv, ip, fmt, va), true)) -#define note_vbprintf(drv, ip, fmt, va) \ - ((drv)->ops->vbprintf && ((drv)->ops->vbprintf(drv, ip, fmt, va), true)) /**************************************************************************** * Private Types @@ -585,10 +585,10 @@ static void note_record_taskname(pid_t pid, FAR const char *name) ti = (FAR struct note_taskname_info_s *) &g_note_taskname.buffer[g_note_taskname.head]; - ti->size = tilen; + ti->size = NOTE_ALIGN(tilen); ti->pid = pid; strlcpy(ti->name, name, namelen + 1); - g_note_taskname.head += tilen; + g_note_taskname.head += ti->size; } #endif @@ -1352,24 +1352,17 @@ void sched_note_irqhandler(int irq, FAR void *handler, bool enter) } #endif -#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP -void sched_note_string_ip(uint32_t tag, uintptr_t ip, FAR const char *buf) +#ifdef CONFIG_SCHED_INSTRUMENTATION_WDOG +void sched_note_wdog(uint8_t event, FAR void *handler, FAR const void *arg) { - FAR struct note_string_s *note; - uint8_t data[255]; - unsigned int length; FAR struct note_driver_s **driver; + struct note_wdog_s note; bool formatted = false; FAR struct tcb_s *tcb = this_task(); - if (!note_isenabled_dump(tag)) - { - return; - } - for (driver = g_note_drivers; *driver; driver++) { - if (note_string(*driver, ip, buf)) + if (note_wdog(*driver, event, handler, arg)) { continue; } @@ -1379,48 +1372,40 @@ void sched_note_string_ip(uint32_t tag, uintptr_t ip, FAR const char *buf) continue; } - /* Format the note */ - if (!formatted) { formatted = true; - note = (FAR struct note_string_s *)data; - length = SIZEOF_NOTE_STRING(strlen(buf)); - if (length > sizeof(data)) - { - length = sizeof(data); - } - - note_common(tcb, ¬e->nst_cmn, length, NOTE_DUMP_STRING); - memcpy(note->nst_data, buf, length - sizeof(struct note_string_s)); - data[length - 1] = '\0'; - note->nst_ip = ip; + note_common(tcb, ¬e.nwd_cmn, sizeof(note), event); + note.handler = (uintptr_t)handler; + note.arg = (uintptr_t)arg; } /* Add the note to circular buffer */ - note_add(*driver, note, length); + note_add(*driver, ¬e, sizeof(note)); } } +#endif -void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event, - FAR const void *buf, size_t len) +#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP +void sched_note_heap(uint8_t event, FAR void *heap, FAR void *mem, + size_t size, size_t used) { - FAR struct note_binary_s *note; FAR struct note_driver_s **driver; + struct note_heap_s note; bool formatted = false; - char data[255]; - unsigned int length; FAR struct tcb_s *tcb = this_task(); - if (!note_isenabled_dump(tag)) +#ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER + if (!note_isenabled()) { return; } +#endif for (driver = g_note_drivers; *driver; driver++) { - if (note_event(*driver, ip, event, buf, len)) + if (note_heap(*driver, event, heap, mem, size, used)) { continue; } @@ -1430,38 +1415,32 @@ void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event, continue; } - /* Format the note */ - if (!formatted) { formatted = true; - note = (FAR struct note_binary_s *)data; - length = SIZEOF_NOTE_BINARY(len); - if (length > sizeof(data)) - { - length = sizeof(data); - } - - note_common(tcb, ¬e->nbi_cmn, length, event); - memcpy(note->nbi_data, buf, - length - sizeof(struct note_binary_s) + 1); - note->nbi_ip = ip; + note_common(tcb, ¬e.nhp_cmn, sizeof(note), event); + note.heap = heap; + note.mem = mem; + note.size = size; + note.used = used; } /* Add the note to circular buffer */ - note_add(*driver, note, length); + note_add(*driver, ¬e, sizeof(note)); } } +#endif -void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, - FAR const char *fmt, va_list va) +#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP +void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event, + FAR const void *buf, size_t len) { - FAR struct note_string_s *note; - uint8_t data[255]; - unsigned int length; + FAR struct note_event_s *note; FAR struct note_driver_s **driver; bool formatted = false; + char data[255]; + unsigned int length; FAR struct tcb_s *tcb = this_task(); if (!note_isenabled_dump(tag)) @@ -1471,7 +1450,7 @@ void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, for (driver = g_note_drivers; *driver; driver++) { - if (note_vprintf(*driver, ip, fmt, va)) + if (note_event(*driver, ip, event, buf, len)) { continue; } @@ -1486,19 +1465,16 @@ void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, if (!formatted) { formatted = true; - note = (FAR struct note_string_s *)data; - length = vsnprintf(note->nst_data, - sizeof(data) - sizeof(struct note_string_s), - fmt, - va); - length = SIZEOF_NOTE_STRING(length); + note = (FAR struct note_event_s *)data; + length = SIZEOF_NOTE_EVENT(len); if (length > sizeof(data)) { length = sizeof(data); } - note_common(tcb, ¬e->nst_cmn, length, NOTE_DUMP_STRING); - note->nst_ip = ip; + note_common(tcb, ¬e->nev_cmn, length, event); + note->nev_ip = ip; + memcpy(note->nev_data, buf, length - SIZEOF_NOTE_EVENT(0)); } /* Add the note to circular buffer */ @@ -1507,42 +1483,14 @@ void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, } } -void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip, - FAR const char *fmt, va_list va) +void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, + uint32_t type, va_list va) { - FAR struct note_binary_s *note; + FAR struct note_printf_s *note; FAR struct note_driver_s **driver; bool formatted = false; uint8_t data[255]; - begin_packed_struct union - { - char c; - short s; - int i; - long l; -#ifdef CONFIG_HAVE_LONG_LONG - long long ll; -#endif - intmax_t im; - size_t sz; - ptrdiff_t ptr; -#ifdef CONFIG_HAVE_FLOAT - float f; -#endif -#ifdef CONFIG_HAVE_DOUBLE - double d; -#endif -#ifdef CONFIG_HAVE_LONG_DOUBLE - long double ld; -#endif - } - - end_packed_struct *var; - - char c; - int length; - bool infmt = false; - int next = 0; + size_t length = 0; FAR struct tcb_s *tcb = this_task(); if (!note_isenabled_dump(tag)) @@ -1552,7 +1500,7 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip, for (driver = g_note_drivers; *driver; driver++) { - if (note_vbprintf(*driver, ip, fmt, va)) + if (note_vprintf(*driver, ip, fmt, va)) { continue; } @@ -1566,156 +1514,244 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip, if (!formatted) { + begin_packed_struct union + { + int i; + long l; +#ifdef CONFIG_HAVE_LONG_LONG + long long ll; +#endif + intmax_t im; + size_t sz; + ptrdiff_t ptr; + FAR void *p; + FAR const char *s; +#ifdef CONFIG_HAVE_DOUBLE + double d; +# ifdef CONFIG_HAVE_LONG_DOUBLE + long double ld; +# endif +#endif + } + + end_packed_struct *var; + size_t next = 0; formatted = true; - note = (FAR struct note_binary_s *)data; - length = sizeof(data) - sizeof(struct note_binary_s) + 1; + note = (FAR struct note_printf_s *)data; + length = sizeof(data) - SIZEOF_NOTE_PRINTF(0); - while ((c = *fmt++) != '\0') + if (type) { - if (c != '%' && !infmt) - { - continue; - } + size_t count = NOTE_PRINTF_GET_COUNT(type); + size_t i; - infmt = true; - var = (FAR void *)¬e->nbi_data[next]; - - if (c == 'd' || c == 'i' || c == 'u' || - c == 'o' || c == 'x' || c == 'X') + for (i = 0; i < count; i++) { - if (*(fmt - 2) == 'h' && *(fmt - 3) == 'h') + var = (FAR void *)¬e->npt_data[next]; + switch (NOTE_PRINTF_GET_TYPE(type, i)) { - if (next + sizeof(var->c) > length) + case NOTE_PRINTF_UINT32: { - break; + var->i = va_arg(va, int); + if (next + sizeof(var->i) > length) + { + break; + } + + next += sizeof(var->i); } + break; + case NOTE_PRINTF_UINT64: + { + if (next + sizeof(var->ll) > length) + { + break; + } - var->c = va_arg(va, int); - next += sizeof(var->c); - } - else if (*(fmt - 2) == 'h') - { - if (next + sizeof(var->s) > length) + var->ll = va_arg(va, long long); + next += sizeof(var->ll); + } + break; + case NOTE_PRINTF_STRING: { - break; + size_t len; + var->s = va_arg(va, FAR const char *); + len = strlen(var->s) + 1; + if (next + len > length) + { + len = length - next; + } + + strlcpy(note->npt_data + next, var->s, len); + next += len; } - - var->s = va_arg(va, int); - next += sizeof(var->s); - } - else if (*(fmt - 2) == 'j') - { - if (next + sizeof(var->im) > length) + break; + case NOTE_PRINTF_DOUBLE: { - break; + var->d = va_arg(va, double); + if (next + sizeof(var->d) > length) + { + break; + } + + next += sizeof(var->d); } + break; + } + } + } + else + { + FAR const char *p = fmt; + bool infmt = false; + char c; - var->im = va_arg(va, intmax_t); - next += sizeof(var->im); + while ((c = *p++) != '\0') + { + if (c != '%' && !infmt) + { + continue; } -#ifdef CONFIG_HAVE_LONG_LONG - else if (*(fmt - 2) == 'l' && *(fmt - 3) == 'l') + + infmt = true; + var = (FAR void *)¬e->npt_data[next]; + + if (c == 'c' || c == 'd' || c == 'i' || c == 'u' || + c == 'o' || c == 'x' || c == 'X') { - if (next + sizeof(var->ll) > length) + if (*(p - 2) == 'j') { - break; + if (next + sizeof(var->im) > length) + { + break; + } + + var->im = va_arg(va, intmax_t); + next += sizeof(var->im); } +#ifdef CONFIG_HAVE_LONG_LONG + else if (*(p - 2) == 'l' && *(p - 3) == 'l') + { + if (next + sizeof(var->ll) > length) + { + break; + } - var->ll = va_arg(va, long long); - next += sizeof(var->ll); - } + var->ll = va_arg(va, long long); + next += sizeof(var->ll); + } #endif - else if (*(fmt - 2) == 'l') - { - if (next + sizeof(var->l) > length) + else if (*(p - 2) == 'l') { - break; - } + if (next + sizeof(var->l) > length) + { + break; + } - var->l = va_arg(va, long); - next += sizeof(var->l); - } - else if (*(fmt - 2) == 'z') - { - if (next + sizeof(var->sz) > length) - { - break; + var->l = va_arg(va, long); + next += sizeof(var->l); } - - var->sz = va_arg(va, size_t); - next += sizeof(var->sz); - } - else if (*(fmt - 2) == 't') - { - if (next + sizeof(var->ptr) > length) + else if (*(p - 2) == 'z') { - break; + if (next + sizeof(var->sz) > length) + { + break; + } + + var->sz = va_arg(va, size_t); + next += sizeof(var->sz); } + else if (*(p - 2) == 't') + { + if (next + sizeof(var->ptr) > length) + { + break; + } - var->ptr = va_arg(va, ptrdiff_t); - next += sizeof(var->ptr); - } - else - { - if (next + sizeof(var->i) > length) + var->ptr = va_arg(va, ptrdiff_t); + next += sizeof(var->ptr); + } + else { - break; + if (next + sizeof(var->i) > length) + { + break; + } + + var->i = va_arg(va, int); + next += sizeof(var->i); } - var->i = va_arg(va, int); - next += sizeof(var->i); + infmt = false; } - - infmt = false; - } - - if (c == 'e' || c == 'f' || c == 'g' || - c == 'E' || c == 'F' || c == 'G') - { - if (*(fmt - 2) == 'L') + else if (c == 'e' || c == 'f' || c == 'g' || c == 'a' || + c == 'A' || c == 'E' || c == 'F' || c == 'G') { -#ifdef CONFIG_HAVE_LONG_DOUBLE - if (next + sizeof(var->ld) > length) +#ifdef CONFIG_HAVE_DOUBLE +# ifdef CONFIG_HAVE_LONG_DOUBLE + if (*(p - 2) == 'L') { - break; + if (next + sizeof(var->ld) > length) + { + break; + } + + var->ld = va_arg(va, long double); + next += sizeof(var->ld); } + else +# endif + { + if (next + sizeof(var->d) > length) + { + break; + } - var->ld = va_arg(va, long double); - next += sizeof(var->ld); + var->d = va_arg(va, double); + next += sizeof(var->d); + } #endif + + infmt = false; } - else if (*(fmt - 2) == 'l') + else if (c == '*') { -#ifdef CONFIG_HAVE_DOUBLE - if (next + sizeof(var->d) > length) + var->i = va_arg(va, int); + next += sizeof(var->i); + } + else if (c == 's') + { + size_t len; + var->s = va_arg(va, FAR char *); + len = strlen(var->s) + 1; + if (next + len > length) { - break; + len = length - next; } - var->d = va_arg(va, double); - next += sizeof(var->d); -#endif + strlcpy(note->npt_data + next, var->s, len); + next += len; + infmt = false; } - else -#ifdef CONFIG_HAVE_FLOAT + else if (c == 'p') { - if (next + sizeof(var->l) > length) + if (next + sizeof(var->p) > length) { break; } - var->l = va_arg(va, double); - next += sizeof(var->l); -#endif + var->p = va_arg(va, FAR void *); + next += sizeof(var->p); + infmt = false; } - - infmt = false; } } - length = SIZEOF_NOTE_BINARY(next); - note_common(tcb, ¬e->nbi_cmn, length, NOTE_DUMP_BINARY); - note->nbi_ip = ip; + length = SIZEOF_NOTE_PRINTF(next); + note_common(tcb, ¬e->npt_cmn, length, NOTE_DUMP_PRINTF); + note->npt_ip = ip; + note->npt_fmt = fmt; + note->npt_type = type; } /* Add the note to circular buffer */ @@ -1724,23 +1760,15 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip, } } -void sched_note_printf_ip(uint32_t tag, uintptr_t ip, - FAR const char *fmt, ...) +void sched_note_printf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, + uint32_t type, ...) { va_list va; - va_start(va, fmt); - sched_note_vprintf_ip(tag, ip, fmt, va); + va_start(va, type); + sched_note_vprintf_ip(tag, ip, fmt, type, va); va_end(va); } -void sched_note_bprintf_ip(uint32_t tag, uintptr_t ip, - FAR const char *fmt, ...) -{ - va_list va; - va_start(va, fmt); - sched_note_vbprintf_ip(tag, ip, fmt, va); - va_end(va); -} #endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */ #ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER @@ -1967,14 +1995,16 @@ 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"); + sched_note_event_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, + NOTE_DUMP_BEGIN, NULL, 0); } 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"); + sched_note_event_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, + NOTE_DUMP_END, NULL, 0); } #endif @@ -2007,4 +2037,3 @@ int note_driver_register(FAR struct note_driver_s *driver) return -ENOMEM; } - diff --git a/drivers/note/notelog_driver.c b/drivers/note/notelog_driver.c index e311e5ec63026..ccce11aee0d7a 100644 --- a/drivers/note/notelog_driver.c +++ b/drivers/note/notelog_driver.c @@ -149,21 +149,11 @@ static void notelog_start(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb) { #ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Start %s, TCB@%p, state=%d\n", - tcb->cpu, tcb->name, tcb, tcb->task_state); + tcb->cpu, get_task_name(tcb), tcb, tcb->task_state); #else - syslog(LOG_INFO, "CPU%d: Start TCB@%p, state=%d\n" - tcb->cpu, tcb, tcb->task_state); -#endif -#else -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "Start %s, TCB@%p, state=%d\n", - tcb->name, tcb, tcb->task_state); -#else - syslog(LOG_INFO, "Start TCB@%p, state=%d\n", - tcb, tcb->task_state); -#endif + get_task_name(tcb), tcb, tcb->task_state); #endif } @@ -171,21 +161,11 @@ static void notelog_stop(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb) { #ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Stop %s, TCB@%p, state=%d\n", - tcb->cpu, tcb->name, tcb, tcb->task_state); -#else - syslog(LOG_INFO, "CPU%d: Stop TCB@%p, state=%d\n", - tcb->cpu, tcb, tcb->task_state); -#endif + tcb->cpu, get_task_name(tcb), tcb, tcb->task_state); #else -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "Stop %s, TCB@%p, state=%d\n", - tcb->name, tcb, tcb->task_state); -#else - syslog(LOG_INFO, "Stop TCB@%p, state=%d\n", - tcb, tcb->task_state); -#endif + get_task_name(tcb), tcb, tcb->task_state); #endif } @@ -194,21 +174,11 @@ static void notelog_suspend(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb) { #ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Suspend %s, TCB@%p, state=%d\n", - tcb->cpu, tcb->name, tcb, tcb->task_state); -#else - syslog(LOG_INFO, "CPU%d: Suspend TCB@%p, state=%d\n", - tcb->cpu, tcb, tcb->task_state); -#endif + tcb->cpu, get_task_name(tcb), tcb, tcb->task_state); #else -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "Suspend %s, TCB@%p, state=%d\n", - tcb->name, tcb, tcb->task_state); -#else - syslog(LOG_INFO, "Suspend TCB@%p, state=%d\n", - tcb, tcb->task_state); -#endif + get_task_name(tcb), tcb, tcb->task_state); #endif } @@ -216,21 +186,11 @@ static void notelog_resume(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb) { #ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Resume %s, TCB@%p, state=%d\n", - tcb->cpu, tcb->name, tcb, tcb->task_state); + tcb->cpu, get_task_name(tcb), tcb, tcb->task_state); #else - syslog(LOG_INFO, "CPU%d: Resume TCB@%p, state=%d\n", - tcb->cpu, tcb, tcb->task_state); -#endif -#else -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "Resume %s, TCB@%p, state=%d\n", - tcb->name, tcb, tcb->task_state); -#else - syslog(LOG_INFO, "Resume TCB@%p, state=%d\n", - tcb, tcb->task_state); -#endif + get_task_name(tcb), tcb, tcb->task_state); #endif } #endif @@ -239,74 +199,44 @@ static void notelog_resume(FAR struct note_driver_s *drv, static void notelog_cpu_start(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb, int cpu) { -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p CPU%d START\n", - tcb->cpu, tcb->name, tcb, cpu); -#else - syslog(LOG_INFO, "CPU%d: TCB@%p CPU%d START\n", - tcb->cpu, tcb, cpu); -#endif + tcb->cpu, get_task_name(tcb), tcb, cpu); } static void notelog_cpu_started(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb) { -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p CPU%d STARTED\n", - tcb->cpu, tcb->name, tcb, tcb->cpu); -#else - syslog(LOG_INFO, "CPU%d: TCB@%p CPU%d STARTED\n", - tcb->cpu, tcb, tcb->cpu); -#endif + tcb->cpu, get_task_name(tcb), tcb, tcb->cpu); } #ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH static void notelog_cpu_pause(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb, int cpu) { -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p CPU%d PAUSE\n", - tcb->cpu, tcb->name, tcb, cpu); -#else - syslog(LOG_INFO, "CPU%d: TCB@%p CPU%d PAUSE\n", - tcb->cpu, tcb, cpu); -#endif + tcb->cpu, get_task_name(tcb), tcb, cpu); } static void notelog_cpu_paused(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb) { -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p CPU%d PAUSED\n", - tcb->cpu, tcb->name, tcb, tcb->cpu); -#else - syslog(LOG_INFO, "CPU%d: TCB@%p CPU%d PAUSED\n", - tcb->cpu, tcb, tcb->cpu); -#endif + tcb->cpu, get_task_name(tcb), tcb, tcb->cpu); } static void notelog_cpu_resume(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb, int cpu) { -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p CPU%d RESUME\n", - tcb->cpu, tcb->name, tcb, cpu); -#else - syslog(LOG_INFO, "CPU%d: TCB@%p CPU%d RESUME\n", - tcb->cpu, tcb, cpu); -#endif + tcb->cpu, get_task_name(tcb), tcb, cpu); } static void notelog_cpu_resumed(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb) { -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p CPU%d RESUMED\n", - tcb->cpu, tcb->name, tcb, tcb->cpu); -#else - syslog(LOG_INFO, "CPU%d: TCB@%p CPU%d RESUMED\n", - tcb->cpu, tcb, tcb->cpu); -#endif + tcb->cpu, get_task_name(tcb), tcb, tcb->cpu); } #endif #endif @@ -316,21 +246,11 @@ static void notelog_premption(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb, bool locked) { #ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p preemption %s\n", - tcb->cpu, tcb->name, tcb, locked ? "LOCKED" : "UNLOCKED"); -#else - syslog(LOG_INFO, "CPU%d: TCB@%p preemption %s\n", - tcb->cpu, tcb, locked ? "LOCKED" : "UNLOCKED"); -#endif + tcb->cpu, get_task_name(tcb), tcb, locked ? "LOCKED" : "UNLOCKED"); #else -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "Task %s, TCB@%p preemption %s\n", - tcb->name, tcb, locked ? "LOCKED" : "UNLOCKED"); -#else - syslog(LOG_INFO, "TCB@%p preemption %s\n", - tcb, locked ? "LOCKED" : "UNLOCKED"); -#endif + get_task_name(tcb), tcb, locked ? "LOCKED" : "UNLOCKED"); #endif } #endif @@ -340,21 +260,11 @@ static void notelog_csection(FAR struct note_driver_s *drv, FAR struct tcb_s *tcb, bool enter) { #ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p critical section %s\n", - tcb->cpu, tcb->name, tcb, enter ? "ENTER" : "LEAVE"); + tcb->cpu, get_task_name(tcb), tcb, enter ? "ENTER" : "LEAVE"); #else - syslog(LOG_INFO, "CPU%d: TCB@%p critical section %s\n", - tcb->cpu, tcb, enter ? "ENTER" : "LEAVE"); -#endif -#else -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "Task %s, TCB@%p critical section %s\n", - tcb->name, tcb, enter ? "ENTER" : "LEAVE"); -#else - syslog(LOG_INFO, "TCB@%p critical section %s\n", - tcb, enter ? "ENTER" : "LEAVE"); -#endif + get_task_name(tcb), tcb, enter ? "ENTER" : "LEAVE"); #endif } #endif @@ -376,21 +286,11 @@ static void note_spinlock(FAR struct note_driver_s *drv, FAR const char * msg = tmp[type - NOTE_SPINLOCK_LOCK]; #ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "CPU%d: Task %s TCB@%p spinlock@%p %s\n", - tcb->cpu, tcb->name, tcb, spinlock, msg); -#else - syslog(LOG_INFO, "CPU%d: TCB@%p spinlock@%p %s\n", - tcb->cpu, tcb, spinlock, msg); -#endif + tcb->cpu, get_task_name(tcb), tcb, spinlock, msg); #else -#if CONFIG_TASK_NAME_SIZE > 0 syslog(LOG_INFO, "Task %s TCB@%p spinlock@%p %s\n", - tcb->name, tcb, spinlock, msg); -#else - syslog(LOG_INFO, "TCB@%p spinlock@%p %s\n", - tcb, spinlock, msg); -#endif + get_task_name(tcb), tcb, spinlock, msg); #endif } #endif diff --git a/drivers/note/noteram_driver.c b/drivers/note/noteram_driver.c index 22aa6ac6d3709..c29447a28acee 100644 --- a/drivers/note/noteram_driver.c +++ b/drivers/note/noteram_driver.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -295,7 +296,7 @@ static void noteram_remove(FAR struct noteram_driver_s *drv) /* Get the length of the note at the tail index */ - length = drv->ni_buffer[tail]; + length = NOTE_ALIGN(drv->ni_buffer[tail]); DEBUGASSERT(length <= noteram_length(drv)); /* Increment the tail index to remove the entire note from the circular @@ -365,7 +366,7 @@ static ssize_t noteram_get(FAR struct noteram_driver_s *drv, { /* Skip the large note so that we do not get constipated. */ - drv->ni_read = noteram_next(drv, read, notelen); + drv->ni_read = noteram_next(drv, read, NOTE_ALIGN(notelen)); /* and return an error */ @@ -387,7 +388,7 @@ static ssize_t noteram_get(FAR struct noteram_driver_s *drv, remaining--; } - drv->ni_read = read; + drv->ni_read = noteram_next(drv, drv->ni_read, NOTE_ALIGN(notelen)); return notelen; } @@ -419,6 +420,7 @@ static int noteram_open(FAR struct file *filep) int noteram_close(FAR struct file *filep) { FAR struct noteram_dump_context_s *ctx = filep->f_priv; + kmm_free(ctx); return OK; } @@ -567,7 +569,7 @@ static void noteram_add(FAR struct note_driver_s *driver, DEBUGASSERT(note != NULL && notelen < drv->ni_bufsize); remain = drv->ni_bufsize - noteram_length(drv); - if (remain < notelen) + if (remain <= NOTE_ALIGN(notelen)) { if (drv->ni_overwrite == NOTERAM_MODE_OVERWRITE_DISABLE) { @@ -586,7 +588,7 @@ static void noteram_add(FAR struct note_driver_s *driver, noteram_remove(drv); remain = drv->ni_bufsize - noteram_length(drv); } - while (remain < notelen); + while (remain <= NOTE_ALIGN(notelen)); } head = drv->ni_head; @@ -594,7 +596,7 @@ static void noteram_add(FAR struct note_driver_s *driver, space = space < notelen ? space : notelen; memcpy(drv->ni_buffer + head, note, space); memcpy(drv->ni_buffer, buf + space, notelen - space); - drv->ni_head = noteram_next(drv, head, notelen); + drv->ni_head = noteram_next(drv, head, NOTE_ALIGN(notelen)); spin_unlock_irqrestore_wo_note(&drv->lock, flags); } @@ -621,11 +623,12 @@ static void noteram_dump_init_context(FAR struct noteram_dump_context_s *ctx) } /**************************************************************************** - * Name: get_task_name + * Name: get_taskname ****************************************************************************/ -static FAR const char *get_task_name(pid_t pid) +static const char *get_taskname(pid_t pid) { +#if CONFIG_DRIVERS_NOTE_TASKNAME_BUFSIZE > 0 FAR const char *taskname; taskname = note_get_taskname(pid); @@ -633,6 +636,7 @@ static FAR const char *get_task_name(pid_t pid) { return taskname; } +#endif return ""; } @@ -658,7 +662,7 @@ static int noteram_dump_header(FAR struct lib_outstream_s *s, #endif ret = lib_sprintf(s, "%8s-%-3u [%d] %3" PRIu32 ".%09" PRIu32 ": ", - get_task_name(pid), get_pid(pid), cpu, sec, nsec); + get_taskname(pid), get_pid(pid), cpu, sec, nsec); return ret; } @@ -694,9 +698,9 @@ static int noteram_dump_sched_switch(FAR struct lib_outstream_s *s, ret = lib_sprintf(s, "sched_switch: prev_comm=%s prev_pid=%u " "prev_prio=%u prev_state=%c ==> " "next_comm=%s next_pid=%u next_prio=%u\n", - get_task_name(current_pid), get_pid(current_pid), + get_taskname(current_pid), get_pid(current_pid), current_priority, get_task_state(cctx->current_state), - get_task_name(next_pid), get_pid(next_pid), + get_taskname(next_pid), get_pid(next_pid), next_priority); cctx->current_pid = cctx->next_pid; @@ -706,6 +710,204 @@ static int noteram_dump_sched_switch(FAR struct lib_outstream_s *s, } #endif +/**************************************************************************** + * Name: noteram_dump_printf + ****************************************************************************/ + +#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP +static int noteram_dump_printf(FAR struct lib_outstream_s *s, + FAR struct note_printf_s *note) +{ + begin_packed_struct union + { + int i; + long l; +#ifdef CONFIG_HAVE_LONG_LONG + long long ll; +#endif + intmax_t im; + size_t sz; + ptrdiff_t pd; + FAR void *p; + FAR const char *s; +#ifdef CONFIG_HAVE_DOUBLE + double d; +# ifdef CONFIG_HAVE_LONG_DOUBLE + long double ld; +# endif +#endif + } + + end_packed_struct *var; + size_t offset = 0; + size_t ret = 0; + size_t len = 0; + + if (note->npt_type == 0) + { + FAR const char *p = note->npt_fmt; + bool infmt = false; + char fmtstr[64]; + char c; + + while ((c = *p++) != '\0') + { + if (c != '%' && !infmt) + { + lib_stream_putc(s, c); + ret++; + continue; + } + + if (!infmt) + { + len = 0; + infmt = true; + memset(fmtstr, 0, sizeof(fmtstr)); + } + + var = (FAR void *)(note->npt_data + offset); + fmtstr[len++] = c; + + if (c == 'c' || c == 'd' || c == 'i' || c == 'u' || + c == 'o' || c == 'x' || c == 'X') + { + if (*(p - 2) == 'j') + { + offset += sizeof(var->im); + ret += lib_sprintf(s, fmtstr, var->im); + } +#ifdef CONFIG_HAVE_LONG_LONG + else if (*(p - 2) == 'l' && *(p - 3) == 'l') + { + offset += sizeof(var->ll); + ret += lib_sprintf(s, fmtstr, var->ll); + } +#endif + else if (*(p - 2) == 'l') + { + offset += sizeof(var->l); + ret += lib_sprintf(s, fmtstr, var->l); + } + else if (*(p - 2) == 'z') + { + offset += sizeof(var->sz); + ret += lib_sprintf(s, fmtstr, var->sz); + } + else if (*(p - 2) == 't') + { + offset += sizeof(var->pd); + ret += lib_sprintf(s, fmtstr, var->pd); + } + else + { + offset += sizeof(var->i); + ret += lib_sprintf(s, fmtstr, var->i); + } + + infmt = false; + } + else if (c == 'e' || c == 'f' || c == 'g' || c == 'a' || + c == 'A' || c == 'E' || c == 'F' || c == 'G') + { +#ifdef CONFIG_HAVE_DOUBLE +# ifdef CONFIG_HAVE_LONG_DOUBLE + if (*(p - 2) == 'L') + { + offset += sizeof(var->ld); + ret += lib_sprintf(s, fmtstr, var->ld); + } + else +# endif + { + offset += sizeof(var->d); + ret += lib_sprintf(s, fmtstr, var->d); + } + + infmt = false; + } +#endif + else if (c == '*') + { + itoa(var->i, fmtstr + len - 1, 10); + len = strlen(fmtstr); + offset += sizeof(var->i); + } + else if (c == 's') + { + const char *str = note->npt_data + offset; + offset += strlen(str) + 1; + ret += lib_sprintf(s, fmtstr, str); + infmt = false; + } + else if (c == 'p') + { + offset += sizeof(var->p); + ret += lib_sprintf(s, fmtstr, var->p); + infmt = false; + } + } + + if (*(p - 2) != '\n') + { + lib_stream_putc(s, '\n'); + ret++; + } + } + else + { + size_t count = NOTE_PRINTF_GET_COUNT(note->npt_type); + size_t i; + + len = strlen(note->npt_fmt); + if (note->npt_fmt[len - 1] == '\n') + { + len--; + } + + ret += lib_sprintf(s, "%p", note->npt_fmt); + for (i = 0; i < count; i++) + { + int type = NOTE_PRINTF_GET_TYPE(note->npt_type, i); + var = (FAR void *)(note->npt_data + offset); + + switch (type) + { + case NOTE_PRINTF_UINT32: + { + offset += sizeof(var->i); + ret += lib_sprintf(s, " %u", var->i); + } + break; + case NOTE_PRINTF_UINT64: + { + offset += sizeof(var->ll); + ret += lib_sprintf(s, " %llu", var->ll); + } + break; + case NOTE_PRINTF_STRING: + { + const char *str = note->npt_data + offset; + offset += strlen(str) + 1; + ret += lib_sprintf(s, " %s", str); + } + break; + case NOTE_PRINTF_DOUBLE: + { + offset += sizeof(var->d); + ret += lib_sprintf(s, " %f", var->d); + } + } + } + + lib_stream_putc(s, '\n'); + ret++; + } + + return ret; +} +#endif + /**************************************************************************** * Name: noteram_dump_one ****************************************************************************/ @@ -740,7 +942,7 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s, ret += noteram_dump_header(s, note, ctx); ret += lib_sprintf(s, "sched_wakeup_new: comm=%s pid=%d " "target_cpu=%d\n", - get_task_name(pid), get_pid(pid), cpu); + get_taskname(pid), get_pid(pid), cpu); } break; @@ -794,7 +996,7 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s, ret += noteram_dump_header(s, note, ctx); ret += lib_sprintf(s, "sched_waking: comm=%s " "pid=%d target_cpu=%d\n", - get_task_name(cctx->next_pid), + get_taskname(cctx->next_pid), get_pid(cctx->next_pid), cpu); cctx->pendingswitch = true; } @@ -897,6 +1099,27 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s, break; #endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_WDOG + case NOTE_WDOG_START: + case NOTE_WDOG_CANCEL: + case NOTE_WDOG_ENTER: + case NOTE_WDOG_LEAVE: + { + FAR struct note_wdog_s *nw; + FAR const char *name[] = + { + "start", "cancel", "enter", "leave", + }; + + nw = (FAR struct note_wdog_s *)p; + ret += noteram_dump_header(s, note, ctx); + ret += lib_sprintf(s, "tracing_mark_write: I|%d|wdog: %s-%pS %p\n", + pid, name[note->nc_type - NOTE_WDOG_START], + (FAR void *)nw->handler, (FAR void *)nw->arg); + } + break; +#endif + #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION case NOTE_CSECTION_ENTER: case NOTE_CSECTION_LEAVE: @@ -929,42 +1152,30 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s, #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP - case NOTE_DUMP_STRING: + case NOTE_DUMP_PRINTF: { - FAR struct note_string_s *nst; - uintptr_t ip; + FAR struct note_printf_s *npt; - nst = (FAR struct note_string_s *)p; - ret += noteram_dump_header(s, note, ctx); - ip = nst->nst_ip; - - if (nst->nst_data[1] == '\0' && - (nst->nst_data[0] == 'B' || nst->nst_data[0] == 'E')) - { - ret += lib_sprintf(s, "tracing_mark_write: %c|%d|%pS\n", - nst->nst_data[0], pid, (FAR void *)ip); - } - else - { - ret += lib_sprintf(s, "tracing_mark_write: %s\n", - nst->nst_data); - } + npt = (FAR struct note_printf_s *)p; + ret += noteram_dump_header(s, &npt->npt_cmn, ctx); + ret += lib_sprintf(s, "tracing_mark_write: "); + ret += noteram_dump_printf(s, npt); } break; case NOTE_DUMP_BEGIN: case NOTE_DUMP_END: { - FAR struct note_binary_s *nbi = (FAR struct note_binary_s *)p; + FAR struct note_event_s *nbi = (FAR struct note_event_s *)p; char c = note->nc_type == NOTE_DUMP_BEGIN ? 'B' : 'E'; int len = note->nc_length - SIZEOF_NOTE_EVENT(0); uintptr_t ip; - ip = nbi->nbi_ip; - ret += noteram_dump_header(s, &nbi->nbi_cmn, ctx); + ip = nbi->nev_ip; + ret += noteram_dump_header(s, &nbi->nev_cmn, ctx); if (len > 0) { ret += lib_sprintf(s, "tracing_mark_write: %c|%d|%.*s\n", - c, pid, len, (FAR const char *)nbi->nbi_data); + c, pid, len, (FAR const char *)nbi->nev_data); } else { @@ -975,47 +1186,45 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s, break; case NOTE_DUMP_MARK: { - int len = note->nc_length - sizeof(struct note_binary_s); - FAR struct note_binary_s *nbi = (FAR struct note_binary_s *)p; - ret += noteram_dump_header(s, &nbi->nbi_cmn, ctx); + int len = note->nc_length - sizeof(struct note_event_s); + FAR struct note_event_s *nbi = (FAR struct note_event_s *)p; + ret += noteram_dump_header(s, &nbi->nev_cmn, ctx); ret += lib_sprintf(s, "tracing_mark_write: I|%d|%.*s\n", - pid, len, (FAR const char *)nbi->nbi_data); + pid, len, (FAR const char *)nbi->nev_data); } break; case NOTE_DUMP_COUNTER: { - FAR struct note_binary_s *nbi = (FAR struct note_binary_s *)p; + FAR struct note_event_s *nbi = (FAR struct note_event_s *)p; FAR struct note_counter_s *counter; - counter = (FAR struct note_counter_s *)nbi->nbi_data; - ret += noteram_dump_header(s, &nbi->nbi_cmn, ctx); + counter = (FAR struct note_counter_s *)nbi->nev_data; + ret += noteram_dump_header(s, &nbi->nev_cmn, ctx); ret += lib_sprintf(s, "tracing_mark_write: C|%d|%s|%ld\n", pid, counter->name, counter->value); } break; - case NOTE_DUMP_BINARY: +#endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP + case NOTE_HEAP_ADD: + case NOTE_HEAP_REMOVE: + case NOTE_HEAP_ALLOC: + case NOTE_HEAP_FREE: { - FAR struct note_binary_s *nbi; - uint8_t count; - uintptr_t ip; - int i; - - nbi = (FAR struct note_binary_s *)p; - ret += noteram_dump_header(s, note, ctx); - count = note->nc_length - sizeof(struct note_binary_s) + 1; - ip = nbi->nbi_ip; - - ret += lib_sprintf(s, "tracing_mark_write: %pS: count=%u", - (FAR void *)ip, count); - for (i = 0; i < count; i++) + FAR struct note_heap_s *nmm = (FAR struct note_heap_s *)p; + FAR const char *name[] = { - ret += lib_sprintf(s, " 0x%x", nbi->nbi_data[i]); - } - - ret += lib_sprintf(s, "\n"); + "add", "remove", "malloc", "free" + }; + + ret += noteram_dump_header(s, &nmm->nhp_cmn, ctx); + ret += lib_sprintf(s, "tracing_mark_write: C|%d|Heap Usage|%d|%s" + ": heap: %p size:%" PRIiPTR ", address: %p\n", + pid, nmm->used, + name[note->nc_type - NOTE_HEAP_ADD], + nmm->heap, nmm->size, nmm->mem); } break; #endif - default: break; } diff --git a/drivers/segger/Make.defs b/drivers/segger/Make.defs index 424c0f7206676..162cd4e3958b6 100644 --- a/drivers/segger/Make.defs +++ b/drivers/segger/Make.defs @@ -69,7 +69,7 @@ endif ifneq ($(CONFIG_SEGGER_RTT)$(CONFIG_SEGGER_SYSVIEW),) CFLAGS += ${INCDIR_PREFIX}segger$(DELIM)SystemView$(DELIM)SEGGER - SYSVIEW_VERSION ?= 354 + SYSVIEW_VERSION ?= 356 SYSVIEW_ZIP = SystemView_Src_V$(SYSVIEW_VERSION).zip # Download and unpack tarball if no git repo found diff --git a/drivers/segger/note_sysview.c b/drivers/segger/note_sysview.c index 24fe2f4c7450c..a783925fdedbf 100644 --- a/drivers/segger/note_sysview.c +++ b/drivers/segger/note_sysview.c @@ -23,6 +23,7 @@ ****************************************************************************/ #include +#include #include #include @@ -73,6 +74,15 @@ static void note_sysview_syscall_enter(FAR struct note_driver_s *drv, static void note_sysview_syscall_leave(FAR struct note_driver_s *drv, int nr, uintptr_t result); #endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP +static void note_sysview_heap(FAR struct note_driver_s *drv, + uint8_t event, FAR void *heap, FAR void *mem, + size_t size, size_t curused); +#endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_WDOG +static void note_sysview_wdog(FAR struct note_driver_s *drv, uint8_t event, + FAR void *handler, FAR const void *arg); +#endif /**************************************************************************** * Private Data @@ -113,6 +123,12 @@ static const struct note_driver_ops_s g_note_sysview_ops = #ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER note_sysview_irqhandler, /* irqhandler */ #endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_WDOG + note_sysview_wdog, /* wdog */ +#endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP + note_sysview_heap, /* heap */ +#endif }; static struct note_sysview_driver_s g_note_sysview_driver = @@ -135,11 +151,7 @@ static void note_sysview_send_taskinfo(FAR struct tcb_s *tcb) SEGGER_SYSVIEW_TASKINFO info; info.TaskID = tcb->pid; -#if CONFIG_TASK_NAME_SIZE > 0 - info.sName = tcb->name; -#else - info.sName = ""; -#endif + info.sName = get_task_name(tcb); info.Prio = tcb->sched_priority; info.StackBase = (uintptr_t)tcb->stack_base_ptr; info.StackSize = tcb->adj_stack_size; @@ -323,6 +335,79 @@ static void note_sysview_syscall_leave(FAR struct note_driver_s *drv, } #endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP +static void note_sysview_heap(FAR struct note_driver_s *drv, + uint8_t event, FAR void *heap, FAR void *mem, + size_t size, size_t curused) +{ + switch (event) + { + case NOTE_HEAP_ALLOC: + case NOTE_HEAP_FREE: + { + U32 value = (U32)curused; + const SEGGER_SYSVIEW_DATA_SAMPLE data = + { + .ID = (U32)(uintptr_t)heap, + .pU32_Value = &value, + }; + + SEGGER_SYSVIEW_SampleData(&data); + if (event == NOTE_HEAP_ALLOC) + { + SEGGER_SYSVIEW_HeapAlloc(heap, mem, size); + } + else + { + SEGGER_SYSVIEW_HeapFree(heap, mem); + } + + break; + } + + case NOTE_HEAP_ADD: + { + char name[32]; + SEGGER_SYSVIEW_DATA_REGISTER data = + { + .ID = (U32)(uintptr_t)heap, + .DataType = SEGGER_SYSVIEW_TYPE_U32, + .Offset = 0, + .RangeMin = 0, + .RangeMax = 0, + .ScalingFactor = 1.f, + .sUnit = "B", + .sName = name, + }; + + snprintf(name, sizeof(name), "Heap%p", heap); + + SEGGER_SYSVIEW_RegisterData(&data); + SEGGER_SYSVIEW_HeapDefine(heap, mem, size, 0); + break; + } + + default: + break; + } +} +#endif + +#ifdef CONFIG_SCHED_INSTRUMENTATION_WDOG +static void note_sysview_wdog(FAR struct note_driver_s *drv, uint8_t event, + FAR void *handler, FAR const void *arg) +{ + if (event == NOTE_WDOG_ENTER) + { + SEGGER_SYSVIEW_RecordEnterTimer((uintptr_t)handler); + } + else if (event == NOTE_WDOG_LEAVE) + { + SEGGER_SYSVIEW_RecordExitTimer(); + } +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index ef00bfa1df327..fc6ff09b89d63 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -1783,9 +1783,9 @@ static int uart_unlink(FAR struct inode *inode) static void uart_launch_foreach(FAR struct tcb_s *tcb, FAR void *arg) { #ifdef CONFIG_TTY_LAUNCH_ENTRY - if (!strcmp(tcb->name, CONFIG_TTY_LAUNCH_ENTRYNAME)) + if (!strcmp(get_task_name(tcb), CONFIG_TTY_LAUNCH_ENTRYNAME)) #else - if (!strcmp(tcb->name, CONFIG_TTY_LAUNCH_FILEPATH)) + if (!strcmp(get_task_name(tcb), CONFIG_TTY_LAUNCH_FILEPATH)) #endif { *(FAR int *)arg = 1; diff --git a/drivers/syslog/Kconfig b/drivers/syslog/Kconfig index e0c9948750982..b46f107958dc0 100644 --- a/drivers/syslog/Kconfig +++ b/drivers/syslog/Kconfig @@ -153,6 +153,7 @@ config SYSLOG_PRIORITY config SYSLOG_PROCESS_NAME bool "Prepend process name to syslog message" default n + depends on TASK_NAME_SIZE > 0 ---help--- Prepend Process name to syslog message. diff --git a/drivers/syslog/ramlog.c b/drivers/syslog/ramlog.c index ba9b3ff849983..dfb0b7c1d53f8 100644 --- a/drivers/syslog/ramlog.c +++ b/drivers/syslog/ramlog.c @@ -234,6 +234,21 @@ static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv) } } +/**************************************************************************** + * Name: ramlog_flush + ****************************************************************************/ + +static void ramlog_bufferflush(FAR struct ramlog_dev_s *priv) +{ + FAR struct ramlog_user_s *upriv; + + priv->rl_header->rl_head = 0; + list_for_every_entry(&priv->rl_list, upriv, struct ramlog_user_s, rl_node) + { + upriv->rl_tail = 0; + } +} + /**************************************************************************** * Name: ramlog_copybuf ****************************************************************************/ @@ -535,7 +550,7 @@ static int ramlog_file_ioctl(FAR struct file *filep, int cmd, upriv->rl_threashold = (uint32_t)arg; break; case BIOC_FLUSH: - priv->rl_header->rl_head = 0; + ramlog_bufferflush(priv); break; default: ret = -ENOTTY; diff --git a/drivers/syslog/vsyslog.c b/drivers/syslog/vsyslog.c index a51c31e2a3625..9ce1ab2fc480b 100644 --- a/drivers/syslog/vsyslog.c +++ b/drivers/syslog/vsyslog.c @@ -83,7 +83,7 @@ int nx_vsyslog(int priority, FAR const IPTR char *fmt, FAR va_list *ap) { struct lib_syslograwstream_s stream; int ret = 0; -#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_SYSLOG_PROCESS_NAME) +#ifdef CONFIG_SYSLOG_PROCESS_NAME FAR struct tcb_s *tcb = nxsched_get_tcb(nxsched_gettid()); #endif #ifdef CONFIG_SYSLOG_TIMESTAMP @@ -196,7 +196,7 @@ int nx_vsyslog(int priority, FAR const IPTR char *fmt, FAR va_list *ap) "[%s] " #endif -#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_SYSLOG_PROCESS_NAME) +#ifdef CONFIG_SYSLOG_PROCESS_NAME /* Prepend the thread name */ "%s: " @@ -242,10 +242,10 @@ int nx_vsyslog(int priority, FAR const IPTR char *fmt, FAR va_list *ap) , CONFIG_SYSLOG_PREFIX_STRING #endif -#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_SYSLOG_PROCESS_NAME) +#ifdef CONFIG_SYSLOG_PROCESS_NAME /* Prepend the thread name */ - , tcb != NULL ? tcb->name : "(null)" + , get_task_name(tcb) #endif ); diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 695f60c2808c1..e84f7311165dd 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -486,11 +486,7 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile, /* Show the task name */ -#if CONFIG_TASK_NAME_SIZE > 0 - name = tcb->name; -#else - name = ""; -#endif + name = get_task_name(tcb); linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%.18s\n", "Name:", name); copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, @@ -670,11 +666,7 @@ static ssize_t proc_cmdline(FAR struct proc_file_s *procfile, /* Show the task name */ -#if CONFIG_TASK_NAME_SIZE > 0 - name = tcb->name; -#else - name = ""; -#endif + name = get_task_name(tcb); linesize = strlen(name); memcpy(procfile->line, name, linesize); copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h index dc994002e41f0..4658e26aff471 100644 --- a/include/nuttx/compiler.h +++ b/include/nuttx/compiler.h @@ -172,7 +172,7 @@ * unnecessary "weak" functions can be excluded from the link. */ -#undef CONFIG_HAVE_WEAKFUNCTIONS +# undef CONFIG_HAVE_WEAKFUNCTIONS # if !defined(__CYGWIN__) && !defined(CONFIG_ARCH_GNU_NO_WEAKFUNCTIONS) # define CONFIG_HAVE_WEAKFUNCTIONS 1 @@ -344,6 +344,7 @@ # define syslog_like(a, b) __attribute__((__format__(__syslog__, a, b))) # define scanf_like(a, b) __attribute__((__format__(__scanf__, a, b))) # define strftime_like(a) __attribute__((__format__(__strftime__, a, 0))) +# define object_size(o, t) __builtin_object_size(o, t) /* GCC does not use storage classes to qualify addressing */ @@ -612,6 +613,7 @@ # define syslog_like(a, b) # define scanf_like(a, b) # define strftime_like(a) +# define object_size(o, t) ((size_t)-1) /* The reentrant attribute informs SDCC that the function * must be reentrant. In this case, SDCC will store input @@ -756,6 +758,7 @@ # define syslog_like(a, b) # define scanf_like(a, b) # define strftime_like(a) +# define object_size(o, t) ((size_t)-1) /* REVISIT: */ @@ -871,6 +874,7 @@ # define syslog_like(a, b) # define scanf_like(a, b) # define strftime_like(a) +# define object_size(o, t) ((size_t)-1) # define FAR # define NEAR @@ -1049,6 +1053,7 @@ # define syslog_like(a, b) # define scanf_like(a, b) # define strftime_like(a) +# define object_size(o, t) ((size_t)-1) # define FAR # define NEAR @@ -1118,6 +1123,7 @@ # define syslog_like(a, b) # define scanf_like(a, b) # define strftime_like(a) +# define object_size(o, t) ((size_t)-1) # define FAR # define NEAR diff --git a/include/nuttx/macro.h b/include/nuttx/macro.h new file mode 100644 index 0000000000000..c9c2481430705 --- /dev/null +++ b/include/nuttx/macro.h @@ -0,0 +1,140 @@ +/**************************************************************************** + * include/nuttx/macro.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_MACRO_H +#define __INCLUDE_NUTTX_MACRO_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define GET_ARG_VALUE(_00, _01, _02, _03, _04, _05, _06, _07, \ + _08, _09, _10, _11, _12, _13, _14, _15, \ + _16, _17, _18, _19, _20, _21, _22, _23, \ + _24, _25, _26, _27, _28, _29, _30, _31, \ + _32, name, ...) name + +/* Get the number of arguments (up to 32) */ + +#define GET_ARG_COUNT(...) \ + GET_ARG_VALUE(_0, ##__VA_ARGS__, 32, 31, 30, \ + 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \ + 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +/* Reverse the arguments */ + +#define EXPAND(x) x + +#define REVERSE_00() +#define REVERSE_01(a) a +#define REVERSE_02(a,b) b,a +#define REVERSE_03(a,...) EXPAND(REVERSE_02(__VA_ARGS__)),a +#define REVERSE_04(a,...) EXPAND(REVERSE_03(__VA_ARGS__)),a +#define REVERSE_05(a,...) EXPAND(REVERSE_04(__VA_ARGS__)),a +#define REVERSE_06(a,...) EXPAND(REVERSE_05(__VA_ARGS__)),a +#define REVERSE_07(a,...) EXPAND(REVERSE_06(__VA_ARGS__)),a +#define REVERSE_08(a,...) EXPAND(REVERSE_07(__VA_ARGS__)),a +#define REVERSE_09(a,...) EXPAND(REVERSE_08(__VA_ARGS__)),a +#define REVERSE_10(a,...) EXPAND(REVERSE_09(__VA_ARGS__)),a +#define REVERSE_11(a,...) EXPAND(REVERSE_10(__VA_ARGS__)),a +#define REVERSE_12(a,...) EXPAND(REVERSE_11(__VA_ARGS__)),a +#define REVERSE_13(a,...) EXPAND(REVERSE_12(__VA_ARGS__)),a +#define REVERSE_14(a,...) EXPAND(REVERSE_13(__VA_ARGS__)),a +#define REVERSE_15(a,...) EXPAND(REVERSE_14(__VA_ARGS__)),a +#define REVERSE_16(a,...) EXPAND(REVERSE_15(__VA_ARGS__)),a +#define REVERSE_17(a,...) EXPAND(REVERSE_16(__VA_ARGS__)),a +#define REVERSE_18(a,...) EXPAND(REVERSE_17(__VA_ARGS__)),a +#define REVERSE_19(a,...) EXPAND(REVERSE_18(__VA_ARGS__)),a +#define REVERSE_20(a,...) EXPAND(REVERSE_19(__VA_ARGS__)),a +#define REVERSE_21(a,...) EXPAND(REVERSE_20(__VA_ARGS__)),a +#define REVERSE_22(a,...) EXPAND(REVERSE_21(__VA_ARGS__)),a +#define REVERSE_23(a,...) EXPAND(REVERSE_22(__VA_ARGS__)),a +#define REVERSE_24(a,...) EXPAND(REVERSE_23(__VA_ARGS__)),a +#define REVERSE_25(a,...) EXPAND(REVERSE_24(__VA_ARGS__)),a +#define REVERSE_26(a,...) EXPAND(REVERSE_25(__VA_ARGS__)),a +#define REVERSE_27(a,...) EXPAND(REVERSE_26(__VA_ARGS__)),a +#define REVERSE_28(a,...) EXPAND(REVERSE_27(__VA_ARGS__)),a +#define REVERSE_29(a,...) EXPAND(REVERSE_28(__VA_ARGS__)),a +#define REVERSE_30(a,...) EXPAND(REVERSE_29(__VA_ARGS__)),a +#define REVERSE_31(a,...) EXPAND(REVERSE_30(__VA_ARGS__)),a +#define REVERSE_32(a,...) EXPAND(REVERSE_31(__VA_ARGS__)),a + +#define REVERSE_ARG_(...) \ + GET_ARG_VALUE(0, ##__VA_ARGS__, \ + REVERSE_32, REVERSE_31, REVERSE_30, REVERSE_29, REVERSE_28, REVERSE_27, \ + REVERSE_26, REVERSE_25, REVERSE_24, REVERSE_23, REVERSE_22, REVERSE_21, \ + REVERSE_20, REVERSE_19, REVERSE_18, REVERSE_17, REVERSE_16, REVERSE_15, \ + REVERSE_14, REVERSE_13, REVERSE_12, REVERSE_11, REVERSE_10, REVERSE_09, \ + REVERSE_08, REVERSE_07, REVERSE_06, REVERSE_05, REVERSE_04, REVERSE_03, \ + REVERSE_02, REVERSE_01, REVERSE_00)(__VA_ARGS__) + +#define REVERSE_ARG(...) REVERSE_ARG_(##__VA_ARGS__) + +/* Apply the macro to each argument */ + +#define FOREACH_00(action, count, ...) 0 +#define FOREACH_01(action, count, arg, ...) action(arg, count - 1 ) +#define FOREACH_02(action, count, arg, ...) action(arg, count - 2 ) FOREACH_01(action, count, __VA_ARGS__) +#define FOREACH_03(action, count, arg, ...) action(arg, count - 3 ) FOREACH_02(action, count, __VA_ARGS__) +#define FOREACH_04(action, count, arg, ...) action(arg, count - 4 ) FOREACH_03(action, count, __VA_ARGS__) +#define FOREACH_05(action, count, arg, ...) action(arg, count - 5 ) FOREACH_04(action, count, __VA_ARGS__) +#define FOREACH_06(action, count, arg, ...) action(arg, count - 6 ) FOREACH_05(action, count, __VA_ARGS__) +#define FOREACH_07(action, count, arg, ...) action(arg, count - 7 ) FOREACH_06(action, count, __VA_ARGS__) +#define FOREACH_08(action, count, arg, ...) action(arg, count - 8 ) FOREACH_07(action, count, __VA_ARGS__) +#define FOREACH_09(action, count, arg, ...) action(arg, count - 9 ) FOREACH_08(action, count, __VA_ARGS__) +#define FOREACH_10(action, count, arg, ...) action(arg, count - 10) FOREACH_09(action, count, __VA_ARGS__) +#define FOREACH_11(action, count, arg, ...) action(arg, count - 11) FOREACH_10(action, count, __VA_ARGS__) +#define FOREACH_12(action, count, arg, ...) action(arg, count - 12) FOREACH_11(action, count, __VA_ARGS__) +#define FOREACH_13(action, count, arg, ...) action(arg, count - 13) FOREACH_12(action, count, __VA_ARGS__) +#define FOREACH_14(action, count, arg, ...) action(arg, count - 14) FOREACH_13(action, count, __VA_ARGS__) +#define FOREACH_15(action, count, arg, ...) action(arg, count - 15) FOREACH_14(action, count, __VA_ARGS__) +#define FOREACH_16(action, count, arg, ...) action(arg, count - 16) FOREACH_15(action, count, __VA_ARGS__) +#define FOREACH_17(action, count, arg, ...) action(arg, count - 17) FOREACH_16(action, count, __VA_ARGS__) +#define FOREACH_18(action, count, arg, ...) action(arg, count - 18) FOREACH_17(action, count, __VA_ARGS__) +#define FOREACH_19(action, count, arg, ...) action(arg, count - 19) FOREACH_18(action, count, __VA_ARGS__) +#define FOREACH_20(action, count, arg, ...) action(arg, count - 20) FOREACH_19(action, count, __VA_ARGS__) +#define FOREACH_21(action, count, arg, ...) action(arg, count - 21) FOREACH_20(action, count, __VA_ARGS__) +#define FOREACH_22(action, count, arg, ...) action(arg, count - 22) FOREACH_21(action, count, __VA_ARGS__) +#define FOREACH_23(action, count, arg, ...) action(arg, count - 23) FOREACH_22(action, count, __VA_ARGS__) +#define FOREACH_24(action, count, arg, ...) action(arg, count - 24) FOREACH_23(action, count, __VA_ARGS__) +#define FOREACH_25(action, count, arg, ...) action(arg, count - 25) FOREACH_24(action, count, __VA_ARGS__) +#define FOREACH_26(action, count, arg, ...) action(arg, count - 26) FOREACH_25(action, count, __VA_ARGS__) +#define FOREACH_27(action, count, arg, ...) action(arg, count - 27) FOREACH_26(action, count, __VA_ARGS__) +#define FOREACH_28(action, count, arg, ...) action(arg, count - 28) FOREACH_27(action, count, __VA_ARGS__) +#define FOREACH_29(action, count, arg, ...) action(arg, count - 29) FOREACH_28(action, count, __VA_ARGS__) +#define FOREACH_30(action, count, arg, ...) action(arg, count - 30) FOREACH_29(action, count, __VA_ARGS__) +#define FOREACH_31(action, count, arg, ...) action(arg, count - 31) FOREACH_30(action, count, __VA_ARGS__) +#define FOREACH_32(action, count, arg, ...) action(arg, count - 32) FOREACH_31(action, count, __VA_ARGS__) + +#define FOREACH_ARG_(action, count, ...) \ + GET_ARG_VALUE(0, ##__VA_ARGS__, \ + FOREACH_32, FOREACH_31, FOREACH_30, FOREACH_29, FOREACH_28, FOREACH_27, \ + FOREACH_26, FOREACH_25, FOREACH_24, FOREACH_23, FOREACH_22, FOREACH_21, \ + FOREACH_20, FOREACH_19, FOREACH_18, FOREACH_17, FOREACH_16, FOREACH_15, \ + FOREACH_14, FOREACH_13, FOREACH_12, FOREACH_11, FOREACH_10, FOREACH_09, \ + FOREACH_08, FOREACH_07, FOREACH_06, FOREACH_05, FOREACH_04, FOREACH_03, \ + FOREACH_02, FOREACH_01, FOREACH_00)(action, count, ##__VA_ARGS__) + +#define FOREACH_ARG(action, ...) \ + FOREACH_ARG_(action, GET_ARG_COUNT(__VA_ARGS__), ##__VA_ARGS__) + +#endif /* __INCLUDE_NUTTX_MACRO_H */ + diff --git a/include/nuttx/note/note_driver.h b/include/nuttx/note/note_driver.h index ddea03374323d..fa6b7fe36ca45 100644 --- a/include/nuttx/note/note_driver.h +++ b/include/nuttx/note/note_driver.h @@ -89,15 +89,20 @@ struct note_driver_ops_s CODE void (*irqhandler)(FAR struct note_driver_s *drv, int irq, FAR void *handler, bool enter); #endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_WDOG + CODE void (*wdog)(FAR struct note_driver_s *drv, uint8_t event, + FAR void *handler, FAR const void *arg); +#endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP + CODE void (*heap)(FAR struct note_driver_s *drv, uint8_t event, + FAR void *heap, FAR void *mem, size_t size, + size_t curused); +#endif #ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP - CODE void (*string)(FAR struct note_driver_s *drv, uintptr_t ip, - FAR const char *buf); CODE void (*event)(FAR struct note_driver_s *drv, uintptr_t ip, uint8_t event, FAR const void *buf, size_t len); CODE void (*vprintf)(FAR struct note_driver_s *drv, uintptr_t ip, FAR const char *fmt, va_list va) printf_like(3, 0); - CODE void (*vbprintf)(FAR struct note_driver_s *drv, uintptr_t ip, - FAR const char *fmt, va_list va) printf_like(3, 0); #endif }; diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 37b06cb6e4723..62cc4e6390fb8 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -222,6 +222,14 @@ #define get_current_mm() (get_group_mm(nxsched_self()->group)) +/* Get task name from tcb */ + +#if CONFIG_TASK_NAME_SIZE > 0 +# define get_task_name(tcb) ((tcb)->name) +#else +# define get_task_name(tcb) "" +#endif + /* These are macros to access the current CPU and the current task on a CPU. * These macros are intended to support a future SMP implementation. */ diff --git a/include/nuttx/sched_note.h b/include/nuttx/sched_note.h index eb0ce3d8040b4..305bad308eb6b 100644 --- a/include/nuttx/sched_note.h +++ b/include/nuttx/sched_note.h @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -51,6 +52,9 @@ * Pre-processor Definitions ****************************************************************************/ +#define NOTE_ALIGN(a) (((a) + sizeof(uintptr_t) - 1) & \ + ~(sizeof(uintptr_t) - 1)) + /* Provide defaults for some configuration settings (could be undefined with * old configuration files) */ @@ -122,25 +126,83 @@ # define NOTE_FILTER_TAGMASK_ZERO(s) #endif +/* Printf argument type */ + +#define NOTE_PRINTF_UINT32 0 +#define NOTE_PRINTF_UINT64 1 +#define NOTE_PRINTF_DOUBLE 2 +#define NOTE_PRINTF_STRING 3 + +/* Get/set printf tag. each parameter occupies 2 bits. The highest + * four bits are used to represent the number of parameters, So up to + * 14 variable arguments can be passed. + */ + +#define NOTE_PRINTF_GET_TYPE(tag, index) (((tag) >> (index) * 2) & 0x03) +#define NOTE_PRINTF_GET_COUNT(tag) (((tag) >> 28) & 0x0f) + +/* Check if a variable is 32-bit or 64-bit */ + +#define NOTE_PRINTF_INT_TYPE(arg) (sizeof((arg) + 0) <= sizeof(uint32_t) ? \ + NOTE_PRINTF_UINT32 : NOTE_PRINTF_UINT64) + +/* Use object_size to mark strings of known size */ + +#define NOTE_PRINTF_OBJECT_SIZE(arg) object_size((FAR void *)(uintptr_t)(arg), 2) + +/* Use _Generic to determine the type of the parameter */ + +#define NOTE_PRINTF_ARG_TYPE(__arg__) \ + _Generic((__arg__) + 0, \ + float : NOTE_PRINTF_DOUBLE, \ + double: NOTE_PRINTF_DOUBLE, \ + char *: ({NOTE_PRINTF_OBJECT_SIZE(__arg__) > 0 ? \ + NOTE_PRINTF_STRING : \ + NOTE_PRINTF_INT_TYPE(__arg__);}), \ + const char *: ({NOTE_PRINTF_OBJECT_SIZE(__arg__) > 0 ? \ + NOTE_PRINTF_STRING : \ + NOTE_PRINTF_INT_TYPE(__arg__);}), \ + default: NOTE_PRINTF_INT_TYPE(__arg__)) + +/* Set the type of each parameter */ + +#define NOTE_PRINTF_TYPE(arg, index) + ((NOTE_PRINTF_ARG_TYPE(arg) << (index) * 2)) +#define NOTE_PRINTF_TYPES(...) FOREACH_ARG(NOTE_PRINTF_TYPE, ##__VA_ARGS__) + +/* Using macro expansion to calculate the expression of tag, tag will + * be a constant at compile time, which will reduce the number of + * size in the code. + */ + +#define NOTE_PRINTF_TAG(...) \ + ((GET_ARG_COUNT(__VA_ARGS__) << 28) + NOTE_PRINTF_TYPES(__VA_ARGS__)) + #define SCHED_NOTE_IP \ ({ __label__ __here; __here: (unsigned long)&&__here; }) -#define sched_note_string(tag, buf) \ - sched_note_string_ip(tag, SCHED_NOTE_IP, buf) #define sched_note_event(tag, event, buf, len) \ sched_note_event_ip(tag, SCHED_NOTE_IP, event, buf, len) -#define sched_note_dump(tag, buf, len) \ - sched_note_event_ip(tag, SCHED_NOTE_IP, NOTE_DUMP_BINARY, buf, len) #define sched_note_vprintf(tag, fmt, va) \ - sched_note_vprintf_ip(tag, SCHED_NOTE_IP, fmt, va) -#define sched_note_vbprintf(tag, fmt, va) \ - sched_note_vbprintf_ip(tag, SCHED_NOTE_IP, fmt, va) -#define sched_note_printf(tag, fmt, ...) \ - sched_note_printf_ip(tag, SCHED_NOTE_IP, fmt, ##__VA_ARGS__) -#define sched_note_bprintf(tag, fmt, ...) \ - sched_note_bprintf_ip(tag, SCHED_NOTE_IP, fmt, ##__VA_ARGS__) -#define sched_note_counter(tag, name, value) \ - sched_note_counter_ip(tag, SCHED_NOTE_IP, name, value) + sched_note_vprintf_ip(tag, SCHED_NOTE_IP, fmt, 0, va) + +#ifdef CONFIG_DRIVERS_NOTE_STRIP_FORMAT +# define sched_note_printf(tag, fmt, ...) \ + do \ + { \ + static const locate_data(".printf_format") \ + char __fmt__[] = fmt; \ + uint32_t __type__ = NOTE_PRINTF_TAG(__VA_ARGS__); \ + static_assert(GET_ARG_COUNT(__VA_ARGS__) <= 14, \ + "The number of sched_note_nprintf " \ + "parameters needs to be less than 14"); \ + sched_note_printf_ip(tag, SCHED_NOTE_IP, __fmt__, \ + __type__, ##__VA_ARGS__); \ + } \ + while (0) +#else +# define sched_note_printf(tag, fmt, ...) \ + sched_note_printf_ip(tag, SCHED_NOTE_IP, fmt, 0, ##__VA_ARGS__) +#endif #define sched_note_begin(tag) \ sched_note_event(tag, NOTE_DUMP_BEGIN, NULL, 0) @@ -153,6 +215,17 @@ #define sched_note_mark(tag, str) \ sched_note_event(tag, NOTE_DUMP_MARK, str, strlen(str)) +#define sched_note_counter(tag, name_, value_) \ + do \ + { \ + struct note_counter_s counter; \ + counter.value = value_; \ + strlcpy(counter.name, name_, NAME_MAX); \ + sched_note_event(tag, NOTE_DUMP_COUNTER, \ + &counter, sizeof(counter)); \ + } \ + while (0) + /**************************************************************************** * Public Types ****************************************************************************/ @@ -161,34 +234,45 @@ enum note_type_e { - NOTE_START = 0, - NOTE_STOP = 1, - NOTE_SUSPEND = 2, - NOTE_RESUME = 3, - NOTE_CPU_START = 4, - NOTE_CPU_STARTED = 5, - NOTE_CPU_PAUSE = 6, - NOTE_CPU_PAUSED = 7, - NOTE_CPU_RESUME = 8, - NOTE_CPU_RESUMED = 9, - NOTE_PREEMPT_LOCK = 10, - NOTE_PREEMPT_UNLOCK = 11, - NOTE_CSECTION_ENTER = 12, - NOTE_CSECTION_LEAVE = 13, - NOTE_SPINLOCK_LOCK = 14, - NOTE_SPINLOCK_LOCKED = 15, - NOTE_SPINLOCK_UNLOCK = 16, - NOTE_SPINLOCK_ABORT = 17, - NOTE_SYSCALL_ENTER = 18, - NOTE_SYSCALL_LEAVE = 19, - NOTE_IRQ_ENTER = 20, - NOTE_IRQ_LEAVE = 21, - NOTE_DUMP_STRING = 22, - NOTE_DUMP_BINARY = 23, - NOTE_DUMP_BEGIN = 24, - NOTE_DUMP_END = 25, - NOTE_DUMP_MARK = 28, - NOTE_DUMP_COUNTER = 29, + NOTE_START, + NOTE_STOP, + NOTE_SUSPEND, + NOTE_RESUME, + NOTE_CPU_START, + NOTE_CPU_STARTED, + NOTE_CPU_PAUSE, + NOTE_CPU_PAUSED, + NOTE_CPU_RESUME, + NOTE_CPU_RESUMED, + NOTE_PREEMPT_LOCK, + NOTE_PREEMPT_UNLOCK, + NOTE_CSECTION_ENTER, + NOTE_CSECTION_LEAVE, + NOTE_SPINLOCK_LOCK, + NOTE_SPINLOCK_LOCKED, + NOTE_SPINLOCK_UNLOCK, + NOTE_SPINLOCK_ABORT, + NOTE_SYSCALL_ENTER, + NOTE_SYSCALL_LEAVE, + NOTE_IRQ_ENTER, + NOTE_IRQ_LEAVE, + NOTE_WDOG_START, + NOTE_WDOG_CANCEL, + NOTE_WDOG_ENTER, + NOTE_WDOG_LEAVE, + NOTE_HEAP_ADD, + NOTE_HEAP_REMOVE, + NOTE_HEAP_ALLOC, + NOTE_HEAP_FREE, + NOTE_DUMP_PRINTF, + + NOTE_DUMP_BEGIN, + NOTE_DUMP_END, + NOTE_DUMP_MARK, + NOTE_DUMP_COUNTER, + + /* Always last */ + NOTE_TYPE_LAST }; @@ -374,25 +458,43 @@ struct note_irqhandler_s uint8_t nih_irq; /* IRQ number */ }; -struct note_string_s +struct note_wdog_s +{ + struct note_common_s nwd_cmn; /* Common note parameters */ + uintptr_t handler; + uintptr_t arg; +}; + +struct note_heap_s +{ + struct note_common_s nhp_cmn; /* Common note parameters */ + FAR void *heap; + FAR void *mem; + size_t size; + size_t used; +}; + +struct note_printf_s { - struct note_common_s nst_cmn; /* Common note parameters */ - uintptr_t nst_ip; /* Instruction pointer called from */ - char nst_data[1]; /* String data terminated by '\0' */ + struct note_common_s npt_cmn; /* Common note parameters */ + uintptr_t npt_ip; /* Instruction pointer called from */ + FAR const char *npt_fmt; /* Printf format string */ + uint32_t npt_type; /* Printf parameter type */ + char npt_data[1]; /* Print arguments */ }; -#define SIZEOF_NOTE_STRING(n) (sizeof(struct note_string_s) + \ - (n) * sizeof(char)) +#define SIZEOF_NOTE_PRINTF(n) (sizeof(struct note_printf_s) + \ + ((n) - 1) * sizeof(uint8_t)) -struct note_binary_s +struct note_event_s { - struct note_common_s nbi_cmn; /* Common note parameters */ - uintptr_t nbi_ip; /* Instruction pointer called from */ - uint8_t nbi_data[1]; /* Binary data */ + struct note_common_s nev_cmn; /* Common note parameters */ + uintptr_t nev_ip; /* Instruction pointer called from */ + uint8_t nev_data[1]; /* Event data */ }; -#define SIZEOF_NOTE_BINARY(n) (sizeof(struct note_binary_s) + \ - ((n) - 1) * sizeof(uint8_t)) +#define SIZEOF_NOTE_EVENT(n) (sizeof(struct note_event_s) + \ + ((n)) * sizeof(uint8_t)) struct note_counter_s { @@ -536,36 +638,30 @@ void sched_note_irqhandler(int irq, FAR void *handler, bool enter); # define sched_note_irqhandler(i,h,e) #endif +#ifdef CONFIG_SCHED_INSTRUMENTATION_WDOG +void sched_note_wdog(uint8_t event, FAR void *handler, FAR const void *arg); +#else +# define sched_note_wdog(e,h,a) +#endif + +#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP +void sched_note_heap(uint8_t event, FAR void *heap, FAR void *mem, + size_t size, size_t used); +#else +# define sched_note_heap(e,h,m,s,c) +#endif + #ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP -void sched_note_string_ip(uint32_t tag, uintptr_t ip, FAR const char *buf); void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event, - FAR const void *buf, size_t len); + FAR const void *buf, size_t len); void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, - va_list va) printf_like(3, 0); -void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, - va_list va) printf_like(3, 0); -void sched_note_printf_ip(uint32_t tag, uintptr_t ip, - FAR const char *fmt, ...) printf_like(3, 4); -void sched_note_bprintf_ip(uint32_t tag, uintptr_t ip, - FAR const char *fmt, ...) printf_like(3, 4); - -static inline void sched_note_counter_ip(uint32_t tag, uintptr_t ip, - FAR const char *name, - long int value) -{ - struct note_counter_s counter; - counter.value = value; - strlcpy(counter.name, name, sizeof(counter.name)); - sched_note_event_ip(tag, ip, NOTE_DUMP_COUNTER, &counter, sizeof(counter)); -} + uint32_t type, va_list va) printf_like(3, 0); +void sched_note_printf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, + uint32_t type, ...) printf_like(3, 5); #else -# define sched_note_string_ip(t,ip,b) # define sched_note_event_ip(t,ip,e,b,l) -# define sched_note_vprintf_ip(t,ip,f,v) -# define sched_note_vbprintf_ip(t,ip,f,v) -# define sched_note_printf_ip(t,ip,f,...) -# define sched_note_bprintf_ip(t,ip,f,...) -# define sched_note_counter_ip(t,ip,n,v) +# define sched_note_vprintf_ip(t,ip,f,p,v) +# define sched_note_printf_ip(t,ip,f,p,...) #endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */ #if defined(__KERNEL__) || defined(CONFIG_BUILD_FLAT) diff --git a/libs/libc/gdbstub/lib_gdbstub.c b/libs/libc/gdbstub/lib_gdbstub.c index 1cdde7aa466f0..3b5510947556b 100644 --- a/libs/libc/gdbstub/lib_gdbstub.c +++ b/libs/libc/gdbstub/lib_gdbstub.c @@ -1249,17 +1249,10 @@ static int gdb_query(FAR struct gdb_state_s *state) } nxsched_get_stateinfo(tcb, thread_state, sizeof(thread_state)); -#if CONFIG_TASK_NAME_SIZE > 0 snprintf(thread_info, sizeof(thread_info), "Name: %s, State: %s, Priority: %d, Stack: %zu", - tcb->name, thread_state, tcb->sched_priority, + get_task_name(tcb), thread_state, tcb->sched_priority, tcb->adj_stack_size); -#else - snprintf(thread_info, sizeof(thread_info), - "State: %s, Priority: %d, Stack: %zu", - thread_state, tcb->sched_priority, - tcb->adj_stack_size); -#endif ret = gdb_bin2hex(state->pkt_buf, sizeof(state->pkt_buf), thread_info, strlen(thread_info)); @@ -1966,4 +1959,3 @@ int gdb_process(FAR struct gdb_state_s *state, int stopreason, state->last_stopaddr = stopaddr; return ret; } - diff --git a/mm/mm_heap/mm_free.c b/mm/mm_heap/mm_free.c index ab3cda0eae62f..6848ad3ab8bea 100644 --- a/mm/mm_heap/mm_free.c +++ b/mm/mm_heap/mm_free.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "mm_heap/mm.h" @@ -99,11 +100,12 @@ void mm_delayfree(FAR struct mm_heap_s *heap, FAR void *mem, bool delay) return; } + nodesize = mm_malloc_size(heap, mem); #ifdef CONFIG_MM_FILL_ALLOCATIONS - memset(mem, MM_FREE_MAGIC, mm_malloc_size(heap, mem)); + memset(mem, MM_FREE_MAGIC, nodesize); #endif - kasan_poison(mem, mm_malloc_size(heap, mem)); + kasan_poison(mem, nodesize); if (delay) { @@ -126,6 +128,7 @@ void mm_delayfree(FAR struct mm_heap_s *heap, FAR void *mem, bool delay) /* Update heap statistics */ heap->mm_curused -= nodesize; + sched_note_heap(NOTE_HEAP_FREE, heap, mem, nodesize, heap->mm_curused); /* Check if the following node is free and, if so, merge it */ diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c index 6852b439ad1db..ae31af1219de2 100644 --- a/mm/mm_heap/mm_initialize.c +++ b/mm/mm_heap/mm_initialize.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -201,6 +202,9 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart, mm_addfreechunk(heap, node); heap->mm_curused += 2 * MM_SIZEOF_ALLOCNODE; mm_unlock(heap); + + sched_note_heap(NOTE_HEAP_ADD, heap, heapstart, heapsize, + heap->mm_curused); } /**************************************************************************** @@ -366,6 +370,9 @@ void mm_uninitialize(FAR struct mm_heap_s *heap) for (i = 0; i < CONFIG_MM_REGIONS; i++) { kasan_unregister(heap->mm_heapstart[i]); + sched_note_heap(NOTE_HEAP_REMOVE, heap, heap->mm_heapstart[i], + (uintptr_t)heap->mm_heapend[i] - + (uintptr_t)heap->mm_heapstart[i], heap->mm_curused); } #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO) diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c index 96adef1a48501..3d15c326ac354 100644 --- a/mm/mm_heap/mm_malloc.c +++ b/mm/mm_heap/mm_malloc.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "mm_heap/mm.h" @@ -306,7 +307,8 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) /* Update heap statistics */ - heap->mm_curused += MM_SIZEOF_NODE(node); + nodesize = MM_SIZEOF_NODE(node); + heap->mm_curused += nodesize; if (heap->mm_curused > heap->mm_maxused) { heap->mm_maxused = heap->mm_curused; @@ -324,7 +326,9 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) if (ret) { MM_ADD_BACKTRACE(heap, node); - ret = kasan_unpoison(ret, mm_malloc_size(heap, ret)); + ret = kasan_unpoison(ret, nodesize - MM_ALLOCNODE_OVERHEAD); + sched_note_heap(NOTE_HEAP_ALLOC, heap, ret, nodesize, + heap->mm_curused); #ifdef CONFIG_MM_FILL_ALLOCATIONS memset(ret, MM_ALLOC_MAGIC, alignsize - MM_ALLOCNODE_OVERHEAD); #endif diff --git a/mm/mm_heap/mm_memalign.c b/mm/mm_heap/mm_memalign.c index 0aa449f29605f..aa0621889fece 100644 --- a/mm/mm_heap/mm_memalign.c +++ b/mm/mm_heap/mm_memalign.c @@ -30,6 +30,7 @@ #include #include +#include #include "mm_heap/mm.h" @@ -267,7 +268,8 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, /* Update heap statistics */ - heap->mm_curused += MM_SIZEOF_NODE(node); + size = MM_SIZEOF_NODE(node); + heap->mm_curused += size; if (heap->mm_curused > heap->mm_maxused) { heap->mm_maxused = heap->mm_curused; @@ -277,10 +279,10 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, MM_ADD_BACKTRACE(heap, node); - alignedchunk = (uintptr_t)kasan_unpoison - ((FAR const void *)alignedchunk, - mm_malloc_size(heap, - (FAR void *)alignedchunk)); + alignedchunk = (uintptr_t)kasan_unpoison((FAR const void *)alignedchunk, + size - MM_ALLOCNODE_OVERHEAD); + sched_note_heap(NOTE_HEAP_ALLOC, heap, (FAR void *)alignedchunk, size, + heap->mm_curused); DEBUGASSERT(alignedchunk % alignment == 0); return (FAR void *)alignedchunk; diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c index 7125a71f04cea..13fc849541866 100644 --- a/mm/mm_heap/mm_realloc.c +++ b/mm/mm_heap/mm_realloc.c @@ -34,6 +34,7 @@ #include #include +#include #include "mm_heap/mm.h" @@ -382,10 +383,15 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, heap->mm_maxused = heap->mm_curused; } + sched_note_heap(NOTE_HEAP_FREE, heap, oldmem, oldsize, + heap->mm_curused - newsize); + sched_note_heap(NOTE_HEAP_ALLOC, heap, newmem, newsize, + heap->mm_curused); mm_unlock(heap); MM_ADD_BACKTRACE(heap, (FAR char *)newmem - MM_SIZEOF_ALLOCNODE); - newmem = kasan_unpoison(newmem, mm_malloc_size(heap, newmem)); + newmem = kasan_unpoison(newmem, MM_SIZEOF_NODE(oldnode) - + MM_ALLOCNODE_OVERHEAD); if (kasan_reset_tag(newmem) != kasan_reset_tag(oldmem)) { /* Now we have to move the user contents 'down' in memory. memcpy diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c index 4c60f419bf507..ff32de3726250 100644 --- a/mm/tlsf/mm_tlsf.c +++ b/mm/tlsf/mm_tlsf.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "tlsf/tlsf.h" @@ -492,15 +493,12 @@ static void mm_delayfree(FAR struct mm_heap_s *heap, FAR void *mem, { if (mm_lock(heap) == 0) { + size_t size = mm_malloc_size(heap, mem); #ifdef CONFIG_MM_FILL_ALLOCATIONS - memset(mem, MM_FREE_MAGIC, mm_malloc_size(heap, mem)); + memset(mem, MM_FREE_MAGIC, size); #endif - kasan_poison(mem, mm_malloc_size(heap, mem)); - - /* Update heap statistics */ - - heap->mm_curused -= mm_malloc_size(heap, mem); + kasan_poison(mem, size); /* Pass, return to the tlsf pool */ @@ -510,6 +508,10 @@ static void mm_delayfree(FAR struct mm_heap_s *heap, FAR void *mem, } else { + /* Update heap statistics */ + + heap->mm_curused -= size; + sched_note_heap(NOTE_HEAP_FREE, heap, mem, size, heap->mm_curused); tlsf_free(heap->mm_tlsf, mem); } @@ -598,6 +600,9 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart, tlsf_add_pool(heap->mm_tlsf, heapstart, heapsize); mm_unlock(heap); + + sched_note_heap(NOTE_HEAP_ADD, heap, heapstart, heapsize, + heap->mm_curused); } /**************************************************************************** @@ -1134,6 +1139,7 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem) FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) { + size_t nodesize; FAR void *ret; /* In case of zero-length allocations allocate the minimum size object */ @@ -1168,7 +1174,8 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) ret = tlsf_malloc(heap->mm_tlsf, size); #endif - heap->mm_curused += mm_malloc_size(heap, ret); + nodesize = mm_malloc_size(heap, ret); + heap->mm_curused += nodesize; if (heap->mm_curused > heap->mm_maxused) { heap->mm_maxused = heap->mm_curused; @@ -1179,11 +1186,14 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) if (ret) { #if CONFIG_MM_BACKTRACE >= 0 - FAR struct memdump_backtrace_s *buf = ret + mm_malloc_size(heap, ret); + FAR struct memdump_backtrace_s *buf = ret + nodesize; memdump_backtrace(heap, buf); #endif - ret = kasan_unpoison(ret, mm_malloc_size(heap, ret)); + + ret = kasan_unpoison(ret, nodesize); + sched_note_heap(NOTE_HEAP_ALLOC, heap, ret, nodesize, + heap->mm_curused); #ifdef CONFIG_MM_FILL_ALLOCATIONS memset(ret, 0xaa, nodesize); @@ -1218,6 +1228,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, size_t size) { + size_t nodesize; FAR void *ret; #ifdef CONFIG_MM_HEAP_MEMPOOL @@ -1245,7 +1256,8 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, ret = tlsf_memalign(heap->mm_tlsf, alignment, size); #endif - heap->mm_curused += mm_malloc_size(heap, ret); + nodesize = mm_malloc_size(heap, ret); + heap->mm_curused += nodesize; if (heap->mm_curused > heap->mm_maxused) { heap->mm_maxused = heap->mm_curused; @@ -1256,11 +1268,13 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, if (ret) { #if CONFIG_MM_BACKTRACE >= 0 - FAR struct memdump_backtrace_s *buf = ret + mm_malloc_size(heap, ret); + FAR struct memdump_backtrace_s *buf = ret + nodesize; memdump_backtrace(heap, buf); #endif - ret = kasan_unpoison(ret, mm_malloc_size(heap, ret)); + ret = kasan_unpoison(ret, nodesize); + sched_note_heap(NOTE_HEAP_ALLOC, heap, ret, nodesize, + heap->mm_curused); } #if CONFIG_MM_FREE_DELAYCOUNT_MAX > 0 @@ -1302,6 +1316,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size) { FAR void *newmem; + size_t oldsize; + size_t newsize; /* If oldmem is NULL, then realloc is equivalent to malloc */ @@ -1361,7 +1377,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, /* Allocate from the tlsf pool */ DEBUGVERIFY(mm_lock(heap)); - heap->mm_curused -= mm_malloc_size(heap, oldmem); + oldsize = mm_malloc_size(heap, oldmem); + heap->mm_curused -= oldsize; #if CONFIG_MM_BACKTRACE >= 0 newmem = tlsf_realloc(heap->mm_tlsf, oldmem, size + sizeof(struct memdump_backtrace_s)); @@ -1369,7 +1386,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, newmem = tlsf_realloc(heap->mm_tlsf, oldmem, size); #endif - heap->mm_curused += mm_malloc_size(heap, newmem ? newmem : oldmem); + newsize = mm_malloc_size(heap, newmem); + heap->mm_curused += newmem ? newsize : oldsize; if (heap->mm_curused > heap->mm_maxused) { heap->mm_maxused = heap->mm_curused; @@ -1377,20 +1395,23 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, mm_unlock(heap); -#if CONFIG_MM_BACKTRACE >= 0 if (newmem) { - FAR struct memdump_backtrace_s *buf = - newmem + mm_malloc_size(heap, newmem); - +#if CONFIG_MM_BACKTRACE >= 0 + FAR struct memdump_backtrace_s *buf = newmem + newsize; memdump_backtrace(heap, buf); - } #endif + sched_note_heap(NOTE_HEAP_FREE, heap, oldmem, oldsize, + heap->mm_curused - newsize); + sched_note_heap(NOTE_HEAP_ALLOC, heap, newmem, newsize, + heap->mm_curused); + } + #if CONFIG_MM_FREE_DELAYCOUNT_MAX > 0 /* Try again after free delay list */ - if (newmem == NULL && free_delaylist(heap, true)) + else if (free_delaylist(heap, true)) { return mm_realloc(heap, oldmem, size); } @@ -1425,6 +1446,9 @@ void mm_uninitialize(FAR struct mm_heap_s *heap) for (i = 0; i < CONFIG_MM_REGIONS; i++) { kasan_unregister(heap->mm_heapstart[i]); + sched_note_heap(NOTE_HEAP_REMOVE, heap, heap->mm_heapstart[i], + (uintptr_t)heap->mm_heapend[i] - + (uintptr_t)heap->mm_heapstart[i], heap->mm_curused); } #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO) diff --git a/sched/Kconfig b/sched/Kconfig index bf210765f332f..2dbbb0a588f99 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -1284,18 +1284,31 @@ config SCHED_INSTRUMENTATION_IRQHANDLER void sched_note_irqhandler(int irq, FAR void *handler, bool enter); +config SCHED_INSTRUMENTATION_HEAP + bool "Heap monitor hooks" + default n + ---help--- + Enables additional hooks for heap allocation. + + void sched_note_heap(uint8_t event, FAR void* heap, FAR void *mem, size_t size, size_t curused); + +config SCHED_INSTRUMENTATION_WDOG + bool "Watchdog timer monitor hooks" + default n + ---help--- + Enables additional hooks for watchdog timer. + + void sched_note_wdog(uint8_t event, FAR void *handler, FAR const void *arg); + config SCHED_INSTRUMENTATION_DUMP bool "Use note dump for instrumentation" default n ---help--- Use note dump for instrumentation. - void sched_note_string(FAR const char *buf); - void sched_note_dump(uint32_t module, uint8_t event, FAR const void *buf, size_t len); - void sched_note_vprintf(FAR const char *fmt, va_list va); - void sched_note_vbprintf(uint32_t module, uint8_t event, FAR const char *fmt, va_list va); - void sched_note_printf(FAR const char *fmt, ...) printf_like(1, 2); - void sched_note_bprintf(uint32_t module, uint8_t event, FAR const char *fmt, ...); + void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event, FAR const void *buf, size_t len); + void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, uint32_t type, va_list va) printf_like(3, 0); + void sched_note_printf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, uint32_t type, ...) printf_like(3, 5); config SCHED_INSTRUMENTATION_FUNCTION bool "Enable function auto-tracing" diff --git a/sched/misc/assert.c b/sched/misc/assert.c index 53b16d297ef1e..af6cfd0e6abe6 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -416,11 +416,7 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg) #ifndef CONFIG_SCHED_CPULOAD_NONE , intpart, fracpart #endif -#if CONFIG_TASK_NAME_SIZE > 0 - , tcb->name -#else - , "" -#endif + , get_task_name(tcb) , args ); } @@ -632,18 +628,14 @@ static void dump_assert_info(FAR struct tcb_s *rtcb, FAR const char *filename, int linenum, FAR const char *msg, FAR void *regs) { -#if CONFIG_TASK_NAME_SIZE > 0 FAR struct tcb_s *ptcb = NULL; -#endif struct utsname name; -#if CONFIG_TASK_NAME_SIZE > 0 if (rtcb->group && (rtcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) { ptcb = nxsched_get_tcb(rtcb->group->tg_pid); } -#endif uname(&name); _alert("Current Version: %s %s %s %s %s\n", @@ -655,20 +647,16 @@ static void dump_assert_info(FAR struct tcb_s *rtcb, "(CPU%d)" #endif ": " -#if CONFIG_TASK_NAME_SIZE > 0 "%s " "process: %s " -#endif "%p\n", msg ? msg : "", filename ? filename : "", linenum, #ifdef CONFIG_SMP this_cpu(), #endif -#if CONFIG_TASK_NAME_SIZE > 0 - rtcb->name, - ptcb ? ptcb->name : "Kernel", -#endif + get_task_name(rtcb), + ptcb ? get_task_name(ptcb) : "Kernel", rtcb->entry.main); /* Dump current CPU registers, running task stack and backtrace. */ diff --git a/sched/sched/sched_dumponexit.c b/sched/sched/sched_dumponexit.c index 2fde136e338ee..aece6501c06ef 100644 --- a/sched/sched/sched_dumponexit.c +++ b/sched/sched/sched_dumponexit.c @@ -57,8 +57,8 @@ static void dumphandler(FAR struct tcb_s *tcb, FAR void *arg) syslog(LOG_INFO, "tcb=%p name=%s, pid:%d, priority=%d state=%d " "stack_alloc_ptr: %p, adj_stack_size: %zu\n", - tcb, tcb->name, tcb->pid, tcb->sched_priority, tcb->task_state, - tcb->stack_alloc_ptr, tcb->adj_stack_size); + tcb, get_task_name(tcb), tcb->pid, tcb->sched_priority, + tcb->task_state, tcb->stack_alloc_ptr, tcb->adj_stack_size); filelist = &tcb->group->tg_filelist; files_dumplist(filelist); diff --git a/sched/task/task_activate.c b/sched/task/task_activate.c index 00aa1c2e55777..1fcba2695e90d 100644 --- a/sched/task/task_activate.c +++ b/sched/task/task_activate.c @@ -86,11 +86,7 @@ void nxtask_activate(FAR struct tcb_s *tcb) nxsched_remove_blocked(tcb); -#if CONFIG_TASK_NAME_SIZE > 0 - sinfo("%s pid=%d,TCB=%p\n", tcb->name, -#else - sinfo("pid=%d,TCB=%p\n", -#endif + sinfo("%s pid=%d,TCB=%p\n", get_task_name(tcb), tcb->pid, tcb); /* Add the task to ready-to-run task list, and diff --git a/sched/task/task_exit.c b/sched/task/task_exit.c index d840a401d0815..a4efb2bc83917 100644 --- a/sched/task/task_exit.c +++ b/sched/task/task_exit.c @@ -91,11 +91,7 @@ int nxtask_exit(void) dtcb = this_task(); #endif -#if CONFIG_TASK_NAME_SIZE > 0 - sinfo("%s pid=%d,TCB=%p\n", dtcb->name, -#else - sinfo("pid=%d,TCB=%p\n", -#endif + sinfo("%s pid=%d,TCB=%p\n", get_task_name(dtcb), dtcb->pid, dtcb); /* Update scheduler parameters */ diff --git a/sched/wdog/wd_cancel.c b/sched/wdog/wd_cancel.c index 65c063cd56086..538fa03e6b0b7 100644 --- a/sched/wdog/wd_cancel.c +++ b/sched/wdog/wd_cancel.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "sched/sched.h" #include "wdog/wdog.h" @@ -95,6 +96,9 @@ int wd_cancel_irq(FAR struct wdog_s *wdog) return -EINVAL; } + sched_note_wdog(NOTE_WDOG_CANCEL, (FAR void *)wdog->func, + (FAR void *)(uintptr_t)wdog->expired); + /* Prohibit timer interactions with the timer queue until the * cancellation is complete */ diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c index fd703e6c976d2..739cec16a2111 100644 --- a/sched/wdog/wd_start.c +++ b/sched/wdog/wd_start.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "sched/sched.h" #include "wdog/wdog.h" @@ -56,9 +57,11 @@ { \ clock_t start; \ clock_t elapsed; \ + sched_note_wdog(NOTE_WDOG_ENTER, func, (FAR void *)arg); \ start = perf_gettime(); \ func(arg); \ elapsed = perf_gettime() - start; \ + sched_note_wdog(NOTE_WDOG_LEAVE, func, (FAR void *)arg); \ if (elapsed > CONFIG_SCHED_CRITMONITOR_MAXTIME_WDOG) \ { \ CRITMONITOR_PANIC("WDOG %p, %s IRQ, execute too long %ju\n", \ @@ -68,7 +71,15 @@ } \ while (0) #else -# define CALL_FUNC(func, arg) func(arg) +# define CALL_FUNC(func, arg) \ + do \ + { \ + sched_note_wdog(NOTE_WDOG_ENTER, func, (FAR void *)arg); \ + func(arg); \ + sched_note_wdog(NOTE_WDOG_LEAVE, func, (FAR void *)arg); \ + } \ + while (0) + #endif /**************************************************************************** @@ -319,6 +330,8 @@ int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks, wd_insert(wdog, ticks, wdentry, arg); #endif leave_critical_section(flags); + + sched_note_wdog(NOTE_WDOG_START, wdentry, (FAR void *)(uintptr_t)ticks); return OK; } diff --git a/tools/nxstyle.c b/tools/nxstyle.c index ce9b8fb1c4248..ce1a957f092bb 100644 --- a/tools/nxstyle.c +++ b/tools/nxstyle.c @@ -294,12 +294,19 @@ static const char *g_white_content_list[] = * drivers/segger/note_sysview.c */ + "DataType", + "Offset", + "Prio", + "pU32_Value", + "RangeMax", + "RangeMin", "SEGGER_SYSVIEW", - "TaskID", + "ScalingFactor", "sName", - "Prio", + "sUnit", "StackBase", "StackSize", + "TaskID", /* Ref: * drivers/segger/syslog_rtt.c