From bdaac354f4cb0ad91d952c2f6941c16240d84da2 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 22 Nov 2021 14:46:19 -0800 Subject: [PATCH] kernel: Bring back object tracking When CONFIG_TRACING_OBJECT_TRACKING is enabled, the kernel will keep lists of some objects (detailed below), so that debuggers or other tools can keep track of them. The lists of objects are: struct k_timer *_track_list_k_timer; struct k_mem_slab *_track_list_k_mem_slab; struct k_sem *_track_list_k_sem; struct k_mutex *_track_list_k_mutex; struct k_stack *_track_list_k_stack; struct k_msgq *_track_list_k_msgq; struct k_mbox *_track_list_k_mbox; struct k_pipe *_track_list_k_pipe; struct k_queue *_track_list_k_queue; Note that while CONFIG_TRACING is needed, one can always use CONFIG_TRACE_NONE=y. Also, tracking will only be done for objects that are also being traced (so, to prevent tracking of some type of object, such as k_timer, just make CONFIG_TRACING_TIMER=n). Some simple "sanity checking" tests are also added in this patch. Signed-off-by: Ederson de Souza --- doc/guides/debug_tools/tracing/index.rst | 40 ++++++ include/kernel.h | 15 +++ include/tracing/tracing.h | 2 + include/tracing/tracing_macros.h | 23 ++++ include/tracing/tracking.h | 142 +++++++++++++++++++++ subsys/tracing/CMakeLists.txt | 5 + subsys/tracing/Kconfig | 6 + subsys/tracing/tracing_tracking.c | 144 ++++++++++++++++++++++ tests/kernel/obj_tracking/CMakeLists.txt | 8 ++ tests/kernel/obj_tracking/prj.conf | 5 + tests/kernel/obj_tracking/src/main.c | 150 +++++++++++++++++++++++ tests/kernel/obj_tracking/testcase.yaml | 4 + 12 files changed, 544 insertions(+) create mode 100644 include/tracing/tracking.h create mode 100644 subsys/tracing/tracing_tracking.c create mode 100644 tests/kernel/obj_tracking/CMakeLists.txt create mode 100644 tests/kernel/obj_tracking/prj.conf create mode 100644 tests/kernel/obj_tracking/src/main.c create mode 100644 tests/kernel/obj_tracking/testcase.yaml diff --git a/doc/guides/debug_tools/tracing/index.rst b/doc/guides/debug_tools/tracing/index.rst index 73d8709d2e4..18f63db2763 100644 --- a/doc/guides/debug_tools/tracing/index.rst +++ b/doc/guides/debug_tools/tracing/index.rst @@ -344,6 +344,41 @@ Locking may not be needed if multiple independent channels are available. ``emit(a ## b ## c, thread_id);`` +Object tracking +*************** + +The kernel can also maintain lists of objects that can be used to track +their usage. Currently, the following lists can be enabled:: + + struct k_timer *_track_list_k_timer; + struct k_mem_slab *_track_list_k_mem_slab; + struct k_sem *_track_list_k_sem; + struct k_mutex *_track_list_k_mutex; + struct k_stack *_track_list_k_stack; + struct k_msgq *_track_list_k_msgq; + struct k_mbox *_track_list_k_mbox; + struct k_pipe *_track_list_k_pipe; + struct k_queue *_track_list_k_queue; + +Those global variables are the head of each list - they can be traversed +with the help of macro ``SYS_PORT_TRACK_NEXT``. For instance, to traverse +all initialized mutexes, one can write:: + + struct k_mutex *cur = _track_list_k_mutex; + while (cur != NULL) { + /* Do something */ + + cur = SYS_PORT_TRACK_NEXT(cur); + } + +To enable object tracking, enable :kconfig:`CONFIG_TRACING_OBJECT_TRACKING`. +Note that each list can be enabled or disabled via their tracing +configuration. For example, to disable tracking of semaphores, one can +disable :kconfig:`CONFIG_TRACING_SEMAPHORE`. + +Object tracking is behind tracing configuration as it currently leverages +tracing infrastructure to perform the tracking. + API *** @@ -431,3 +466,8 @@ Timers ====== .. doxygengroup:: subsys_tracing_apis_timer + +Object tracking +=============== + +.. doxygengroup:: subsys_tracing_object_tracking diff --git a/include/kernel.h b/include/kernel.h index c7e370ae301..59419549d9b 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -1288,6 +1288,7 @@ struct k_timer { /* user-specific data, also used to support legacy features */ void *user_data; + SYS_PORT_TRACING_TRACKING_FIELD(k_timer) }; #define Z_TIMER_INITIALIZER(obj, expiry, stop) \ @@ -1670,6 +1671,8 @@ struct k_queue { _wait_q_t wait_q; _POLL_EVENT; + + SYS_PORT_TRACING_TRACKING_FIELD(k_queue) }; #define Z_QUEUE_INITIALIZER(obj) \ @@ -2548,6 +2551,8 @@ struct k_stack { stack_data_t *base, *next, *top; uint8_t flags; + + SYS_PORT_TRACING_TRACKING_FIELD(k_stack) }; #define Z_STACK_INITIALIZER(obj, stack_buffer, stack_num_entries) \ @@ -2705,6 +2710,8 @@ struct k_mutex { /** Original thread priority */ int owner_orig_prio; + + SYS_PORT_TRACING_TRACKING_FIELD(k_mutex) }; /** @@ -2888,6 +2895,8 @@ struct k_sem { _POLL_EVENT; + SYS_PORT_TRACING_TRACKING_FIELD(k_sem) + }; #define Z_SEM_INITIALIZER(obj, initial_count, count_limit) \ @@ -4328,6 +4337,8 @@ struct k_msgq { /** Message queue */ uint8_t flags; + + SYS_PORT_TRACING_TRACKING_FIELD(k_msgq) }; /** * @cond INTERNAL_HIDDEN @@ -4617,6 +4628,7 @@ struct k_mbox { _wait_q_t rx_msg_queue; struct k_spinlock lock; + SYS_PORT_TRACING_TRACKING_FIELD(k_mbox) }; /** * @cond INTERNAL_HIDDEN @@ -4756,6 +4768,8 @@ struct k_pipe { } wait_q; /** Wait queue */ uint8_t flags; /**< Flags */ + + SYS_PORT_TRACING_TRACKING_FIELD(k_pipe) }; /** @@ -4929,6 +4943,7 @@ struct k_mem_slab { uint32_t max_used; #endif + SYS_PORT_TRACING_TRACKING_FIELD(k_mem_slab) }; #define Z_MEM_SLAB_INITIALIZER(obj, slab_buffer, slab_block_size, \ diff --git a/include/tracing/tracing.h b/include/tracing/tracing.h index f0bb6c83f4d..8e09907369e 100644 --- a/include/tracing/tracing.h +++ b/include/tracing/tracing.h @@ -8,6 +8,8 @@ #include +#include "tracking.h" + #if defined CONFIG_SEGGER_SYSTEMVIEW #include "tracing_sysview.h" #elif defined CONFIG_TRACING_CTF diff --git a/include/tracing/tracing_macros.h b/include/tracing/tracing_macros.h index ebb75df9365..e04599b501e 100644 --- a/include/tracing/tracing_macros.h +++ b/include/tracing/tracing_macros.h @@ -18,6 +18,8 @@ #define SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(obj_type, func, obj, ...) do { } while (false) #define SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func, obj, ...) do { } while (false) +#define SYS_PORT_TRACING_TRACKING_FIELD(type) + #else /** @@ -54,6 +56,15 @@ #define _SYS_PORT_TRACING_OBJ_FUNC_EXIT(name, func) \ sys_port_trace_ ## name ## _ ## func ## _exit +/* + * Helper macros for the object tracking system + */ + +#define _SYS_PORT_TRACKING_OBJ_INIT(name) \ + sys_port_track_ ## name ## _init +#define _SYS_PORT_TRACKING_OBJ_FUNC(name, func) \ + sys_port_track_ ## name ## _ ## func + /* * Object trace macros part of the system for checking if certain * objects should be traced or not depending on the tracing configuration. @@ -252,6 +263,8 @@ do { \ SYS_PORT_TRACING_TYPE_MASK(obj_type, \ _SYS_PORT_TRACING_OBJ_INIT(obj_type)(obj, ##__VA_ARGS__)); \ + SYS_PORT_TRACING_TYPE_MASK(obj_type, \ + _SYS_PORT_TRACKING_OBJ_INIT(obj_type)(obj, ##__VA_ARGS__)); \ } while (false) /** @@ -268,6 +281,8 @@ do { \ SYS_PORT_TRACING_TYPE_MASK(obj_type, \ _SYS_PORT_TRACING_OBJ_FUNC(obj_type, func)(obj, ##__VA_ARGS__)); \ + SYS_PORT_TRACING_TYPE_MASK(obj_type, \ + _SYS_PORT_TRACKING_OBJ_FUNC(obj_type, func)(obj, ##__VA_ARGS__)); \ } while (false) /** @@ -322,6 +337,14 @@ _SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func)(obj, ##__VA_ARGS__)); \ } while (false) +/** + * @brief Field added to kernel objects so they are tracked. + * + * @param type Type of object being tracked (k_thread, k_sem, etc.) + */ +#define SYS_PORT_TRACING_TRACKING_FIELD(type) \ + SYS_PORT_TRACING_TYPE_MASK(type, struct type *_obj_track_next;) + /** @} */ /* end of subsys_tracing_macros */ #endif /* CONFIG_TRACING */ diff --git a/include/tracing/tracking.h b/include/tracing/tracking.h new file mode 100644 index 00000000000..6b030ecf943 --- /dev/null +++ b/include/tracing/tracking.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_TRACING_TRACKING_H_ +#define ZEPHYR_INCLUDE_TRACING_TRACKING_H_ + +#include +#include + +#if defined(CONFIG_TRACING_OBJECT_TRACKING) || defined(__DOXYGEN__) + +/** + * @brief Object tracking + * + * Object tracking provides lists to kernel objects, so their + * existence and current status can be tracked. + * + * The following global variables are the heads of available lists: + * - _track_list_k_timer + * - _track_list_k_mem_slab + * - _track_list_k_sem + * - _track_list_k_mutex + * - _track_list_k_stack + * - _track_list_k_msgq + * - _track_list_k_mbox + * - _track_list_k_pipe + * - _track_list_k_queue + * + * @defgroup subsys_tracing_object_tracking Object tracking + * @ingroup subsys_tracing + * @{ + */ + +extern struct k_timer *_track_list_k_timer; +extern struct k_mem_slab *_track_list_k_mem_slab; +extern struct k_sem *_track_list_k_sem; +extern struct k_mutex *_track_list_k_mutex; +extern struct k_stack *_track_list_k_stack; +extern struct k_msgq *_track_list_k_msgq; +extern struct k_mbox *_track_list_k_mbox; +extern struct k_pipe *_track_list_k_pipe; +extern struct k_queue *_track_list_k_queue; + +/** + * @brief Gets node's next element in a object tracking list. + * + * @param list Node to get next element from. + */ +#define SYS_PORT_TRACK_NEXT(list)((list)->_obj_track_next) + +/** @cond INTERNAL_HIDDEN */ + +#define sys_port_track_k_thread_start(thread) +#define sys_port_track_k_thread_create(new_thread) +#define sys_port_track_k_thread_sched_ready(thread) +#define sys_port_track_k_thread_wakeup(thread) +#define sys_port_track_k_thread_sched_priority_set(thread, prio) +#define sys_port_track_k_work_delayable_init(dwork) +#define sys_port_track_k_work_queue_init(queue) +#define sys_port_track_k_work_init(work) +#define sys_port_track_k_mutex_init(mutex, ret) \ + sys_track_k_mutex_init(mutex) +#define sys_port_track_k_timer_stop(timer) +#define sys_port_track_k_timer_start(timer) +#define sys_port_track_k_timer_init(timer) \ + sys_track_k_timer_init(timer) +#define sys_port_track_k_queue_peek_tail(queue, ret) +#define sys_port_track_k_queue_peek_head(queue, ret) +#define sys_port_track_k_queue_cancel_wait(queue) +#define sys_port_track_k_queue_init(queue) \ + sys_track_k_queue_init(queue) +#define sys_port_track_k_pipe_init(pipe) \ + sys_track_k_pipe_init(pipe) +#define sys_port_track_k_condvar_init(condvar, ret) +#define sys_port_track_k_stack_init(stack) \ + sys_track_k_stack_init(stack) +#define sys_port_track_k_thread_name_set(thread, ret) +#define sys_port_track_k_sem_reset(sem) +#define sys_port_track_k_sem_init(sem, ret) \ + sys_track_k_sem_init(sem) +#define sys_port_track_k_msgq_purge(msgq) +#define sys_port_track_k_msgq_peek(msgq, ret) +#define sys_port_track_k_msgq_init(msgq) \ + sys_track_k_msgq_init(msgq) +#define sys_port_track_k_mbox_init(mbox) \ + sys_track_k_mbox_init(mbox) +#define sys_port_track_k_mem_slab_init(slab, rc) \ + sys_track_k_mem_slab_init(slab) +#define sys_port_track_k_heap_free(h) +#define sys_port_track_k_heap_init(h) + +void sys_track_k_timer_init(struct k_timer *timer); +void sys_track_k_mem_slab_init(struct k_mem_slab *slab); +void sys_track_k_sem_init(struct k_sem *sem); +void sys_track_k_mutex_init(struct k_mutex *mutex); +void sys_track_k_stack_init(struct k_stack *stack); +void sys_track_k_msgq_init(struct k_msgq *msgq); +void sys_track_k_mbox_init(struct k_mbox *mbox); +void sys_track_k_pipe_init(struct k_pipe *pipe); +void sys_track_k_queue_init(struct k_queue *queue); + +/** @endcond */ + +/** @} */ /* end of subsys_tracing_object_tracking */ + +#else + +#define sys_port_track_k_thread_start(thread) +#define sys_port_track_k_thread_create(new_thread) +#define sys_port_track_k_thread_sched_ready(thread) +#define sys_port_track_k_thread_wakeup(thread) +#define sys_port_track_k_thread_sched_priority_set(thread, prio) +#define sys_port_track_k_work_delayable_init(dwork) +#define sys_port_track_k_work_queue_init(queue) +#define sys_port_track_k_work_init(work) +#define sys_port_track_k_mutex_init(mutex, ret) +#define sys_port_track_k_timer_stop(timer) +#define sys_port_track_k_timer_start(timer) +#define sys_port_track_k_timer_init(timer) +#define sys_port_track_k_queue_peek_tail(queue, ret) +#define sys_port_track_k_queue_peek_head(queue, ret) +#define sys_port_track_k_queue_cancel_wait(queue) +#define sys_port_track_k_queue_init(queue) +#define sys_port_track_k_pipe_init(pipe) +#define sys_port_track_k_condvar_init(condvar, ret) +#define sys_port_track_k_stack_init(stack) +#define sys_port_track_k_thread_name_set(thread, ret) +#define sys_port_track_k_sem_reset(sem) +#define sys_port_track_k_sem_init(sem, ret) +#define sys_port_track_k_msgq_purge(msgq) +#define sys_port_track_k_msgq_peek(msgq, ret) +#define sys_port_track_k_msgq_init(msgq) +#define sys_port_track_k_mbox_init(mbox) +#define sys_port_track_k_mem_slab_init(slab, rc) +#define sys_port_track_k_heap_free(h) +#define sys_port_track_k_heap_init(h) + +#endif + +#endif /* ZEPHYR_INCLUDE_TRACING_TRACKING_H_ */ diff --git a/subsys/tracing/CMakeLists.txt b/subsys/tracing/CMakeLists.txt index 325bcfe8269..1c0cca52319 100644 --- a/subsys/tracing/CMakeLists.txt +++ b/subsys/tracing/CMakeLists.txt @@ -45,6 +45,11 @@ if(NOT CONFIG_PERCEPIO_TRACERECORDER AND NOT CONFIG_TRACING_CTF zephyr_sources(tracing_none.c) endif() +zephyr_sources_ifdef( + CONFIG_TRACING_OBJECT_TRACKING + tracing_tracking.c + ) + zephyr_include_directories_ifdef( CONFIG_TRACING ${ZEPHYR_BASE}/kernel/include diff --git a/subsys/tracing/Kconfig b/subsys/tracing/Kconfig index 9785acafafd..5770b548992 100644 --- a/subsys/tracing/Kconfig +++ b/subsys/tracing/Kconfig @@ -202,6 +202,12 @@ config TRACING_CMD_BUFFER_SIZE help Size of tracing command buffer. +config TRACING_OBJECT_TRACKING + bool "Enable object tracking" + default n + help + Keep lists to track kernel objects. + menu "Tracing Configuration" config TRACING_SYSCALL diff --git a/subsys/tracing/tracing_tracking.c b/subsys/tracing/tracing_tracking.c new file mode 100644 index 00000000000..8fcd2f29b93 --- /dev/null +++ b/subsys/tracing/tracing_tracking.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +struct k_timer *_track_list_k_timer; +struct k_spinlock _track_list_k_timer_lock; + +struct k_mem_slab *_track_list_k_mem_slab; +struct k_spinlock _track_list_k_mem_slab_lock; + +struct k_sem *_track_list_k_sem; +struct k_spinlock _track_list_k_sem_lock; + +struct k_mutex *_track_list_k_mutex; +struct k_spinlock _track_list_k_mutex_lock; + +struct k_stack *_track_list_k_stack; +struct k_spinlock _track_list_k_stack_lock; + +struct k_msgq *_track_list_k_msgq; +struct k_spinlock _track_list_k_msgq_lock; + +struct k_mbox *_track_list_k_mbox; +struct k_spinlock _track_list_k_mbox_lock; + +struct k_pipe *_track_list_k_pipe; +struct k_spinlock _track_list_k_pipe_lock; + +struct k_queue *_track_list_k_queue; +struct k_spinlock _track_list_k_queue_lock; + +#define SYS_TRACK_LIST_PREPEND(list, obj) \ + do { \ + k_spinlock_key_t key = k_spin_lock(&list ## _lock); \ + obj->_obj_track_next = list; \ + list = obj; \ + k_spin_unlock(&list ## _lock, key); \ + } while (false) + +#define SYS_TRACK_STATIC_INIT(type, ...) \ + do { \ + STRUCT_SECTION_FOREACH(type, obj) \ + _SYS_PORT_TRACKING_OBJ_INIT(type)(obj, ##__VA_ARGS__); \ + } while (false) + + +void sys_track_k_timer_init(struct k_timer *timer) +{ + SYS_PORT_TRACING_TYPE_MASK(k_timer, + SYS_TRACK_LIST_PREPEND(_track_list_k_timer, timer)); +} + +void sys_track_k_mem_slab_init(struct k_mem_slab *slab) +{ + SYS_PORT_TRACING_TYPE_MASK(k_mem_slab, + SYS_TRACK_LIST_PREPEND(_track_list_k_mem_slab, slab)); +} + +void sys_track_k_sem_init(struct k_sem *sem) +{ + if (sem) { + SYS_PORT_TRACING_TYPE_MASK(k_sem, + SYS_TRACK_LIST_PREPEND(_track_list_k_sem, sem)); + } +} + +void sys_track_k_mutex_init(struct k_mutex *mutex) +{ + SYS_PORT_TRACING_TYPE_MASK(k_mutex, + SYS_TRACK_LIST_PREPEND(_track_list_k_mutex, mutex)); +} + +void sys_track_k_stack_init(struct k_stack *stack) +{ + SYS_PORT_TRACING_TYPE_MASK(k_stack, + SYS_TRACK_LIST_PREPEND(_track_list_k_stack, stack)); +} + +void sys_track_k_msgq_init(struct k_msgq *msgq) +{ + SYS_PORT_TRACING_TYPE_MASK(k_msgq, + SYS_TRACK_LIST_PREPEND(_track_list_k_msgq, msgq)); +} + +void sys_track_k_mbox_init(struct k_mbox *mbox) +{ + SYS_PORT_TRACING_TYPE_MASK(k_mbox, + SYS_TRACK_LIST_PREPEND(_track_list_k_mbox, mbox)); +} + +void sys_track_k_pipe_init(struct k_pipe *pipe) +{ + SYS_PORT_TRACING_TYPE_MASK(k_pipe, + SYS_TRACK_LIST_PREPEND(_track_list_k_pipe, pipe)); +} + +void sys_track_k_queue_init(struct k_queue *queue) +{ + SYS_PORT_TRACING_TYPE_MASK(k_queue, + SYS_TRACK_LIST_PREPEND(_track_list_k_queue, queue)); +} + +static int sys_track_static_init(const struct device *arg) +{ + ARG_UNUSED(arg); + + SYS_PORT_TRACING_TYPE_MASK(k_timer, + SYS_TRACK_STATIC_INIT(k_timer)); + + SYS_PORT_TRACING_TYPE_MASK(k_mem_slab, + SYS_TRACK_STATIC_INIT(k_mem_slab, 0)); + + SYS_PORT_TRACING_TYPE_MASK(k_sem, + SYS_TRACK_STATIC_INIT(k_sem, 0)); + + SYS_PORT_TRACING_TYPE_MASK(k_mutex, + SYS_TRACK_STATIC_INIT(k_mutex, 0)); + + SYS_PORT_TRACING_TYPE_MASK(k_stack, + SYS_TRACK_STATIC_INIT(k_stack)); + + SYS_PORT_TRACING_TYPE_MASK(k_msgq, + SYS_TRACK_STATIC_INIT(k_msgq)); + + SYS_PORT_TRACING_TYPE_MASK(k_mbox, + SYS_TRACK_STATIC_INIT(k_mbox)); + + SYS_PORT_TRACING_TYPE_MASK(k_pipe, + SYS_TRACK_STATIC_INIT(k_pipe)); + + SYS_PORT_TRACING_TYPE_MASK(k_queue, + SYS_TRACK_STATIC_INIT(k_queue)); + + return 0; +} + +SYS_INIT(sys_track_static_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); diff --git a/tests/kernel/obj_tracking/CMakeLists.txt b/tests/kernel/obj_tracking/CMakeLists.txt new file mode 100644 index 00000000000..4f6bd17abd4 --- /dev/null +++ b/tests/kernel/obj_tracking/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(obj_tracking) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/obj_tracking/prj.conf b/tests/kernel/obj_tracking/prj.conf new file mode 100644 index 00000000000..35cfc0e951e --- /dev/null +++ b/tests/kernel/obj_tracking/prj.conf @@ -0,0 +1,5 @@ +CONFIG_ZTEST=y +CONFIG_IRQ_OFFLOAD=y +CONFIG_TRACING=y +CONFIG_TRACING_OBJECT_TRACKING=y +CONFIG_TRACING_NONE=y diff --git a/tests/kernel/obj_tracking/src/main.c b/tests/kernel/obj_tracking/src/main.c new file mode 100644 index 00000000000..817e4517103 --- /dev/null +++ b/tests/kernel/obj_tracking/src/main.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +void dummy_fn(struct k_timer *timer) +{ + ARG_UNUSED(timer); +} + +K_TIMER_DEFINE(timer_s, dummy_fn, NULL); +K_MEM_SLAB_DEFINE(slab_s, 8, 2, 8); +K_SEM_DEFINE(sem_s, 0, 1); +K_MUTEX_DEFINE(mutex_s); +K_STACK_DEFINE(stack_s, 64); +K_MSGQ_DEFINE(msgq_s, sizeof(int), 2, 4); +K_MBOX_DEFINE(mbox_s); +K_PIPE_DEFINE(pipe_s, 64, 4); +K_QUEUE_DEFINE(queue_s); + +unsigned char __aligned(4) pipe_buffer[64]; +char __aligned(4) slab_buffer[8 * 4]; +stack_data_t stack_array[8 * 4]; +int msgq_buffer[64]; + +void test_obj_tracking_sanity(void) +{ + struct k_timer timer; + struct k_mem_slab slab; + struct k_sem sem; + struct k_mutex mutex; + struct k_stack stack; + struct k_msgq msgq; + struct k_mbox mbox; + struct k_pipe pipe; + struct k_queue queue; + void *list; + int count; + + k_timer_init(&timer, dummy_fn, NULL); + count = 0; + list = _track_list_k_timer; + while (list != NULL) { + if (list == &timer || list == &timer_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_timer *)list); + } + zassert_equal(count, 2, "Wrong number of timer objects"); + + k_mem_slab_init(&slab, slab_buffer, 8, 4); + count = 0; + list = _track_list_k_mem_slab; + while (list != NULL) { + if (list == &slab || list == &slab_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_mem_slab *)list); + } + zassert_equal(count, 2, "Wrong number of mem_slab objects"); + + k_sem_init(&sem, 1, 2); + count = 0; + list = _track_list_k_sem; + while (list != NULL) { + if (list == &sem || list == &sem_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_sem *)list); + } + zassert_equal(count, 2, "Wrong number of semaphore objects"); + + k_mutex_init(&mutex); + count = 0; + list = _track_list_k_mutex; + while (list != NULL) { + if (list == &mutex || list == &mutex_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_mutex *)list); + } + zassert_equal(count, 2, "Wrong number of mutex objects"); + + k_stack_init(&stack, stack_array, 20); + count = 0; + list = _track_list_k_stack; + while (list != NULL) { + if (list == &stack || list == &stack_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_stack *)list); + } + zassert_equal(count, 2, "Wrong number of stack objects"); + + k_msgq_init(&msgq, (char *)msgq_buffer, sizeof(int), 8); + count = 0; + list = _track_list_k_msgq; + while (list != NULL) { + if (list == &msgq || list == &msgq_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_msgq *)list); + } + zassert_equal(count, 2, "Wrong number of message queue objects"); + + k_mbox_init(&mbox); + count = 0; + list = _track_list_k_mbox; + while (list != NULL) { + if (list == &mbox || list == &mbox_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_mbox *)list); + } + zassert_equal(count, 2, "Wrong number of mbox objects"); + + k_pipe_init(&pipe, pipe_buffer, sizeof(pipe_buffer)); + count = 0; + list = _track_list_k_pipe; + while (list != NULL) { + if (list == &pipe || list == &pipe_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_pipe *)list); + } + zassert_equal(count, 2, "Wrong number of pipe objects"); + + k_queue_init(&queue); + count = 0; + list = _track_list_k_queue; + while (list != NULL) { + if (list == &queue || list == &queue_s) { + count++; + } + list = SYS_PORT_TRACK_NEXT((struct k_queue *)list); + } + zassert_equal(count, 2, "Wrong number of queue objects"); +} + +void test_main(void) +{ + ztest_test_suite(obj_tracking, + ztest_unit_test(test_obj_tracking_sanity) + ); + + ztest_run_test_suite(obj_tracking); +} diff --git a/tests/kernel/obj_tracking/testcase.yaml b/tests/kernel/obj_tracking/testcase.yaml new file mode 100644 index 00000000000..aa190a9d4b2 --- /dev/null +++ b/tests/kernel/obj_tracking/testcase.yaml @@ -0,0 +1,4 @@ +tests: + kernel.objects.tracking: + tags: kernel + platform_exclude: qemu_x86_tiny