Skip to content

Conversation

@zycz
Copy link
Contributor

@zycz zycz commented Sep 16, 2021

Moves event manager with sample from sdk-nrf to zephyr.

Event Manager is a piece of software that supports development of consistent, modular, event-based application. In an event-based application, parts of the application functionality are separated into isolated modules that communicate with each other using events. Events are submitted by modules and other modules can subscribe and react to them.

This PR aims to:
-Initiate the discussion.
-Push the event manager as-is but once comments are taken we will move forward. This will be done in another task.
-Check if all applications already using event manager work fine with event manager placed in zephyr
-Introduce Event manager code into Zephyr

/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace with SPDX-License-Identifier: Apache-2.0

/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace with SPDX-License-Identifier: Apache-2.0

#
# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace with SPDX-License-Identifier: Apache-2.0

#
# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace with SPDX-License-Identifier: Apache-2.0

/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace with SPDX-License-Identifier: Apache-2.0

/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace with SPDX-License-Identifier: Apache-2.0

/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace with SPDX-License-Identifier: Apache-2.0

@zycz zycz marked this pull request as ready for review September 17, 2021 10:47
@zycz zycz requested a review from carlescufi September 17, 2021 10:48
@nordic-krch
Copy link
Contributor

Couple of comments:

  • include/profiler.h didn't catch if it is event_manager specific or something more generic.
  • there are references to NCS in the documentation
  • maybe sample should be moved to samples/application_development?

As for event manager design, there are few things that could be added later on:

  • option to use dedicated thread instead of system work queue.
  • option to not use heap. I think that mpsc_pbuf (MPSC packet buffer) would suit well for that purpose.

@zycz
Copy link
Contributor Author

zycz commented Sep 27, 2021

  • include/profiler.h didn't catch if it is event_manager specific or something more generic.

Profiler is a tool for monitoring events both from event manager and custom ones. https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/libraries/others/profiler.html#profiler
We add profiler.h in this PR to ensure event manager will still be able to work with the profiler.

  • there are references to NCS in the documentation
  • maybe sample should be moved to samples/application_development?

Ok, it is now fixed

Copy link
Contributor

@nordic-krch nordic-krch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few more comments, what about test? Would be good to get that in as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sample/application_development/event_manager

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure why are we adding this for this board specifically? (and why the board is listing all the samples it supports in the first place)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's required because of event_manager_priv.h. It woould be better then to create include/event_manager and move there all headers (including profiler.h)and remove this line. After that profiler.h name can stay because it will be name-spaced with event manager.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot find this option in Kconfig.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see other guards in zephyr, they contain path to the include file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all those must be prefixed with event_manager_

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is redundant and only spoils API. Profiling functions are cut during linking process because they are called conditionally. The only change i had to make to compile it was to add
.profile_fn = IS_ENABLED(CONFIG_PROFILER) ? profile_func : NULL, in _EVENT_INFO_DEFINE.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like CONFIG_PROFILER does not exist.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be assigned only if profiler is enabled. Now event infos are created even when not used. That should also allow to clean up double defines for some macros, eg. MEM_ADDRESS_LABEL

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't like that event structure gets suffix and user must somehow know that after calling EVENT_INFO_DEFINE(control_event,..) it must use control_event_info. Imo, event info name should be explicit so that user does something like:

EVENT_INFO_DEFINE(control_event_info,
		  ENCODE(),
		  ENCODE(),
		  profile_control_event);

EVENT_TYPE_DEFINE(control_event,
		  true,
		  NULL,
		  &control_event_info);

@zycz zycz force-pushed the event_manager branch 3 times, most recently from babd721 to be66328 Compare September 28, 2021 15:24
@hongshui3000
Copy link
Contributor

Very useful, hope to be merged. :)

Copy link
Contributor

@JordanYates JordanYates left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thoughts on the general themes.

The inability to register new event subscribers at runtime is not great. #2746 has seen some renewed interest recently, and having dynamic modules unable to hook into events would be a big limitation.

