Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ztimer_ondemand has non-composing semantics #20824

Open
chrysn opened this issue Aug 20, 2024 · 1 comment
Open

ztimer_ondemand has non-composing semantics #20824

chrysn opened this issue Aug 20, 2024 · 1 comment
Assignees

Comments

@chrysn
Copy link
Member

chrysn commented Aug 20, 2024

Description

Usually, our modules are local and additive: If one component depends on a module, it can be pulled in and enables some feature. There may be modules that conflict with each other, but if an author needs something, no matter whether they are authoring an application or a module, they can pull it in. If multiple parties pull in a module, all the better -- they just saved code. Unless there is a module conflict, pulling in a module does no more harm than impacting some performance characteristic (code size, startup time, maybe even size of some structs).

ztimer_ondemand is different: When it is enabled, ztimers may be switched off, and all of a sudden, all components in the system need to be strict about ztimer. Therefore, this module can only be set by the application, and it is up to the application author to vet all active modules for ztimer abuse. As a consequence, that doesn't get enabled.

Steps to reproduce the issue

  • Write a module that uses ztimer in a power friendly way
  • Consider enabling ztimer_ondemand in that module
  • Think more about the application
  • Wonder how we got there

Transition plan

I think have two options to fix this:

  1. The careful one

    • Identify whether we have offenders in our code base
    • Create a module ztimer_always_acquired (which has the proper composing semantics) that does nothing but conflict with ztimer_ondemand.
    • Make all offending code depend on ztimer_always_acquired
    • At the end of dependency resolution, enable ztimer_ondemand unless ztimer_always_acquired got pulled in
    • Deprecate manual activation of ztimer_ondemand
    • Switch the users of MODULE_ZTIMER_ONDEMAND to use !IS_ENABLED(ZTIMER_ALWAYS_ACQUIRED) instead
    • Slowly fix all our modules that conflict with ondemand
  2. The cold water approach

    • Fix the modules that conflict with ondemand
    • Add a ztimer_always_acquired module for out-of-tree users (and maybe even insta-deprecate it; it's unlikely they need all timers always on)
    • Switch the users of MODULE_ZTIMER_ONDEMAND to use !IS_ENABLED(ZTIMER_ALWAYS_ACQUIRED) instead

If we don't, RIOT will rarely be power efficient by default.

@chrysn
Copy link
Member Author

chrysn commented Aug 28, 2024

From Matrix discussion, feedback is mainly on how to do it precisely than whether to do it:

Some support for following the careful approach. We could have ztimer_{msec,usec,sec}_always_acquired to not make modules that use ztimer_now(msec) too often do much harm. A criterion for easy first categorization of modules could be "does it use ztimer_now (or ztimer_periodic_wakeup) but neither acquisition nor a continuous ztimer_periodic".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants