Browse Source
Adds documentation for both object cores and object core statistics. Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>pull/63341/head
2 changed files with 234 additions and 0 deletions
@ -0,0 +1,233 @@
@@ -0,0 +1,233 @@
|
||||
.. _object_cores_api: |
||||
|
||||
Object Cores |
||||
############ |
||||
|
||||
Object cores are a kernel debugging tool that can be used to both identify and |
||||
perform operations on registered objects. |
||||
|
||||
.. contents:: |
||||
:local: |
||||
:depth: 2 |
||||
|
||||
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: |
||||
* :ref:`Condition Variables <condvar>` |
||||
* :ref:`Events <events>` |
||||
* :ref:`FIFOs <fifos_v2>` and :ref:`LIFOs <lifos_v2>` |
||||
* :ref:`Mailboxes <mailboxes_v2>` |
||||
* :ref:`Memory Slabs <memory_slabs_v2>` |
||||
* :ref:`Message Queues <message_queues_v2>` |
||||
* :ref:`Mutexes <mutexes_v2>` |
||||
* :ref:`Pipes <pipes_v2>` |
||||
* :ref:`Semaphores <semaphores_v2>` |
||||
* :ref:`Timers <timers_v2>` |
||||
* :ref:`System Memory Blocks <sys_mem_blocks>` |
||||
|
||||
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 |
||||
:c:struct:`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. |
||||
|
||||
.. code-block:: c |
||||
|
||||
/* 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. |
||||
|
||||
.. code-block:: c |
||||
|
||||
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 :c:func:`k_obj_type_walk_locked` and |
||||
:c:func:`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. |
||||
|
||||
.. code-block:: c |
||||
|
||||
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. |
||||
|
||||
.. code-block:: c |
||||
|
||||
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: |
||||
|
||||
* :kconfig:option:`CONFIG_OBJ_CORE` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_CONDVAR` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_EVENT` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_FIFO` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_LIFO` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_MAILBOX` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_MEM_SLAB` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_MSGQ` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_MUTEX` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_PIPE` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_SEM` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_STACK` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_TIMER` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_SYS_MEM_BLOCKS` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_STATS` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_STATS_MEM_SLAB` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_STATS_THREAD` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_STATS_SYSTEM` |
||||
* :kconfig:option:`CONFIG_OBJ_CORE_STATS_SYS_MEM_BLOCKS` |
||||
|
||||
API Reference |
||||
************* |
||||
|
||||
.. doxygengroup:: obj_core_apis |
||||
.. doxygengroup:: obj_core_stats_apis |
Loading…
Reference in new issue