There is no inbuilt integration with the existing Zephyr synchronization paradigm (poll). If I have a thread that just wants to run some operations on a new GPS sample that comes in, I not only need to raise the appropriate signals in the callback, but also manually copy out the event to some temporary storage, as the buffer doesn't exist after the subscribers have been notified. This is a larger downside if your event is a new buffer of 128 16bit 3-axis accelerometer samples (768 bytes).

Configuring CONFIG_HEAP_MEM_POOL_SIZE (via guess and check) for each application will never be fun. For a robust system, it will need to be at least as large as the sum of all the individual event sizes. This information is known at the locations where events are generated, but I can't see a way to make this any easier.

Less important, and not necessarily in scope for what the subsys is trying to achieve, but it is not possible to query the latest value of an event. For example, code may not necessarily care how often the battery voltage changes, or want to be notified each time a measurement is obtained, but simply query what the current state is.

@zycz
Copy link
Contributor Author

zycz commented Oct 18, 2021

Hi,

Thanks for your thoughts

The inability to register new event subscribers at runtime is not great.

I see your point, but as you already mentioned option to dynamically add modules is generally unsupported yet in Zephyr. In my opinion first this option should be included in Zephyr and then it should be implemented also in Event Manager.

There is no inbuilt integration with the existing Zephyr synchronization paradigm (poll).
it is not possible to query the latest value of an event.

The changes you are suggesting are as you said "not necessarily in scope for what the subsys is trying to achieve" :) Its aim is to enable easy and safe communication between modules. If you have a module with an external sensor and you sample it every 2s you would probably store latest result in some variable. If you needed to have an update of measurement in this moment you would send request to make additional measurement. In case of EM it is similar. After receiving event you would need to store its value somewhere and in case you want additional measurement you just need to send event which will trigger measurement.

@JordanYates
Copy link
Contributor

The inability to register new event subscribers at runtime is not great.

I see your point, but as you already mentioned option to dynamically add modules is generally unsupported yet in Zephyr. In my opinion first this option should be included in Zephyr and then it should be implemented also in Event Manager.

Dynamic modules is one thing, but modules themselves can't explicitly state "I now care about these events" and "I no longer care about these events" via the API. It needs to be done via some global boolean flag in your callback (while making sure everything is thread-safe).

Its aim is to enable easy and safe communication between modules.

Right, but there are BIG caveats in terms of how much this subsys is helping you do that. All that this really gives you over a standard sys_slist_t of callbacks is that you can (only) register for callbacks at compile time, iteration over the callbacks happens on the system workqueue, and some fancyness around mapping an event type to a list of callbacks. There is no deeper level of integration.

If you have a module with an external sensor and you sample it every 2s you would probably store latest result in some variable

Coming back to the accelerometer example, this would require (768 * (N+1)) bytes of CONFIG_HEAP_MEM_POOL_SIZE, where N is the number of modules interested in accelerometer data. This gets large fast, when conceptually you only really need 768 bytes.

I know that I am being pretty critical without offering any solutions. I am contrasting this with an internal subsys we have that performs a similar function without the limitations above. I need to have a conversation with my management around whether we want to at least propose our solution as an alternative.

@nordic-krch
Copy link
Contributor

modules themselves can't explicitly state "I now care about these events"

It can be done locally in the listener by simply checking if given event is enabled for me. I guess it could be moved to internals of event manager, use some bit mask and CLZ to quickly iterate over enabled listeners. It is only the optimization.

Regarding collecting sensor samples to a database which could be shared between the modules, i don't think it is the scope of event manager. Event manager just distributes event to loosely coupled modules. One of those modules can be a database that collects the samples.

Regarding use of heap, there are discussions to add an option to use dedicated buffer space instead of heap (e.g. mpsc_pbuf could be used which serves the event manager case - multiple producers, single consumer).

It would be good to see what alternative could be used.

@zycz zycz force-pushed the event_manager branch 2 times, most recently from 8190228 to 1acde17 Compare February 7, 2022 15:13
zycz added 3 commits February 7, 2022 16:51
Add sample aplication of event manager with documentation to it.
Aplication shows how events are submited and received .

Signed-off-by: Jan Zyczkowski <[email protected]>
Add unit tests for event manager.

Signed-off-by: Jan Zyczkowski <[email protected]>
Add first subscriber to event functionality to event manager.

Jira: NCSDK-9067

Signed-off-by: Jan Zyczkowski <[email protected]>
Copy link
Contributor

@jfischer-no jfischer-no left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have looked at this PR more closely, among other because I wanted something similar for USB subsystem. Event Manager as it is might be robust and fast, but that is about it. It is probably not extensible and not extensible at all to runtime subscription/unsubscription. Macro acrobatics hurt; need of EVENT_TYPE_DEFINE and EVENT_TYPE_DECLARE is awkward, especially since event define header must also be included by listener, and the latter could pull the information even without macro obfuscation; no chance to get rid of LINKER_ORPHAN_SECTION. I have tried to improve and change it, but went over to rewrite something similar from scratch. I will come soon with a proposal.

@pdunaj
Copy link
Contributor

pdunaj commented Feb 15, 2022

@jfischer-no

It is probably not extensible and not extensible at all to runtime subscription/unsubscription.

We can add enable/disable if there is a need for that. Runtime subscription costs I am not sure it is really needed in embedded we work on.

Macro acrobatics hurt; need of EVENT_TYPE_DEFINE and EVENT_TYPE_DECLARE is awkward

Depends what you are looking for. Performance was priority. Defining new event is not really magic. We have never got any question about it and we know people use it.

no chance to get rid of LINKER_ORPHAN_SECTION

Please check again. It was removed without a problem.

@pdunaj pdunaj requested a review from jakub-uC March 4, 2022 10:37
@carlescufi carlescufi dismissed nashif’s stale review March 17, 2022 10:14

Test implemented

@carlescufi carlescufi requested review from anangl and yperess and removed request for ycsin March 17, 2022 10:31
* @param ename Name of the event.
*/
#define EVENT_SUBSCRIBE_FIRST(lname, ename) \
_EVENT_SUBSCRIBE(lname, ename, _EM_MARKER_FIRST_ELEMENT); \
Copy link
Contributor

@jfischer-no jfischer-no Mar 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For EVENT_SUBSCRIBE and all other macros here, there is no reason at all to hide anything in enet_manager_priv.h, actually it makes no sense to have event_manager_priv.h, it just makes review and maintenance harder, exposed to application it is in anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is perfect sense. These items should not be used directly - placing them in priv header makes it explicit.

*
* @param ename Name of the event.
*/
#define EVENT_TYPE_DECLARE(ename) _EVENT_TYPE_DECLARE(ename)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of both EVENT_TYPE_DECLARE and EVENT_TYPE_DEFINE is awkward, specially as the user has to include header which "declare" the event anyway, there is no advantage over a simple union {uint32_t foo; void *bar}; type. The properties of the message can then be obtained from the event source header, without these awkward macros and without unnecessary complexity. Further instead of EVENT_TYPE_DYNDATA_DECLARE memory slabs or net_buf can be used, which again simplifies a lot. Therefore from my side strong NACK to EVENT_TYPE_DECLARE/EVENT_TYPE_DYNDATA_DECLARE.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seemed the simplest to do at the time when event manager was created. Can you elaborate on proposal?

Note that we migrate event manager from NCS - it's not a new code. There is quite a legacy behind. If there is no real advantage I would not change anything. The current API works fine.

* @param ev_info_struct Data structure describing the event type.
* NULL can be used in case no data structure is needed.
*/
#define EVENT_TYPE_DEFINE(ename, init_log_en, log_fn, ev_info_struct) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see any real reason to go that far with logging and with tracing anyway, but presumably it is result of EVENT_TYPE_DECLARE/EVENT_TYPE_DYNDATA_DECLARE complexity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure you don't ;)

*
* @param event Pointer to the event object.
*/
#define EVENT_SUBMIT(event) _event_submit(&event->header)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NACK for this macro, why not just to use event_submit(&event->header); ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simplification of usage - I recommend you to look at the code again

Comment on lines 227 to 272
/** Bool indicating if the event is logged by default. */
bool init_log_enable;

/** Function to log data from this event. */
log_event_data log_event_func;

/** Deprecated function to log data from this event. */
log_event_data_dep log_event_func_dep;

/** Custom data related to tracking. */
const void *trace_data;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is unnecessary, takes more space in the structure than that which is productively necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use it in NCS

Comment on lines 12 to 13
Note that Event Manager uses orphan sections to handle its
data structures.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it use orphan sections or not?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more. This is a leftover after cleanup (@zycz )

depends on LOG
default y
help
This option controls if events are printed to console.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This option controls if events are logged.

Comment on lines 43 to 45
char log_buf[CONFIG_EVENT_MANAGER_EVENT_LOG_BUF_LEN];

int pos = et->log_event_func_dep(eh, log_buf, sizeof(log_buf));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variables should be defined at the top of a block.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I accept you have a different view on this but I don't agree. There is no rule for that and there are many well known advantages of defining variables as close to code as possible (i.e. in place).

Comment on lines 159 to 156
k_spinlock_key_t key = k_spin_lock(&lock);

if (sys_slist_is_empty(&eventq)) {
k_spin_unlock(&lock, key);
return;
}

sys_slist_merge_slist(&events, &eventq);

k_spin_unlock(&lock, key);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same can be implemented in one-line using struct k_fifo and k_fifo_get(). I also see no advantages not to do it this way, very unlikely eventq would contain more than a single event per k_work_submit(&event_processor);.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe. It could be a potential change for later.
Originally it was implemented to be as fast as possible so heavier api was avoided. To change it we would need to see if there would be no impact on performance.

Comment on lines 173 to 165
while (NULL != (node = sys_slist_get(&events))) {
struct event_header *eh = CONTAINER_OF(node,
struct event_header,
node);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is SYS_SLIST_FOR_EACH_CONTAINER macro, using it and moving variable definition to the top of a block, removing of few empty line below, would make code below looks much nicer.

Add changes cleaning event manager.

Signed-off-by: Jan Zyczkowski <[email protected]>
Renamed event_manager files to app_event_manager.

Signed-off-by: Jan Zyczkowski <[email protected]>
Copy link
Contributor

@nordic-krch nordic-krch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add test to hooks APP_EVENT_HOOK.... A lot of those is defined in the API but they are nowhere used.

* @param et Pointer to the event type.
* @retval Boolean value of requested flag.
*/
static inline bool get_app_event_type_flag(const struct event_type *et,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be prefixed with module name -> app_event_get_type_flag

* @param lname Listener name.
* @param cb_fn Pointer to the event handler function.
*/
#define APP_EVENT_LISTENER(lname, cb_fn) _APP_EVENT_LISTENER(lname, cb_fn)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal API shall be prefixed with Z_ so Z_APP_EVENT_LISTENER. Same with others.

*
* @param id ID.
*/
#define ASSERT_APP_EVENT_ID(id) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APP_EVENT_ASSERT_ID

*/
#define APP_EVENT_HOOK_POSTPROCESS_REGISTER(hook_fn) \
_APP_EVENT_HOOK_POSTPROCESS_REGISTER(hook_fn, \
_EM_SUBS_PRIO_ID(_EM_SUBS_PRIO_NORMAL))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_EM should probably be changed to Z_APP_EVENT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to Z_APP_EM it is shorter :)

* @param hook_fn Hook function.
*/
#define APP_EVENT_HOOK_POSTPROCESS_REGISTER_LAST(hook_fn) \
const struct {} __event_hook_postprocess_last_sub_redefined = {}; \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the purpose of this variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a marker indicating that only one hook can be registered as Last.

Add changes cleaning event manager.

Signed-off-by: Jan Zyczkowski <[email protected]>
@zycz
Copy link
Contributor Author

zycz commented Apr 7, 2022

App Event Manager right now won't be up streamed to Zephyr. I close PR.

@zycz zycz closed this Apr 7, 2022
@pdunaj
Copy link
Contributor

pdunaj commented Apr 13, 2022

hi @rodrigobrochado , I have noticed your emoji. Any reason? The code is still available in Nordic Connect SDK :)

