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 <ederson.desouza@intel.com>
This commit is contained in:
Ederson de Souza 2021-11-22 14:46:19 -08:00 committed by Anas Nashif
commit bdaac354f4
12 changed files with 544 additions and 0 deletions

View file

@ -344,6 +344,41 @@ Locking may not be needed if multiple independent channels are available.
``emit(a ## b ## c, thread_id);`` ``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 API
*** ***
@ -431,3 +466,8 @@ Timers
====== ======
.. doxygengroup:: subsys_tracing_apis_timer .. doxygengroup:: subsys_tracing_apis_timer
Object tracking
===============
.. doxygengroup:: subsys_tracing_object_tracking

View file

@ -1288,6 +1288,7 @@ struct k_timer {
/* user-specific data, also used to support legacy features */ /* user-specific data, also used to support legacy features */
void *user_data; void *user_data;
SYS_PORT_TRACING_TRACKING_FIELD(k_timer)
}; };
#define Z_TIMER_INITIALIZER(obj, expiry, stop) \ #define Z_TIMER_INITIALIZER(obj, expiry, stop) \
@ -1670,6 +1671,8 @@ struct k_queue {
_wait_q_t wait_q; _wait_q_t wait_q;
_POLL_EVENT; _POLL_EVENT;
SYS_PORT_TRACING_TRACKING_FIELD(k_queue)
}; };
#define Z_QUEUE_INITIALIZER(obj) \ #define Z_QUEUE_INITIALIZER(obj) \
@ -2548,6 +2551,8 @@ struct k_stack {
stack_data_t *base, *next, *top; stack_data_t *base, *next, *top;
uint8_t flags; uint8_t flags;
SYS_PORT_TRACING_TRACKING_FIELD(k_stack)
}; };
#define Z_STACK_INITIALIZER(obj, stack_buffer, stack_num_entries) \ #define Z_STACK_INITIALIZER(obj, stack_buffer, stack_num_entries) \
@ -2705,6 +2710,8 @@ struct k_mutex {
/** Original thread priority */ /** Original thread priority */
int owner_orig_prio; int owner_orig_prio;
SYS_PORT_TRACING_TRACKING_FIELD(k_mutex)
}; };
/** /**
@ -2888,6 +2895,8 @@ struct k_sem {
_POLL_EVENT; _POLL_EVENT;
SYS_PORT_TRACING_TRACKING_FIELD(k_sem)
}; };
#define Z_SEM_INITIALIZER(obj, initial_count, count_limit) \ #define Z_SEM_INITIALIZER(obj, initial_count, count_limit) \
@ -4328,6 +4337,8 @@ struct k_msgq {
/** Message queue */ /** Message queue */
uint8_t flags; uint8_t flags;
SYS_PORT_TRACING_TRACKING_FIELD(k_msgq)
}; };
/** /**
* @cond INTERNAL_HIDDEN * @cond INTERNAL_HIDDEN
@ -4617,6 +4628,7 @@ struct k_mbox {
_wait_q_t rx_msg_queue; _wait_q_t rx_msg_queue;
struct k_spinlock lock; struct k_spinlock lock;
SYS_PORT_TRACING_TRACKING_FIELD(k_mbox)
}; };
/** /**
* @cond INTERNAL_HIDDEN * @cond INTERNAL_HIDDEN
@ -4756,6 +4768,8 @@ struct k_pipe {
} wait_q; /** Wait queue */ } wait_q; /** Wait queue */
uint8_t flags; /**< Flags */ uint8_t flags; /**< Flags */
SYS_PORT_TRACING_TRACKING_FIELD(k_pipe)
}; };
/** /**
@ -4929,6 +4943,7 @@ struct k_mem_slab {
uint32_t max_used; uint32_t max_used;
#endif #endif
SYS_PORT_TRACING_TRACKING_FIELD(k_mem_slab)
}; };
#define Z_MEM_SLAB_INITIALIZER(obj, slab_buffer, slab_block_size, \ #define Z_MEM_SLAB_INITIALIZER(obj, slab_buffer, slab_block_size, \

View file

@ -8,6 +8,8 @@
#include <kernel.h> #include <kernel.h>
#include "tracking.h"
#if defined CONFIG_SEGGER_SYSTEMVIEW #if defined CONFIG_SEGGER_SYSTEMVIEW
#include "tracing_sysview.h" #include "tracing_sysview.h"
#elif defined CONFIG_TRACING_CTF #elif defined CONFIG_TRACING_CTF

View file

@ -18,6 +18,8 @@
#define SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(obj_type, func, obj, ...) do { } while (false) #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_OBJ_FUNC_EXIT(obj_type, func, obj, ...) do { } while (false)
#define SYS_PORT_TRACING_TRACKING_FIELD(type)
#else #else
/** /**
@ -54,6 +56,15 @@
#define _SYS_PORT_TRACING_OBJ_FUNC_EXIT(name, func) \ #define _SYS_PORT_TRACING_OBJ_FUNC_EXIT(name, func) \
sys_port_trace_ ## name ## _ ## func ## _exit 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 * Object trace macros part of the system for checking if certain
* objects should be traced or not depending on the tracing configuration. * objects should be traced or not depending on the tracing configuration.
@ -252,6 +263,8 @@
do { \ do { \
SYS_PORT_TRACING_TYPE_MASK(obj_type, \ SYS_PORT_TRACING_TYPE_MASK(obj_type, \
_SYS_PORT_TRACING_OBJ_INIT(obj_type)(obj, ##__VA_ARGS__)); \ _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) } while (false)
/** /**
@ -268,6 +281,8 @@
do { \ do { \
SYS_PORT_TRACING_TYPE_MASK(obj_type, \ SYS_PORT_TRACING_TYPE_MASK(obj_type, \
_SYS_PORT_TRACING_OBJ_FUNC(obj_type, func)(obj, ##__VA_ARGS__)); \ _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) } while (false)
/** /**
@ -322,6 +337,14 @@
_SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func)(obj, ##__VA_ARGS__)); \ _SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func)(obj, ##__VA_ARGS__)); \
} while (false) } 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 */ /** @} */ /* end of subsys_tracing_macros */
#endif /* CONFIG_TRACING */ #endif /* CONFIG_TRACING */

