With this commit xtimer will always be implemented with ztimer.
The default compat layer will be ztimer_xtimer_compat, so xtimer
calls will be inlined to ZTIMER_USEC, or ZTIMER64_USEC when the
64bit xtimer API is required.
This can be reverted by adding 'xtimer_no_ztimer_default' module
to a build.
This adds a xtimer_no_ztimer_default that is currently always
selected in Makefile, but that can be switched off in Kconfig.
Removing its inclusion will allow switching the default xtimer
backend to ztimer, while allowing for an easy way back.
Replace use of C11 atomics with atomic utils. This fixes
> error: address argument to atomic operation must be a pointer to a
> trivially-copyable type ('_Atomic(int) *' invalid)
error when compiling on AVR with LLVM.
Place a verbatim copy of `_mutex_lock()` as `static` in `xtimer`, so internal
mutex function can be optimized one step at a time without breaking `xtimer`.
Replace direct accesses to sched_active_thread and sched_active_pid with
the helper functions thread_getpid() and thread_get_active(). This serves
two purposes:
1. It makes accidental writes to those variable from outside core less likely.
2. Casting off the volatile qualifier is now well contained to those two
functions
This fixes `xtimer` to use `xtimer_now64()` instead of `xtimer_now()`
for updating the `*now` variable during the iteration in
`_update_short_timers()` function. The same function is used to
initialize `*now` in `_timer_callback()` below.
While using `xtimer_now()` in this iteration step does not hinder the
proper execution of all timers in the short term timers (for those the
`xtimer` module only looks at the `start_time` member, not the
`long_start_time` member) at least for the current long term time window
(I did not test higher cases), it sets the `long_start_time` member to 0
for all timers following in the list of timers after this iteration
step. However, external modules that rely on this to be correct,
e.g. evtimer [1], fail their calculations when trying to compare to
the current value to `xtimer_now64()`.
[1] https://github.com/RIOT-OS/RIOT/blob/11f3d68/sys/evtimer/evtimer.c#L118-L121
Co-Authored-By: Cenk Gündoğan <mail+dev@gundogan.net>
This function tries to remove the thread from a mutex waiting queue.
The value pointed to by unlocked will be set to 1 if the thread was removed from the waiting queue otherwise 0.
Handling timeout smaller than XTIMER_BACKOFF (the timer spins) when the mutex is already locked.
This fixes the test tests/xtimer_mutex_lock_timeout/main.c:mutex_timeout_spin_locked.
This commit adds logic to make xtimer use ztimer_usec as backend
(instead of periph_timer). This allows ztimer_usec and xtimer to
coexist. It also allows xtimer to profit from eventually implemented
power mode blocking in ztimer's periph_timer backend.
Prevent a possible race condition when _mutex_timeout fires just after the
mutex was locked but before the xtimer was removed
The flow
int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t timeout) {
...
mutex_lock(mutex);
/* mutex locked */
/* _mutex_timeout fires and tries to remove thread from mutex queue */
/* DEBUG: simulate callback call between lock and remove */
xtimer_spin(xtimer_ticks_from_usec(timeout*2));
xtimer_remove(&t);
...
}
if xtimer_set spins the callback is executed in the thread context.
comment to explain irq_disable
and when this line could be removed
(when xtimer stops executing the callback funtion from thread context)
1. When the 32 bit target of the xtimer overflowed the timer was not placed in the right list.
2. When the hardware timer overflowed the comparison was wrong for setting next target.
3. Backoff condition