@rodrigobrochado
Copy link
Contributor

Hi @pdunaj, yes, I saw it on NCS. I'm just excited about NCS features getting upstreamed to Zephyr. No big deal, but thanks for asking :)

@hongshui3000
Copy link
Contributor

It's a pity that this PR was closed

Copy link
Member

@gmarull gmarull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some more comments. I have to say that except a few rough edges I like what is presented in this PR.

Comment on lines 64 to 65
1. Include :file:`event_manager.h` in your :file:`main.c` file.
#. Call :c:func:`event_manager_init()`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does event manager need to be started manually? could it be done via SYS_INIT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event manager was created to be an application skeleton (not a system one) and I believe it is better for application to have a control when event processing is started.
This said initialization function does almost nothing at the moment - it performs checks but was left in case we would like to extend the configuration in the future (like start a separate event processing thread, prepare an allocator or something similar).

.. code-block:: c

/* Allocate event. */
struct sample_event *event = new_sample_event();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this dynamic allocation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - there are hooks (weak linkage) that allows user to pass own allocator functions. by default it's k_malloc.

Comment on lines 78 to 82
#define _EVENT_SUBSCRIBE(lname, ename, prio) \
const struct event_subscriber _CONCAT(_CONCAT(__event_subscriber_, ename), lname) __used \
__attribute__((__section__(_EVENT_SUBSCRIBERS_SECTION_NAME(ename, prio)))) = { \
.listener = &_CONCAT(__event_listener_, lname), \
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I had a look during the last rework if we can use more of standard macros. There must have been something that prevented it but I don't recall what it was.

* ename type.
*/
#define _EVENT_ALLOCATOR_FN(ename) \
static inline struct ename *_CONCAT(new_, ename)(void) \
Copy link
Member

@gmarull gmarull Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all event manager function calls should be namespaced, e.g. evm_, this just creates new_....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right - this is leftover from times it was used in one app only that was not fixed during API rework, we should probably follow up on that in NCS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zycz , can you create a ticket to follow this up?

* ename type.
*/
#define _EVENT_ALLOCATOR_FN(ename) \
static inline struct ename *_CONCAT(new_, ename)(void) \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is dynamic allocation a mandatory thing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How else you would want to do it?
Events are dynamic so you have to do dynamic allocation on them. I expect having a preset of event objects create at build time would be quite limiting.
As for an actual allocator that is used - by default it is heap (k_malloc heap to be precise) but user can hook any other allocator (slab for example).

Comment on lines 109 to 119
void __weak event_manager_trace_event_execution(const struct event_header *eh,
bool is_start)
{
}

void __weak event_manager_trace_event_submission(const struct event_header *eh,
const void *trace_info)
{
}

void * __weak event_manager_alloc(size_t size)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that in general we should avoid using weaks (it's a non-standard feature). Kconfig options to allow custom re-implementations would be a better choice IMO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zephyr has multiple things based on weaks. I don't see a problem with using a feature that is actually requested by basic components of the OS.
This said you are right and we really could simply compile this allocators in by default and allow user to turn them off in preprocessor if other calls are provided. I would not change it at this point however as it does it's job.

Comment on lines 18 to 20
(et != NULL) && (et != __stop_event_types); et++) {

size_t ev_id = et - __start_event_types;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should likely avoid using such variables directly and provide iterator functions instead, see for example device_required_foreach.

* @{
*/

#include "event_manager/event_manager.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use headers correctly: anything in the include path (non-local) must use <>.

Comment on lines 28 to 30
#ifdef __cplusplus
}
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this need to run on C++ code?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect sample simply copied code from some previously defined event. Is there any harm coming out of it?


static void log_config_event(const struct event_header *eh)
{
struct config_event *event = cast_config_event(eh);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a macro would be more useful/readable (aligning with CONTAINER_OF usage), e.g.

struct config_event *event = EVM_CAST(eh, config);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea - we could follow this up along with new_event api @zycz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.