mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-27 07:21:18 +01:00
Merge pull request #18942 from maribu/cpu/native
cpu/native: fix build with musl
This commit is contained in:
commit
886c6a2709
@ -450,15 +450,20 @@ static inline const char *thread_getname(kernel_pid_t pid)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Measures the stack usage of a stack
|
||||
* @brief Measures the stack usage of a stack
|
||||
* @internal Should not be used externally
|
||||
*
|
||||
* Only works if the thread was created with the flag THREAD_CREATE_STACKTEST.
|
||||
* Only works if the stack is filled with canaries
|
||||
* (`*((uintptr_t *)ptr) == (uintptr_t)ptr` for naturally aligned `ptr` within
|
||||
* the stack).
|
||||
*
|
||||
* @param[in] stack the stack you want to measure. Try `thread_get_stackstart(thread_get_active())`
|
||||
* @param[in] stack the stack you want to measure. Try
|
||||
* `thread_get_stackstart(thread_get_active())`
|
||||
* @param[in] size size of @p stack in bytes
|
||||
*
|
||||
* @return the amount of unused space of the thread's stack
|
||||
* @return the amount of unused space of the thread's stack
|
||||
*/
|
||||
uintptr_t thread_measure_stack_free(const char *stack);
|
||||
uintptr_t measure_stack_free_internal(const char *stack, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Get the number of bytes used on the ISR stack
|
||||
@ -621,6 +626,24 @@ static inline const char *thread_get_name(const thread_t *thread)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Measures the stack usage of a stack
|
||||
*
|
||||
* @pre Only works if the thread was created with the flag
|
||||
* `THREAD_CREATE_STACKTEST`.
|
||||
*
|
||||
* @param[in] thread The thread to measure the stack of
|
||||
*
|
||||
* @return the amount of unused space of the thread's stack
|
||||
*/
|
||||
static inline uintptr_t thread_measure_stack_free(const thread_t *thread)
|
||||
{
|
||||
/* explicitly casting void pointers is bad code style, but needed for C++
|
||||
* compatibility */
|
||||
return measure_stack_free_internal((const char *)thread_get_stackstart(thread),
|
||||
thread_get_stacksize(thread));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -171,15 +171,18 @@ void thread_add_to_list(list_node_t *list, thread_t *thread)
|
||||
list->next = new_node;
|
||||
}
|
||||
|
||||
uintptr_t thread_measure_stack_free(const char *stack)
|
||||
uintptr_t measure_stack_free_internal(const char *stack, size_t size)
|
||||
{
|
||||
/* Alignment of stack has been fixed (if needed) by thread_create(), so
|
||||
* we can silence -Wcast-align here */
|
||||
uintptr_t *stackp = (uintptr_t *)(uintptr_t)stack;
|
||||
uintptr_t end = (uintptr_t)stack + size;
|
||||
|
||||
/* better be safe than sorry: align end of stack just in case */
|
||||
end &= (sizeof(uintptr_t) - 1);
|
||||
|
||||
/* assume that the comparison fails before or after end of stack */
|
||||
/* assume that the stack grows "downwards" */
|
||||
while (*stackp == (uintptr_t)stackp) {
|
||||
while (((uintptr_t)stackp < end) && (*stackp == (uintptr_t)stackp)) {
|
||||
stackp++;
|
||||
}
|
||||
|
||||
|
||||
@ -197,7 +197,7 @@ UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask)
|
||||
thread_t *thread = thread_get((xTask == NULL) ? (uint32_t)thread_getpid()
|
||||
: (uint32_t)xTask);
|
||||
assert(thread != NULL);
|
||||
return thread_measure_stack_free(thread->stack_start);
|
||||
return thread_measure_stack_free(thread);
|
||||
}
|
||||
|
||||
void *pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery,
|
||||
|
||||
@ -92,10 +92,9 @@ void thread_isr_stack_init(void)
|
||||
|
||||
int thread_isr_stack_usage(void)
|
||||
{
|
||||
/* cppcheck-suppress comparePointers
|
||||
* (reason: comes from ESP-SDK, so should be valid) */
|
||||
return &port_IntStackTop - &port_IntStack -
|
||||
thread_measure_stack_free((char*)&port_IntStack);
|
||||
size_t stack_size = (uintptr_t)&port_IntStackTop - (uintptr_t)&port_IntStack;
|
||||
return stack_size -
|
||||
measure_stack_free_internal((char *)&port_IntStack, stack_size);
|
||||
}
|
||||
|
||||
void *thread_isr_stack_pointer(void)
|
||||
|
||||
@ -19,3 +19,10 @@ ifeq ($(OS) $(OS_ARCH),Linux x86_64)
|
||||
endif
|
||||
|
||||
include $(RIOTMAKE)/arch/native.inc.mk
|
||||
|
||||
USE_LIBUCONTEXT := $(shell pkg-config libucontext 2> /dev/null && echo 1 || echo 0)
|
||||
|
||||
ifeq ($(USE_LIBUCONTEXT),1)
|
||||
CFLAGS += $(pkg-config libucontext --cflags) -DUSE_LIBUCONTEXT=1
|
||||
LINKFLAGS += $(shell pkg-config libucontext --libs)
|
||||
endif
|
||||
|
||||
@ -172,7 +172,7 @@ extern volatile int _native_in_isr;
|
||||
extern volatile int _native_in_syscall;
|
||||
|
||||
extern char __isr_stack[];
|
||||
extern char __end_stack[];
|
||||
extern const size_t __isr_stack_size;
|
||||
extern ucontext_t native_isr_context;
|
||||
extern ucontext_t end_context;
|
||||
extern ucontext_t *_native_cur_ctx, *_native_isr_ctx;
|
||||
|
||||
@ -13,10 +13,16 @@
|
||||
* @author Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
|
||||
*/
|
||||
|
||||
/* __USE_GNU for gregs[REG_EIP] access under glibc
|
||||
* _GNU_SOURCE for REG_EIP and strsignal() under musl */
|
||||
#define __USE_GNU
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <err.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_VALGRIND_H
|
||||
#include <valgrind.h>
|
||||
@ -29,16 +35,12 @@
|
||||
#define VALGRIND_DEBUG(...)
|
||||
#endif
|
||||
|
||||
/* __USE_GNU for gregs[REG_EIP] access under Linux */
|
||||
#define __USE_GNU
|
||||
#include <signal.h>
|
||||
#undef __USE_GNU
|
||||
|
||||
#include "irq.h"
|
||||
#include "cpu.h"
|
||||
#include "periph/pm.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
#include "test_utils/expect.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
@ -50,6 +52,7 @@ volatile int _native_in_syscall;
|
||||
static sigset_t _native_sig_set, _native_sig_set_dint;
|
||||
|
||||
char __isr_stack[THREAD_STACKSIZE_DEFAULT];
|
||||
const size_t __isr_stack_size = sizeof(__isr_stack);
|
||||
ucontext_t native_isr_context;
|
||||
ucontext_t *_native_cur_ctx, *_native_isr_ctx;
|
||||
|
||||
@ -58,7 +61,6 @@ volatile int _native_sigpend;
|
||||
int _sig_pipefd[2];
|
||||
|
||||
static _native_callback_t native_irq_handlers[255];
|
||||
char sigalt_stk[SIGSTKSZ];
|
||||
|
||||
void *thread_isr_stack_pointer(void)
|
||||
{
|
||||
@ -523,8 +525,9 @@ void native_interrupt_init(void)
|
||||
_native_isr_ctx = &native_isr_context;
|
||||
|
||||
static stack_t sigstk;
|
||||
sigstk.ss_sp = sigalt_stk;
|
||||
sigstk.ss_size = sizeof(sigalt_stk);
|
||||
sigstk.ss_sp = malloc(SIGSTKSZ);
|
||||
expect(sigstk.ss_sp != NULL);
|
||||
sigstk.ss_size = SIGSTKSZ;
|
||||
sigstk.ss_flags = 0;
|
||||
|
||||
if (sigaltstack(&sigstk, NULL) < 0) {
|
||||
|
||||
@ -21,16 +21,22 @@
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* __USE_GNU for gregs[REG_EIP] access under glibc
|
||||
* _GNU_SOURCE for REG_EIP and strsignal() under musl */
|
||||
#define __USE_GNU
|
||||
#include <signal.h>
|
||||
#undef __USE_GNU
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <ucontext.h>
|
||||
#include <err.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if USE_LIBUCONTEXT
|
||||
#include <libucontext/libucontext.h>
|
||||
#else
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VALGRIND_H
|
||||
#include <valgrind.h>
|
||||
@ -45,11 +51,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "irq.h"
|
||||
#include "sched.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "cpu_conf.h"
|
||||
#include "irq.h"
|
||||
#include "sched.h"
|
||||
#include "test_utils/expect.h"
|
||||
|
||||
#ifdef MODULE_NETDEV_TAP
|
||||
#include "netdev_tap.h"
|
||||
@ -62,7 +68,6 @@ extern netdev_tap_t netdev_tap;
|
||||
#include "debug.h"
|
||||
|
||||
ucontext_t end_context;
|
||||
char __end_stack[SIGSTKSZ];
|
||||
|
||||
/**
|
||||
* make the new context assign `_native_in_isr = 0` before resuming
|
||||
@ -194,7 +199,7 @@ void cpu_switch_context_exit(void)
|
||||
irq_disable();
|
||||
_native_in_isr = 1;
|
||||
native_isr_context.uc_stack.ss_sp = __isr_stack;
|
||||
native_isr_context.uc_stack.ss_size = SIGSTKSZ;
|
||||
native_isr_context.uc_stack.ss_size = __isr_stack_size;
|
||||
native_isr_context.uc_stack.ss_flags = 0;
|
||||
makecontext(&native_isr_context, isr_cpu_switch_context_exit, 0);
|
||||
if (setcontext(&native_isr_context) == -1) {
|
||||
@ -247,7 +252,7 @@ void thread_yield_higher(void)
|
||||
_native_in_isr = 1;
|
||||
irq_disable();
|
||||
native_isr_context.uc_stack.ss_sp = __isr_stack;
|
||||
native_isr_context.uc_stack.ss_size = SIGSTKSZ;
|
||||
native_isr_context.uc_stack.ss_size = __isr_stack_size;
|
||||
native_isr_context.uc_stack.ss_flags = 0;
|
||||
makecontext(&native_isr_context, isr_thread_yield, 0);
|
||||
if (swapcontext(ctx, &native_isr_context) == -1) {
|
||||
@ -263,13 +268,16 @@ void native_cpu_init(void)
|
||||
err(EXIT_FAILURE, "native_cpu_init: getcontext");
|
||||
}
|
||||
|
||||
end_context.uc_stack.ss_sp = __end_stack;
|
||||
end_context.uc_stack.ss_sp = malloc(SIGSTKSZ);
|
||||
expect(end_context.uc_stack.ss_sp != NULL);
|
||||
end_context.uc_stack.ss_size = SIGSTKSZ;
|
||||
end_context.uc_stack.ss_flags = 0;
|
||||
makecontext(&end_context, sched_task_exit, 0);
|
||||
(void) VALGRIND_STACK_REGISTER(__end_stack, __end_stack + sizeof(__end_stack));
|
||||
(void)VALGRIND_STACK_REGISTER(end_context.uc_stack.ss_sp,
|
||||
(char *)end_context.uc_stack.ss_sp + end_context.uc_stack.ss_size);
|
||||
VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n",
|
||||
(void*)__end_stack, (void*)(__end_stack + sizeof(__end_stack)));
|
||||
(void*)end_context.uc_stack.ss_sp,
|
||||
(void*)((char *)end_context.uc_stack.ss_sp + end_context.uc_stack.ss_size));
|
||||
|
||||
DEBUG("RIOT native cpu initialized.\n");
|
||||
}
|
||||
|
||||
@ -22,30 +22,28 @@
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include "byteorder.h"
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <features.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "kernel_init.h"
|
||||
#include "cpu.h"
|
||||
#include "byteorder.h"
|
||||
#include "irq.h"
|
||||
|
||||
#include "board_internal.h"
|
||||
#include "kernel_init.h"
|
||||
#include "native_internal.h"
|
||||
#include "stdio_base.h"
|
||||
#include "tty_uart.h"
|
||||
|
||||
#include "periph/init.h"
|
||||
#include "periph/pm.h"
|
||||
#include "test_utils/expect.h"
|
||||
#include "tty_uart.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
@ -121,6 +119,12 @@ static const char short_opts[] = ":hi:s:deEoc:"
|
||||
#endif
|
||||
"";
|
||||
|
||||
#if __GLIBC__
|
||||
static const bool _is_glibc = true;
|
||||
#else
|
||||
static const bool _is_glibc = false;
|
||||
#endif
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "id", required_argument, NULL, 'i' },
|
||||
@ -468,6 +472,49 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e
|
||||
/* initialize stdio as early as possible */
|
||||
early_init();
|
||||
|
||||
/* Passing argc, argv, and envp to init_fini handlers is a glibc
|
||||
* extension. If we are not running glibc, we parse /proc/self/cmdline
|
||||
* to populate argc and argv by hand */
|
||||
if (!_is_glibc) {
|
||||
const size_t bufsize = 4096;
|
||||
const size_t argc_max = 32;
|
||||
size_t cmdlen = 0;
|
||||
char *cmdline = malloc(bufsize);
|
||||
argv = calloc(sizeof(char *), argc_max);
|
||||
argc = 0;
|
||||
envp = NULL;
|
||||
expect(cmdline != NULL);
|
||||
int cmdfd = real_open("/proc/self/cmdline", O_RDONLY);
|
||||
expect(cmdfd != -1);
|
||||
ssize_t count;
|
||||
do {
|
||||
count = real_read(cmdfd, cmdline + cmdlen, bufsize - cmdlen);
|
||||
if (count < 0) {
|
||||
if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) {
|
||||
continue;
|
||||
}
|
||||
expect(0);
|
||||
}
|
||||
cmdlen += count;
|
||||
} while (count > 0);
|
||||
real_close(cmdfd);
|
||||
cmdline = realloc(cmdline, cmdlen);
|
||||
|
||||
char *argpos = cmdline;
|
||||
while ((size_t)argc < argc_max) {
|
||||
if (argpos == cmdline + cmdlen) {
|
||||
argv[argc] = NULL;
|
||||
break;
|
||||
}
|
||||
size_t len = strlen(argpos);
|
||||
|
||||
argv[argc++] = argpos;
|
||||
argpos += len + 1;
|
||||
}
|
||||
expect((size_t)argc < argc_max);
|
||||
argv = realloc(argv, sizeof(char *) * (argc + 1));
|
||||
}
|
||||
|
||||
_native_argv = argv;
|
||||
_progname = argv[0];
|
||||
_native_pid = real_getpid();
|
||||
|
||||
@ -143,7 +143,7 @@ void _native_syscall_leave(void)
|
||||
* stacks are manually word aligned in thread_static_init() */
|
||||
_native_cur_ctx = (ucontext_t *)(uintptr_t)thread_get_active()->sp;
|
||||
native_isr_context.uc_stack.ss_sp = __isr_stack;
|
||||
native_isr_context.uc_stack.ss_size = SIGSTKSZ;
|
||||
native_isr_context.uc_stack.ss_size = __isr_stack_size;
|
||||
native_isr_context.uc_stack.ss_flags = 0;
|
||||
native_interrupts_enabled = 0;
|
||||
makecontext(&native_isr_context, native_irq_handler, 0);
|
||||
|
||||
2
examples/rust-gcoap/Cargo.lock
generated
2
examples/rust-gcoap/Cargo.lock
generated
@ -785,7 +785,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "riot-wrappers"
|
||||
version = "0.8.3"
|
||||
source = "git+https://github.com/RIOT-OS/rust-riot-wrappers#ea8d7fad95c8cb256ba9bc178f7779d266cc0def"
|
||||
source = "git+https://github.com/RIOT-OS/rust-riot-wrappers#87ba1141e093a97d1999e3c48ab276dd0e9c6529"
|
||||
dependencies = [
|
||||
"bare-metal",
|
||||
"coap-handler 0.1.6",
|
||||
|
||||
2
examples/rust-hello-world/Cargo.lock
generated
2
examples/rust-hello-world/Cargo.lock
generated
@ -574,7 +574,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "riot-wrappers"
|
||||
version = "0.8.3"
|
||||
source = "git+https://github.com/RIOT-OS/rust-riot-wrappers#ea8d7fad95c8cb256ba9bc178f7779d266cc0def"
|
||||
source = "git+https://github.com/RIOT-OS/rust-riot-wrappers#87ba1141e093a97d1999e3c48ab276dd0e9c6529"
|
||||
dependencies = [
|
||||
"bare-metal",
|
||||
"coap-handler 0.1.6",
|
||||
|
||||
@ -98,7 +98,7 @@ void ps(void)
|
||||
#ifdef DEVELHELP
|
||||
int stacksz = thread_get_stacksize(p); /* get stack size */
|
||||
overall_stacksz += stacksz;
|
||||
int stack_free = thread_measure_stack_free(thread_get_stackstart(p));
|
||||
int stack_free = thread_measure_stack_free(p);
|
||||
stacksz -= stack_free;
|
||||
overall_used += stacksz;
|
||||
#endif
|
||||
|
||||
2
sys/rust_riotmodules_standalone/Cargo.lock
generated
2
sys/rust_riotmodules_standalone/Cargo.lock
generated
@ -600,7 +600,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "riot-wrappers"
|
||||
version = "0.8.3"
|
||||
source = "git+https://github.com/RIOT-OS/rust-riot-wrappers#ea8d7fad95c8cb256ba9bc178f7779d266cc0def"
|
||||
source = "git+https://github.com/RIOT-OS/rust-riot-wrappers#87ba1141e093a97d1999e3c48ab276dd0e9c6529"
|
||||
dependencies = [
|
||||
"bare-metal",
|
||||
"coap-handler 0.1.6",
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
void print_stack_usage_metric(const char *name, void *stack, unsigned max_size)
|
||||
{
|
||||
unsigned free = thread_measure_stack_free(stack);
|
||||
unsigned free = measure_stack_free_internal(stack, max_size);
|
||||
|
||||
if ((LOG_LEVEL >= LOG_INFO) &&
|
||||
(thread_get_stacksize(thread_get_active()) >= MIN_SIZE)) {
|
||||
|
||||
2
tests/rust_minimal/Cargo.lock
generated
2
tests/rust_minimal/Cargo.lock
generated
@ -574,7 +574,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "riot-wrappers"
|
||||
version = "0.8.3"
|
||||
source = "git+https://github.com/RIOT-OS/rust-riot-wrappers#ea8d7fad95c8cb256ba9bc178f7779d266cc0def"
|
||||
source = "git+https://github.com/RIOT-OS/rust-riot-wrappers#87ba1141e093a97d1999e3c48ab276dd0e9c6529"
|
||||
dependencies = [
|
||||
"bare-metal",
|
||||
"coap-handler 0.1.6",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user