Skip to content

Commit

Permalink
doc: Add object core documentation
Browse files Browse the repository at this point in the history
Adds documentation for both object cores and object core statistics.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
  • Loading branch information
peter-mitsis committed Jun 12, 2023
1 parent 6e945a8 commit 7f5ad9e
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/kernel/index.rst
Expand Up @@ -12,6 +12,7 @@ Kernel
memory_management/index.rst
data_structures/index.rst
timing_functions/index.rst
object_cores/index.rst
timeutil.rst
util/index.rst
iterable_sections/index.rst
Expand Down
234 changes: 234 additions & 0 deletions doc/kernel/object_cores/index.rst
@@ -0,0 +1,234 @@
.. _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 has embedded within it 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:
* Condition Variables
* Events
* FIFOs and LIFOs
* Mailboxes
* Memory Slabs
* Message Queues
* Mutexes
* Pipes
* Semaphores
* Timers
* System Memory 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).

Object core statistics have been integrated into the following kernel objects:
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_type, 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

0 comments on commit 7f5ad9e

Please sign in to comment.