Object Cores
Object cores are a kernel debugging tool that can be used to both identify and perform operations on registered objects.
Object Core Concepts
Each instance of an object embeds an object core field named obj_core. Objects of the same type are linked together via their respective object cores to form a singly linked list. Each object core also links to the their respective object type. Each object type contains a singly linked list linking together all the object cores of that type. Object types are also linked together via a singly linked list. Together, this can allow debugging tools to traverse all the objects in the system.
- Object cores have been integrated into following kernel objects:
Developers are free to integrate them if desired into other objects within their projects.
Object Core Statistics Concepts
A variety of kernel objects allow for the gathering and reporting of statistics. Object cores provide a uniform means to retrieve that information via object core statistics. When enabled, the object type contains a pointer to a statistics descriptor that defines the various operations that have been enabled for interfacing with the object’s statistics. Additionally, the object core contains a pointer to the “raw” statistical information associated with that object. Raw data is the raw, unmanipulated data associated with the statistics. Queried data may be “raw”, but it may also have been manipulated in some way by calculation (such as determining an average).
The following table indicates both what objects have been integrated into the object core statistics as well as the structures used for both “raw” and “queried” data.
Object |
Raw Data Type |
Query Data Type |
---|---|---|
struct mem_slab |
struct mem_slab_info |
struct sys_memory_stats |
struct sys_mem_blocks |
struct sys_mem_blocks_info |
struct sys_memory_stats |
struct k_thread |
struct k_cycle_stats |
struct k_thread_runtime_stats |
struct _cpu |
struct k_cycle_stats |
struct k_thread_runtime_stats |
struct z_kernel |
struct k_cycle_stats[num CPUs] |
struct k_thread_runtime_stats |
Implementation
Defining a New Object Type
An object type is defined using a global variable of type
k_obj_type
. It must be initialized before any objects of that type
are initialized. The following code shows how a new object type can be
initialized for use with object cores and object core statistics.
/* Unique object type ID */
#define K_OBJ_TYPE_MY_NEW_TYPE K_OBJ_TYPE_ID_GEN("UNIQ")
struct k_obj_type my_obj_type;
struct my_obj_type_raw_info {
...
};
struct my_obj_type_query_stats {
...
};
struct my_new_obj {
...
struct k_obj_core obj_core;
struct my_obj_type_raw_info info;
};
struct k_obj_core_stats_desc my_obj_type_stats_desc = {
.raw_size = sizeof(struct my_obj_type_raw_stats),
.query_size = sizeof(struct my_obj_type_query_stats),
.raw = my_obj_type_stats_raw,
.query = my_obj_type_stats_query,
.reset = my_obj_type_stats_reset,
.disable = NULL, /* Stats gathering is always on */
.enable = NULL, /* Stats gathering is always on */
};
void my_obj_type_init(void)
{
z_obj_type_init(&my_obj_type, K_OBJ_TYPE_MY_NEW_TYPE,
offsetof(struct my_new_obj, obj_core);
k_obj_type_stats_init(&my_obj_type, &my_obj_type_stats_desc);
}
Initializing a New Object Core
Kernel objects that have already been integrated into the object core framework automatically have their object cores initialized when the object is initialized. However, developers that wish to add their own objects into the framework need to both initialize the object core and link it. The following code builds on the example above and initializes the object core.
void my_new_obj_init(struct my_new_obj *new_obj)
{
...
k_obj_core_init(K_OBJ_CORE(new_obj), &my_obj_type);
k_obj_core_link(K_OBJ_CORE(new_obj));
k_obj_core_stats_register(K_OBJ_CORE(new_obj), &new_obj->raw_stats,
sizeof(struct my_obj_type_raw_info));
}
Walking a List of Object Cores
Two routines exist for walking the list of object cores linked to an object
type. These are k_obj_type_walk_locked()
and
k_obj_type_walk_unlocked()
. The following code builds upon the example
above and prints the addresses of all the objects of that new object type.
int walk_op(struct k_obj_core *obj_core, void *data)
{
uint8_t *ptr;
ptr = obj_core;
ptr -= obj_core->type->obj_core_offset;
printk("%p\n", ptr);
return 0;
}
void print_object_addresses(void)
{
struct k_obj_type *obj_type;
/* Find the object type */
obj_type = k_obj_type_find(K_OBJ_TYPE_MY_NEW_TYPE);
/* Walk the list of objects */
k_obj_type_walk_unlocked(obj_type, walk_op, NULL);
}
Object Core Statistics Querying
The following code builds on the examples above and shows how an object integrated into the object core statistics framework can both retrieve queried data and reset the stats associated with the object.
struct my_new_obj my_obj;
...
void my_func(void)
{
struct my_obj_type_query_stats my_stats;
int status;
my_obj_type_init(&my_obj);
...
status = k_obj_core_stats_query(K_OBJ_CORE(&my_obj),
&my_stats, sizeof(my_stats));
if (status != 0) {
/* Failed to get stats */
...
} else {
k_obj_core_stats_reset(K_OBJ_CORE(&my_obj));
}
...
}
Configuration Options
Related configuration options:
API Reference
- group obj_core_apis
Defines
-
K_OBJ_CORE(kobj)
Convert kernel object pointer into its object core pointer.
-
K_OBJ_TYPE_ID_GEN(s)
Generate new object type IDs based on a 4 letter string.
-
K_OBJ_TYPE_CONDVAR_ID
Condition variable object type.
-
K_OBJ_TYPE_CPU_ID
CPU object type.
-
K_OBJ_TYPE_EVENT_ID
Event object type.
-
K_OBJ_TYPE_FIFO_ID
FIFO object type.
-
K_OBJ_TYPE_KERNEL_ID
Kernel object type.
-
K_OBJ_TYPE_LIFO_ID
LIFO object type.
-
K_OBJ_TYPE_MEM_BLOCK_ID
Memory block object type.
-
K_OBJ_TYPE_MBOX_ID
Mailbox object type.
-
K_OBJ_TYPE_MEM_SLAB_ID
Memory slab object type.
-
K_OBJ_TYPE_MSGQ_ID
Message queue object type.
-
K_OBJ_TYPE_MUTEX_ID
Mutex object type.
-
K_OBJ_TYPE_PIPE_ID
Pipe object type.
-
K_OBJ_TYPE_SEM_ID
Semaphore object type.
-
K_OBJ_TYPE_STACK_ID
Stack object type.
-
K_OBJ_TYPE_THREAD_ID
Thread object type.
-
K_OBJ_TYPE_TIMER_ID
Timer object type.
Functions
-
struct k_obj_type *k_obj_type_find(uint32_t type_id)
Find a specific object type by ID.
Given an object type ID, this function searches for the object type that is associated with the specified type ID type_id.
- Parameters:
type_id – Type ID associated with object type
- Return values:
NULL – if object type not found
Pointer – to object type if found
-
int k_obj_type_walk_locked(struct k_obj_type *type, int (*func)(struct k_obj_core*, void*), void *data)
Walk the object type’s list of object cores.
This function takes a global spinlock and walks the object type’s list of object cores and invokes the callback function on each element while holding that lock. Although this will ensure that the list is not modified, one can expect a significant penalty in terms of performance and latency.
The callback function shall either return non-zero to stop further walking, or it shall return 0 to continue walking.
- Parameters:
type – Pointer to the object type
func – Callback to invoke on each object core of the object type
data – Custom data passed to the callback
- Return values:
non-zero – if walk is terminated by the callback; otherwise 0
-
int k_obj_type_walk_unlocked(struct k_obj_type *type, int (*func)(struct k_obj_core*, void*), void *data)
Walk the object type’s list of object cores.
This function is similar to k_obj_type_walk_locked() except that it walks the list without obtaining the global spinlock. No synchronization is provided here. Mutation of the list of objects while this function is in progress must be prevented at the application layer, otherwise undefined/unreliable behavior, corruption and/or crashes may result.
The callback function shall either return non-zero to stop further walking, or it shall return 0 to continue walking.
- Parameters:
type – Pointer to the object type
func – Callback to invoke on each object core of the object type
data – Custom data passed to the callback
- Return values:
non-zero – if walk is terminated by the callback; otherwise 0
-
void k_obj_core_init(struct k_obj_core *obj_core, struct k_obj_type *type)
Initialize the core of the kernel object.
Initializing the kernel object core associates it with the specified kernel object type.
- Parameters:
obj_core – Pointer to the kernel object to initialize
type – Pointer to the kernel object type
-
void k_obj_core_link(struct k_obj_core *obj_core)
Link the kernel object to the kernel object type list.
A kernel object can be optionally linked into the kernel object type’s list of objects. A kernel object must have been initialized before it can be linked. Linked kernel objects can be traversed and have information extracted from them by system tools.
- Parameters:
obj_core – Pointer to the kernel object
-
void k_obj_core_init_and_link(struct k_obj_core *obj_core, struct k_obj_type *type)
Automatically link the kernel object after initializing it.
A useful wrapper to both initialize the core of the kernel object and automatically link it into the kernel object type’s list of objects.
- Parameters:
obj_core – Pointer to the kernel object to initialize
type – Pointer to the kernel object type
-
void k_obj_core_unlink(struct k_obj_core *obj_core)
Unlink the kernel object from the kernel object type list.
Kernel objects can be unlinked from their respective kernel object type lists. If on a list, it must be done at the end of the kernel object’s life cycle.
- Parameters:
obj_core – Pointer to the kernel object
-
struct k_obj_core_stats_desc
- #include <obj_core.h>
Object core statistics descriptor.
Public Members
-
size_t raw_size
Internal representation stats buffer size.
-
size_t query_size
Stats buffer size used for reporting.
-
int (*raw)(struct k_obj_core *obj_core, void *stats)
Function pointer to retrieve internal representation of stats.
-
int (*query)(struct k_obj_core *obj_core, void *stats)
Function pointer to retrieve reported statistics.
-
int (*reset)(struct k_obj_core *obj_core)
Function pointer to reset object’s statistics.
-
int (*disable)(struct k_obj_core *obj_core)
Function pointer to disable object’s statistics gathering.
-
int (*enable)(struct k_obj_core *obj_core)
Function pointer to enable object’s statistics gathering.
-
size_t raw_size
-
struct k_obj_type
- #include <obj_core.h>
Object type structure.
Public Members
-
sys_snode_t node
Node within list of object types.
-
sys_slist_t list
List of objects of this object type.
-
uint32_t id
Unique type ID.
-
size_t obj_core_offset
Offset to obj_core field.
-
sys_snode_t node
-
struct k_obj_core
- #include <obj_core.h>
Object core structure.
Public Members
-
sys_snode_t node
Object node within object type’s list.
-
struct k_obj_type *type
Object type to which object belongs.
-
sys_snode_t node
-
K_OBJ_CORE(kobj)
- group obj_core_stats_apis
Functions
-
int k_obj_core_stats_register(struct k_obj_core *obj_core, void *stats, size_t stats_len)
Register kernel object for gathering statistics.
Before a kernel object can gather statistics, it must be registered to do so. Registering will also automatically enable the kernel object to gather its statistics.
- Parameters:
obj_core – Pointer to kernel object core
stats – Pointer to raw kernel statistics
stats_len – Size of raw kernel statistics buffer
- Return values:
0 – on success
-errno – on failure
-
int k_obj_core_stats_deregister(struct k_obj_core *obj_core)
Deregister kernel object from gathering statistics.
Deregistering a kernel object core from gathering statistics prevents it from gathering any more statistics. It is expected to be invoked at the end of a kernel object’s life cycle.
- Parameters:
obj_core – Pointer to kernel object core
- Return values:
0 – on success
-errno – on failure
-
int k_obj_core_stats_raw(struct k_obj_core *obj_core, void *stats, size_t stats_len)
Retrieve the raw statistics associated with the kernel object.
This function copies the raw statistics associated with the kernel object core specified by obj_core into the buffer stats. Note that the size of the buffer (stats_len) must match the size specified by the kernel object type’s statistics descriptor.
- Parameters:
obj_core – Pointer to kernel object core
stats – Pointer to memory buffer into which to copy raw stats
stats_len – Length of the memory buffer
- Return values:
0 – on success
-errno – on failure
-
int k_obj_core_stats_query(struct k_obj_core *obj_core, void *stats, size_t stats_len)
Retrieve the statistics associated with the kernel object.
This function copies the statistics associated with the kernel object core specified by obj_core into the buffer stats. Unlike the raw statistics this may report calculated values such as averages. Note that the size of the buffer (stats_len) must match the size specified by the kernel object type’s statistics descriptor.
- Parameters:
obj_core – Pointer to kernel object core
stats – Pointer to memory buffer into which to copy the queried stats
stats_len – Length of the memory buffer
- Return values:
0 – on success
-errno – on failure
-
int k_obj_core_stats_reset(struct k_obj_core *obj_core)
Reset the stats associated with the kernel object.
This function resets the statistics associated with the kernel object core specified by obj_core.
- Parameters:
obj_core – Pointer to kernel object core
- Return values:
0 – on success
-errno – on failure
-
int k_obj_core_stats_disable(struct k_obj_core *obj_core)
Stop gathering the stats associated with the kernel object.
This function temporarily stops the gathering of statistics associated with the kernel object core specified by obj_core. The gathering of statistics can be resumed by invoking :c:func :
k_obj_core_stats_enable
.- Parameters:
obj_core – Pointer to kernel object core
- Return values:
0 – on success
-errno – on failure
-
int k_obj_core_stats_enable(struct k_obj_core *obj_core)
Reset the stats associated with the kernel object.
This function resumes the gathering of statistics associated with the kernel object core specified by obj_core.
- Parameters:
obj_core – Pointer to kernel object core
- Return values:
0 – on success
-errno – on failure
-
int k_obj_core_stats_register(struct k_obj_core *obj_core, void *stats, size_t stats_len)