The previous implementation relied on `thread_flag_set()` to defer the
context switch when called with IRQs disabled until `irq_restore()` is
called. This however can only be the case when `thread_yield_higher`
triggers an IRQ and performs the context switch within the ISR. This
allowed the previous implementation to continue calling
`thread_flag_set()` for the remaining group members.
This however is an implementation detail that is not part of the API
contract. Platforms that do not have a service request IRQ may have to
use other means for context switching that do not get deferred until
an `irq_restore()` is called. In that case, the first call to
`thread_flags_set()` even with IRQs disabled may directly trigger a
context switch to the unblocked thread, even if other group members
would also be unblocked and have a higher priority.
This changes the implementation to manually set the flags and update
the thread status without yielding and keep track whether any thread
has been awoken. Only once the states of all threads have been updated,
the adapted implementation will now call `thread_yield()` (unless no
thread was awoken).
All uses of thread_flags_wake() also had to set the flags anyway, so
we can just combine those operations into a new
thread_flags_set_internal() and update the users to use that instead.
GCC requires symbols to first be declared before they can be renamed.
So we move the `#pragma redefine_extname` just to the bottom of the
compilation unit.
Co-authored-by: crasbe <crasbe@gmail.com>
Co-authored-by: Mikolai Gütschow <mikolai.guetschow@tu-dresden.de>
Starting from clang 21 (see [release notes][1]) clang also supports
`-Wunterminated-string-initialization` and the corresponding
`__attribute__((nonstring))`. Hence, also provide `NONSTRING` as the
corresponding `__attribute__((nonstring))` for clang starting with
clang version 21.
[1]: https://releases.llvm.org/21.1.0/tools/clang/docs/ReleaseNotes.html
That way users can rely on elimation of dead code from the optimizer
instead of having to use preprocessor conditionals when feature-gating
assert implementations behind `!NDEBUG`.
Co-authored-by: benpicco <benpicco@googlemail.com>
Co-authored-by: crasbe <crasbe@gmail.com>
Co-authored-by: mguetschow <mikolai.guetschow@tu-dresden.de>
This adds the `NONSTRING` attribute that is defined as either
`__attribute__((nonstring))` or as empty, depending on whether the
toolchain understands the `nonstring` attribute.
This allows declaring char arrays as not being a zero-terminated
c-string without cluttering the code with preprocessor conditinational
to ensure backward compatibility with compilers that do not support
`-Wunterminated-string-initialization` yet.
Modules can now add the following snipped to their `Makefile`:
MODULE_SUPPORTS_STATIC_ANALYSIS := 1
When the application is then build with `make STATIC_ANALYSIS=1`, all
modules that opted in to static analysis get build with static analysis.
This fixes compilation with `-fanalyzer`. We use `assume()` to signal
GCC that `thread` must not be null in `NDEBUG` mode, and `assert()` it
in with enabled assertions.
This also drops the `volatile` qualifier from the function argument and
changes the return value to `bool`.
Rather than using an `assert()` on `thread_get()`, check for the thread
to exist and return a capacity of `0` if it does not.
This fixes compilation with `-fanalyzer` with `NDEBUG` defined, is more
consistent with other core APIs, and makes the API usable for threads
with a dynamic life cycle.
Co-authored-by: crasbe <crasbe@gmail.com>
This now ensures race-free access to the CIB tracking the number
of messages queued in the ringbuffer for a given thread.
In addition, `msg_avail_thread()` now checks if the provided pid refers
to a thread that is currently existing.
Co-authored-by: Mikolai Gütschow <mikolai.guetschow@tu-dresden.de>
Users of CIB may easily be mislead to believing that it is generally
thread safe, or at least thread safe as long as there is a single
consumer and producer. Neither is the case, which now is clearly
communicated in the API doc.
Co-authored-by: mguetschow <mikolai.guetschow@tu-dresden.de>
In thread_state_to_string() it is not checked whether state is within
the valid range, so that in the event of an error an invalid memory
address is returned, which in turn leads to further invalid memory
accesses when the string is output. thread_state_to_string() is used
in particular by ps(). In the case of a corrupt thread context, which
often occurred in my case due to the stack size being too small,
thread_state_to_string() is called with an invalid status.
In thread_wakeup() the status of the function to be woken up is
incorrectly set to TASK_RUNNING. Instead the task should be set
to STATUS_PENDING here, as only sched_run() is allowed to set a
task to TASK_RUNNING.
This changes the API of xfa from
XFA(array_name, prio) type element_name = INITIALIZER;
to
XFA(type, array_name, prio) element_name = INITIALIZER;
this allows forcing natural alignment of the type, fixing failing tests
on `native64`.
Using `sched_switch()` in `mutex_unlock()` can result in crashes when
`mutex_unlock()` is called from IRQ context. This however is a common
pattern in RIOT to wake up a thread from IRQ. The reason for the crash
is that `sched_switch()` assumes `thread_get_active()` to always return
a non-`NULL` value. But when thread-less idle is used, no thread may be
active after the last runnable thread exited. Using
`thread_yield_higher()` instead solves the issue, as
`thread_yield_higher()` is safe to call from IRQ context without an
active thread.
This fixes https://github.com/RIOT-OS/RIOT/issues/20812