142
include/tracing/tracking.h Normal file
View file

@ -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 <kernel.h>
#include <kernel_structs.h>
#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_ */

View file

@ -45,6 +45,11 @@ if(NOT CONFIG_PERCEPIO_TRACERECORDER AND NOT CONFIG_TRACING_CTF
zephyr_sources(tracing_none.c) zephyr_sources(tracing_none.c)
endif() endif()
zephyr_sources_ifdef(
CONFIG_TRACING_OBJECT_TRACKING
tracing_tracking.c
)
zephyr_include_directories_ifdef( zephyr_include_directories_ifdef(
CONFIG_TRACING CONFIG_TRACING
${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/kernel/include

View file

@ -202,6 +202,12 @@ config TRACING_CMD_BUFFER_SIZE
help help
Size of tracing command buffer. 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" menu "Tracing Configuration"
config TRACING_SYSCALL config TRACING_SYSCALL

View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2021 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <init.h>
#include <spinlock.h>
#include <sys/slist.h>
#include <tracing/tracking.h>
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);

View file

@ -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})

View file

@ -0,0 +1,5 @@
CONFIG_ZTEST=y
CONFIG_IRQ_OFFLOAD=y
CONFIG_TRACING=y
CONFIG_TRACING_OBJECT_TRACKING=y
CONFIG_TRACING_NONE=y

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2021 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
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);
}

View file

@ -0,0 +1,4 @@
tests:
kernel.objects.tracking:
tags: kernel
platform_exclude: qemu_x86_tiny