Skip to content

Commit d70345c

Browse files
committed
zbus: Improve consistency with runtime observers
A previous PR merged (to remove runtime observers' dependency with heap) added inconsistencies and compatibility breaks to the zbus. This commit improves that by removing the inconsistencies and still attending to the features requested by the community. Signed-off-by: Rodrigo Peixoto <[email protected]>
1 parent e41909a commit d70345c

File tree

3 files changed

+92
-6
lines changed

3 files changed

+92
-6
lines changed

include/zephyr/zbus/zbus.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -883,10 +883,11 @@ struct zbus_observer_node {
883883
* @retval 0 Observer added to the channel.
884884
* @retval -EALREADY The observer is already present in the channel's runtime observers list.
885885
* @retval -EAGAIN Waiting period timed out.
886+
* @retval -ENOMEM No memory available for a new runtime observer node.
886887
* @retval -EINVAL Some parameter is invalid.
887888
*/
888889
int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
889-
struct zbus_observer_node *node, k_timeout_t timeout);
890+
k_timeout_t timeout);
890891

891892
/**
892893
* @brief Remove an observer from a channel.

subsys/zbus/Kconfig

+28-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ menuconfig ZBUS
99

1010
if ZBUS
1111

12+
config ZBUS_PREFER_DYNAMIC_ALLOCATION
13+
bool "Set zbus to work on static allocation only"
14+
default y if HEAP_MEM_POOL_SIZE > 0
15+
1216
config ZBUS_CHANNELS_SYS_INIT_PRIORITY
1317
default 5
1418
int "The priority used during the SYS_INIT procedure."
@@ -33,7 +37,8 @@ if ZBUS_MSG_SUBSCRIBER
3337

3438
choice ZBUS_MSG_SUBSCRIBER_BUF_ALLOC
3539
prompt "ZBus msg_subscribers buffer allocation"
36-
default ZBUS_MSG_SUBSCRIBER_BUF_ALLOC_DYNAMIC
40+
default ZBUS_MSG_SUBSCRIBER_BUF_ALLOC_DYNAMIC if ZBUS_PREFER_DYNAMIC_ALLOCATION
41+
default ZBUS_MSG_SUBSCRIBER_BUF_ALLOC_STATIC
3742

3843
config ZBUS_MSG_SUBSCRIBER_BUF_ALLOC_DYNAMIC
3944
bool "Use heap to allocate msg_subscriber buffers data"
@@ -63,6 +68,28 @@ endif # ZBUS_MSG_SUBSCRIBER
6368
config ZBUS_RUNTIME_OBSERVERS
6469
bool "Runtime observers support."
6570

71+
if ZBUS_RUNTIME_OBSERVERS
72+
73+
choice ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC
74+
prompt "ZBus runtime observers node allocation"
75+
default ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_DYNAMIC if ZBUS_PREFER_DYNAMIC_ALLOCATION
76+
default ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_STATIC
77+
78+
config ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_DYNAMIC
79+
bool "Use heap to allocate runtime observers node"
80+
81+
config ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_STATIC
82+
bool "Use a pool of runtime observers nodes"
83+
84+
endchoice
85+
86+
config ZBUS_RUNTIME_OBSERVERS_NODE_POOL_SIZE
87+
int "Runtime observer pool size"
88+
depends on ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_STATIC
89+
default 8
90+
91+
endif # ZBUS_RUNTIME_OBSERVERS
92+
6693
config ZBUS_PRIORITY_BOOST
6794
bool "ZBus priority boost algorithm"
6895
default y

subsys/zbus/zbus_runtime_observers.c

+62-4
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,63 @@
88

99
LOG_MODULE_DECLARE(zbus, CONFIG_ZBUS_LOG_LEVEL);
1010

11+
#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_DYNAMIC)
12+
13+
static inline int _zbus_runtime_observer_node_alloc(struct zbus_observer_node **node,
14+
k_timeout_t timeout)
15+
{
16+
ARG_UNUSED(timeout);
17+
18+
*node = k_malloc(sizeof(struct zbus_observer_node));
19+
20+
_ZBUS_ASSERT(*node != NULL, "could not allocate observer node the heap is full!");
21+
22+
if (*node == NULL) {
23+
return -ENOMEM;
24+
}
25+
26+
return 0;
27+
}
28+
29+
static inline void _zbus_runtime_observer_node_free(struct zbus_observer_node *node)
30+
{
31+
k_free(node);
32+
}
33+
#else
34+
35+
K_MEM_SLAB_DEFINE_STATIC(_zbus_runtime_observers_slab, sizeof(struct zbus_observer_node),
36+
CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_POOL_SIZE, 8);
37+
38+
static inline int _zbus_runtime_observer_node_alloc(struct zbus_observer_node **node,
39+
k_timeout_t timeout)
40+
{
41+
int err = k_mem_slab_alloc(&_zbus_runtime_observers_slab, (void **)node, timeout);
42+
43+
_ZBUS_ASSERT(*node != NULL, "not enough runtime observer nodes in the pool. Increase the "
44+
"ZBUS_RUNTIME_OBSERVERS_NODE_POOL_SIZE");
45+
46+
return err;
47+
}
48+
49+
static inline void _zbus_runtime_observer_node_free(struct zbus_observer_node *node)
50+
{
51+
k_mem_slab_free(&_zbus_runtime_observers_slab, (void *)node);
52+
}
53+
#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_DYNAMIC */
54+
1155
int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
12-
struct zbus_observer_node *node, k_timeout_t timeout)
56+
k_timeout_t timeout)
1357
{
1458
int err;
59+
1560
struct zbus_observer_node *obs_nd, *tmp;
1661
struct zbus_channel_observation *observation;
1762

1863
_ZBUS_ASSERT(!k_is_in_isr(), "ISR blocked");
1964
_ZBUS_ASSERT(chan != NULL, "chan is required");
2065
_ZBUS_ASSERT(obs != NULL, "obs is required");
21-
_ZBUS_ASSERT(node != NULL, "node is required");
66+
67+
k_timepoint_t end_time = sys_timepoint_calc(timeout);
2268

2369
err = k_sem_take(&chan->data->sem, timeout);
2470
if (err) {
@@ -47,9 +93,19 @@ int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observe
4793
}
4894
}
4995

50-
node->obs = obs;
96+
struct zbus_observer_node *new_obs_nd = NULL;
5197

52-
sys_slist_append(&chan->data->observers, &node->node);
98+
err = _zbus_runtime_observer_node_alloc(&new_obs_nd, sys_timepoint_timeout(end_time));
99+
100+
if (err) {
101+
k_sem_give(&chan->data->sem);
102+
103+
return err;
104+
}
105+
106+
new_obs_nd->obs = obs;
107+
108+
sys_slist_append(&chan->data->observers, &new_obs_nd->node);
53109

54110
k_sem_give(&chan->data->sem);
55111

@@ -76,6 +132,8 @@ int zbus_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer
76132
if (obs_nd->obs == obs) {
77133
sys_slist_remove(&chan->data->observers, &prev_obs_nd->node, &obs_nd->node);
78134

135+
_zbus_runtime_observer_node_free(obs_nd);
136+
79137
k_sem_give(&chan->data->sem);
80138

81139
return 0;

0 commit comments

Comments
 (0)