The dark magic used used in thread_measure_stack_free() is frowned upon
by valgrind. E.g. valgrind may deduce (by monitoring the stack pointer)
that a specific value was at some point allocated on the stack, but has
gone out of scope. When that value is now read again to estimate stack
usage, it does look a lot like someone passed a pointer to a stack
allocated value, and that pointer is referenced after that value has
gone out of scope.
This is "fixed" by temporarily disabling valgrind error reporting while
iterating over the stack.
`thread_measure_stack_free()` previously assumed that reading past the
stack is safe. When the stack was indeed part of a thread, the
`thread_t` structure is put after the stack, increasing the odds of
this assumption to hold. However, `thread_measure_stack_free()` could
also be used on the ISR stack, which may be allocated at the end of
SRAM.
A second parameter had to be added to indicate the stack size, so that
reading past the stack can now be prevented.
This also makes valgrind happy on `native`/`native64`.
Make sure both the stack and TLS blocks are correctly aligned by
adjusting the TLS base address to the most strict alignment of the TLS
block and the stack.
Signed-off-by: Keith Packard <keithp@keithp.com>
- activate THREAD_CREATE_STACKTEST also if test_utils_print_stack_usage
is used
- make thread_measure_stack_free() available unconditionally
- if DEVELHELP is active, call test_utils_print_stack_usage() on any
thread exit
- if DEVELHELP is active, call test_utils_print_stack_usage() after main
for the idle thread, if that is used
Verified that each warning generated by -Wcast-align is indeed a false positive
and used an (intermediate) cast to `uintptr_t` to silence the warnings.
Separate thread names from DEVELHELP so thread names can be
enabled in non-development/debug builds when required/desired.
THREAD_NAMES will be enabled by default then DEVELHELP is set to 1.
Allocate and initialize a thread-local block for each thread at the
top of the stack.
Set the tls base when switching to a new thread.
Add tdata/tbss linker instructions to cortex_m and risc-v scripts.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
v2:
Squash fixes
v3:
Replace tabs with spaces
v4:
Add tbss to fe310 linker script
Replace accesses to `sched_active_thread`, `sched_active_pid`, and
`sched_threads` with `thread_get_active()`, `thread_get_active_pid()`, and
`thread_get_unchecked()` where sensible.
- Introduced enum type `thread_state_t` to replace preprocessor macros
- Moved thread states to `sched.h` for two reasons:
a) Because of the interdependencies of `sched.h` and `thread.h` keeping it in
`thread.h` would result in ugly code.
b) Theses thread states are defined from the schedulers point of view, so it
actually makes senses to have it defined there