diff --git a/cpu/native/async_read.c b/cpu/native/async_read.c index 5aed77739e..81c84b513d 100644 --- a/cpu/native/async_read.c +++ b/cpu/native/async_read.c @@ -1,4 +1,4 @@ -/** +/* * Multiple asynchronous read on file descriptors * * Copyright (C) 2015 Ludwig Knüpfer , @@ -11,10 +11,7 @@ * General Public License v2.1. See the file LICENSE in the top level * directory for more details. * - * @ingroup cpu_native - * @{ - * @file - * @author Takuo Yonezawa + * Author: Takuo Yonezawa */ #include @@ -45,11 +42,11 @@ static void _async_io_isr(void) { } void native_async_read_setup(void) { - register_interrupt(SIGIO, _async_io_isr); + native_register_interrupt(SIGIO, _async_io_isr); } void native_async_read_cleanup(void) { - unregister_interrupt(SIGIO); + native_unregister_interrupt(SIGIO); for (int i = 0; i < _next_index; i++) { real_close(_fds[i].fd); @@ -115,12 +112,12 @@ void native_async_read_remove_handler(int fd) return; } - unregister_interrupt(SIGIO); + native_unregister_interrupt(SIGIO); for (; i < (unsigned)_next_index - 1; i++) { _fds[i] = _fds[i + 1]; } _next_index--; - register_interrupt(SIGIO, _async_io_isr); + native_register_interrupt(SIGIO, _async_io_isr); _fds[_next_index] = (struct pollfd){ 0 }; } @@ -179,4 +176,3 @@ static void _sigio_child(int index) sigwait(&sigmask, &sig); } } -/** @} */ diff --git a/cpu/native/include/cpu.h b/cpu/native/include/cpu.h index 20a8f6310b..ca9dd47364 100644 --- a/cpu/native/include/cpu.h +++ b/cpu/native/include/cpu.h @@ -5,18 +5,6 @@ * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ - -/** - * @ingroup cpu - * @defgroup cpu_native Native - * @brief Native CPU specific code - * @details The native CPU uses system calls to simulate hardware access. - * @ingroup cpu - * @brief CPU abstraction for the native port - * @{ - * @author Ludwig Knüpfer - */ - #ifndef CPU_H #define CPU_H @@ -28,6 +16,22 @@ extern "C" { #endif +/** + * @defgroup cpu_native Native CPU + * @ingroup cpu + * @brief CPU implementation for running RIOT on a Linux and BSD + * @author Ludwig Knüpfer + * + * The native CPU uses system calls to simulate hardware access. + * + * @{ + */ + +/* MARK: - Basics */ +/** + * @name + * @{ + */ /** * @brief The CPU supports unaligned memory access. * Even if the underlying architecture does not support it, the kernel will take care of it. @@ -44,10 +48,12 @@ __attribute__((always_inline)) static inline uintptr_t cpu_get_caller_pc(void) * it is the return address of the user of this function */ return (uintptr_t)__builtin_return_address(0); } +/** @} */ + +/** @} */ #ifdef __cplusplus } #endif -/** @} */ #endif /* CPU_H */ diff --git a/cpu/native/include/cpu_conf.h b/cpu/native/include/cpu_conf.h index 88d37cbb94..2dec361e2c 100644 --- a/cpu/native/include/cpu_conf.h +++ b/cpu/native/include/cpu_conf.h @@ -1,4 +1,4 @@ -/** +/* * Native CPU configuration * * Copyright (C) 2013 Ludwig Knüpfer @@ -6,12 +6,6 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer - * @} */ #ifndef CPU_CONF_H #define CPU_CONF_H @@ -21,7 +15,13 @@ extern "C" { #endif /** - * @brief CPU specific default stack sizes + * @addtogroup cpu_native + * @{ + */ + +/* MARK: - CPU-specific default stack sizes */ +/** + * @brief CPU-specific default stack sizes * * TODO: tighten stack sizes * @@ -53,6 +53,11 @@ extern "C" { #endif /** @} */ +/* MARK: - Networking constants */ +/** + * @name Networking constants + * @{ + */ /** * @brief Native internal Ethernet protocol number */ @@ -62,10 +67,12 @@ extern "C" { # undef CONFIG_GNRC_PKTBUF_SIZE # define CONFIG_GNRC_PKTBUF_SIZE (2048) #endif +/** @} */ +/* MARK: - Native flash emulation */ /** - * @brief Native Flash emulation - * Use unusual parameters to trigger edge cases + * @name Native flash emulation + * Use unusual parameters to trigger edge cases * @{ */ #ifndef FLASHPAGE_SIZE @@ -89,6 +96,8 @@ extern char _native_flash[FLASHPAGE_SIZE * FLASHPAGE_NUMOF]; #define CPU_FLASH_BASE ((uintptr_t)_native_flash) /** @} */ +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/native/include/native_internal.h b/cpu/native/include/native_internal.h index 154baf2b33..3e7e08f35d 100644 --- a/cpu/native/include/native_internal.h +++ b/cpu/native/include/native_internal.h @@ -11,50 +11,25 @@ */ /** - * @defgroup cpu_native_stdio STDIO for native - * @ingroup sys_stdio - * @brief Standard input/output backend for native + * @defgroup cpu_native_stdio STDIO for native + * @ingroup sys_stdio + * @brief Standard input/output backend for native * * This will hook up RIOT's stdio to the host's stdio fds. It is the default * stdio implementation of the board `native`. * - * @see cpu_native - */ - -/** - * @ingroup cpu_native - * @{ - * @author Ludwig Knüpfer + * @see @ref cpu_native */ #ifndef NATIVE_INTERNAL_H #define NATIVE_INTERNAL_H -#include +#include "util/ucontext.h" #include #include #include -/* enable signal handler register access on different platforms - * check here for more: - * http://sourceforge.net/p/predef/wiki/OperatingSystems/ - */ -#ifdef __FreeBSD__ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE -#include -#undef _XOPEN_SOURCE -#else -#include -#endif -#elif defined(__linux__) -#ifndef _GNU_SOURCE -#define GNU_SOURCE -#include -#undef GNU_SOURCE -#else -#include -#endif -#endif /* BSD/Linux */ + +#include #include #include #include @@ -64,80 +39,270 @@ #include #include +#include "cpu_conf.h" +#include "thread.h" +#include "sched.h" + #ifdef __cplusplus extern "C" { #endif #include "syscalls.h" + /** - * Prototype for native's internal callbacks + * @addtogroup cpu_native + * @{ + */ + +/* MARK: - Internal native CPU API */ +/** + * @name Internal native CPU API + * @{ + */ + +/** + * @brief Prototype for native's internal callbacks */ typedef void (*_native_callback_t)(void); /** - * @cond INTERNAL - * internal functions + * @brief Initializes native CPU */ void native_cpu_init(void); +/** @} */ + +/* MARK: - Native Signal Handling */ +/** + * @name Native Signal Handling + * @{ + */ + +/** + * @brief A boolean variable indicating whether interrupts are currently permissible + * @private + */ +extern volatile bool _native_interrupts_enabled; + +/** + * @brief Pipe yielding signals + * @private + * + * The internal signal handler writes into the write end of this pipe + */ +extern int _signal_pipe_fd[2]; + +/** + * @brief Number of currently pending signals + * @private + */ +extern volatile int _native_pending_signals; + +/** + * @brief Registers signal handlers for the native CPU + */ void native_interrupt_init(void); -void native_irq_handler(void); +/** + * @brief Register interrupt handler handler for interrupt signal + * + * @param sig Signal number + * @param handler Signal action function + * + * @returns 0 on success, negative number otherwise. + */ +int native_register_interrupt(int sig, _native_callback_t handler); + +/** + * @brief Unregister interrupt handler for interrupt signal + * + * @param sig Signal number + * + * @returns 0 on success, negative number otherwise. + */ +int native_unregister_interrupt(int sig); + +/** + * @brief Calls signal handlers for pending signal, then exits ISR context and performs context switch + * @pre Intended to be called from **ISR context** + * @private + * + * The context switch back to userspace is performed using @ref `cpu_switch_context_exit`. + * + * @note While it would have been possible to separate this method's functionality into two functions, `setcontext` requires us to have a single function. + */ +void _native_call_sig_handlers_and_switch(void); + +/** + * @brief Switches to ISR context, then enables IRQ and returns to userspace + * + * @note This function is implemented in assembly. + */ extern void _native_sig_leave_tramp(void); -extern void _native_sig_leave_handler(void); +/** @} */ + +/* MARK: - System Calls */ +/** + * @name System Calls + * + * We wrap system calls and syscall-invoking library calls to ensure **no context switches occur during a system call**. + * @{ + */ +/** + * @brief Number of currently pending system calls + * @private + */ +extern volatile int _native_pending_syscalls; + +/** + * @brief Increment spending system call counter + */ +static inline void _native_pending_syscalls_up(void) { + _native_pending_syscalls += 1; +} + +/** + * @brief Decrements pending system call counter + */ +static inline void _native_pending_syscalls_down(void) { + _native_pending_syscalls -= 1; +} + +/** + * @brief Executes post-syscall logic + * @private + * + * Decrements internal pending syscall counter. + * + * If there are other pending system calls and when not already in an ISR context, this function switches to the ISR context and + * calls signals handlers. This is done through @ref `_native_call_sig_handlers_and_switch`. Returns to userspace + * thereafter. + */ void _native_syscall_leave(void); + +/** + * @brief Executes pre-syscall logic + * @private + * + * Increments internal pending syscall counter. + */ void _native_syscall_enter(void); + +/** + * @brief Registers system calls. + * + * Wraps syscall functions from the standard library. + */ void _native_init_syscalls(void); +/** @} */ +/* MARK: - Native Context Switching */ /** - -/** - * data structures + * @name Native Context Switching + * @{ + */ + +// TODO: do we still need to expose this? +extern volatile uintptr_t _native_user_fptr; + +/** + * @brief A boolean variable indicating whether program execution currently takes place in an ISR context */ -extern volatile int native_interrupts_enabled; -extern volatile uintptr_t _native_saved_eip; -extern int _sig_pipefd[2]; -extern volatile int _native_sigpend; extern volatile int _native_in_isr; -extern volatile int _native_in_syscall; -extern char __isr_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; +/** + * @brief Stack used in ISR context + */ +extern char _isr_stack[THREAD_STACKSIZE_DEFAULT]; +/** + * @brief ISR context + */ +extern ucontext_t *_native_isr_context; + +/** + * @brief Resets internal `in_ISR` barrier switch and resumes execution on the currently scheduled thread + * @pre Intended to be executed in userspace + * @private + * + * @note This function is implemented in assembly to preserve registers. See `native.S` + */ +extern void _native_isr_leave(void); + + +/** @} */ + +/* MARK: - Native Process State */ +/** + * @name Native Process State + * @{ + */ +/** + * @brief Program name + * @private + */ extern const char *_progname; + +/** + * @brief Program argument values + * @private + */ extern char **_native_argv; + +/** + * @brief Process Identifier + * @private + */ extern pid_t _native_pid; + +/** + * @brief Process Identifier / CPUID ??? + * @private + */ extern pid_t _native_id; -extern unsigned _native_rng_seed; -extern int _native_rng_mode; /**< 0 = /dev/random, 1 = random(3) */ -extern const char *_native_unix_socket_path; +/** + * @brief Random number generator seed value + * @private + */ +extern unsigned int _native_rng_seed; + +/** + * @brief Random number generator mode + * @private + * + * - `0`: Use `/dev/random` + * - `1`: Use `random(3)` + */ +extern int _native_rng_mode; +/** @} */ + +/* MARK: - Native Read/Write Methods */ +/** + * @name Native Read/Write Methods + * @{ + */ +/** + * @brief Reads file, populates given buffer + */ ssize_t _native_read(int fd, void *buf, size_t count); + +/** + * @brief Writes given data into file + */ ssize_t _native_write(int fd, const void *buf, size_t count); + +/** + * @brief Performs a vectored write operation + */ ssize_t _native_writev(int fildes, const struct iovec *iov, int iovcnt); +/** @} */ -/** - * @endcond - */ -/** - * register interrupt handler handler for interrupt sig - */ -int register_interrupt(int sig, _native_callback_t handler); - -/** - * unregister interrupt handler for interrupt sig - */ -int unregister_interrupt(int sig); +/** @} */ #ifdef __cplusplus } #endif -#include "sched.h" - -/** @} */ #endif /* NATIVE_INTERNAL_H */ diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index e1c0d88323..cf7007f16a 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -1,4 +1,4 @@ -/** +/* * Native CPU irq.h implementation * * Copyright (C) 2013 Ludwig Knüpfer @@ -6,18 +6,8 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer */ -/* __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 #include #include @@ -46,31 +36,38 @@ #include "debug.h" #define DEBUG_IRQ(...) DEBUG("[native] IRQ: " __VA_ARGS__) -volatile int native_interrupts_enabled = 0; +volatile bool _native_interrupts_enabled = false; volatile int _native_in_isr; -volatile int _native_in_syscall; +volatile int _native_pending_syscalls; -static sigset_t _native_sig_set, _native_sig_set_dint; +char _isr_stack[THREAD_STACKSIZE_DEFAULT]; +static ucontext_t _native_isr_context_storage; +ucontext_t *_native_isr_context = &_native_isr_context_storage; +ucontext_t *_native_current_context = NULL; -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; +volatile uintptr_t _native_user_fptr; -volatile uintptr_t _native_saved_eip; -volatile int _native_sigpend; -int _sig_pipefd[2]; +static sigset_t _native_sig_set; +static sigset_t _native_sig_set_dint; +volatile int _native_pending_signals; +int _signal_pipe_fd[2]; -static _native_callback_t native_irq_handlers[255]; +static _native_callback_t _native_irq_handlers[255]; + +static inline void _set_sigmask(ucontext_t *ctx) +{ + ctx->uc_sigmask = _native_sig_set_dint; + _native_interrupts_enabled = false; +} void *thread_isr_stack_pointer(void) { - return native_isr_context.uc_stack.ss_sp; + return _native_isr_context->uc_stack.ss_sp; } void *thread_isr_stack_start(void) { - return __isr_stack; + return _isr_stack; } void print_thread_sigmask(ucontext_t *cp) @@ -82,7 +79,7 @@ void print_thread_sigmask(ucontext_t *cp) } for (int i = 1; i < (NSIG); i++) { - if (native_irq_handlers[i] != NULL) { + if (_native_irq_handlers[i] != NULL) { printf("%s: %s\n", strsignal(i), (sigismember(&_native_sig_set, i) ? "blocked" : "unblocked") @@ -131,7 +128,7 @@ void native_print_signals(void) } for (int i = 1; i < (NSIG); i++) { - if (native_irq_handlers[i] != NULL || i == SIGUSR1) { + if (_native_irq_handlers[i] != NULL || i == SIGUSR1) { printf("%s: %s in active thread\n", strsignal(i), (sigismember(&_native_sig_set, i) ? "blocked" : "unblocked") @@ -166,8 +163,8 @@ unsigned irq_disable(void) err(EXIT_FAILURE, "irq_disable: sigprocmask"); } - prev_state = native_interrupts_enabled; - native_interrupts_enabled = 0; + prev_state = _native_interrupts_enabled; + _native_interrupts_enabled = false; DEBUG_IRQ("irq_disable(): return\n"); _native_syscall_leave(); @@ -197,8 +194,8 @@ unsigned irq_enable(void) * before returning to userspace. */ - prev_state = native_interrupts_enabled; - native_interrupts_enabled = 1; + prev_state = _native_interrupts_enabled; + _native_interrupts_enabled = true; if (sigprocmask(SIG_SETMASK, &_native_sig_set, NULL) == -1) { err(EXIT_FAILURE, "irq_enable: sigprocmask"); @@ -232,7 +229,7 @@ void irq_restore(unsigned state) bool irq_is_enabled(void) { - return native_interrupts_enabled; + return _native_interrupts_enabled; } bool irq_is_in(void) @@ -241,7 +238,7 @@ bool irq_is_in(void) return _native_in_isr; } -int _native_popsig(void) +static int _native_pop_sig(void) { int nread, nleft, i; int sig = 0; @@ -249,36 +246,32 @@ int _native_popsig(void) nleft = sizeof(int); i = 0; - while ((nleft > 0) && ((nread = real_read(_sig_pipefd[0], ((uint8_t*)&sig) + i, nleft)) != -1)) { + while ((nleft > 0) && ((nread = real_read(_signal_pipe_fd[0], ((uint8_t*)&sig) + i, nleft)) != -1)) { i += nread; nleft -= nread; } if (nread == -1) { - err(EXIT_FAILURE, "_native_popsig: real_read"); + err(EXIT_FAILURE, "_native_pop_sig: real_read"); } return sig; } -/** - * call signal handlers, - * restore user context - */ -void native_irq_handler(void) +void _native_call_sig_handlers_and_switch(void) { DEBUG_IRQ("\n\n\t\tcall sig handlers + switch\n\n"); - while (_native_sigpend > 0) { - int sig = _native_popsig(); - _native_sigpend--; + while (_native_pending_signals > 0) { + int sig = _native_pop_sig(); + _native_pending_signals--; - if (native_irq_handlers[sig] != NULL) { - native_irq_handlers[sig](); + if (_native_irq_handlers[sig]) { DEBUG_IRQ("call sig handlers + switch: calling interrupt handler for %i\n", sig); + _native_irq_handlers[sig](); } else if (sig == SIGUSR1) { - warnx("native_irq_handler: ignoring SIGUSR1"); + warnx("call sig handlers + switch: ignoring SIGUSR1"); } else { errx(EXIT_FAILURE, "XXX: no handler for signal %i\nXXX: this should not have happened!\n", sig); @@ -286,52 +279,41 @@ void native_irq_handler(void) } DEBUG_IRQ("call sig handlers + switch: return\n"); + + /* Leave ISR context */ cpu_switch_context_exit(); } -void isr_set_sigmask(ucontext_t *ctx) -{ - ctx->uc_sigmask = _native_sig_set_dint; - native_interrupts_enabled = 0; -} - -/** - * save signal, return to _native_sig_leave_tramp if possible - */ -void native_isr_entry(int sig, siginfo_t *info, void *context) +void native_signal_action(int sig, siginfo_t *info, void *context) { (void) info; /* unused at the moment */ - //printf("\n\033[33m\n\t\tnative_isr_entry(%i)\n\n\033[0m", sig); /* save the signal */ - if (real_write(_sig_pipefd[1], &sig, sizeof(int)) == -1) { - err(EXIT_FAILURE, "native_isr_entry: real_write()"); + if (real_write(_signal_pipe_fd[1], &sig, sizeof(int)) == -1) { + err(EXIT_FAILURE, "native_signal_action: real_write()"); } - _native_sigpend++; - //real_write(STDOUT_FILENO, "sigpend\n", 8); + _native_pending_signals++; if (context == NULL) { - errx(EXIT_FAILURE, "native_isr_entry: context is null - unhandled"); + errx(EXIT_FAILURE, "native_signal_action: context is null - unhandled"); } if (thread_get_active() == NULL) { _native_in_isr++; - warnx("native_isr_entry: thread_get_active() is null - unhandled"); + warnx("native_signal_action: thread_get_active() is null - unhandled"); _native_in_isr--; return; } /* XXX: Workaround safety check - whenever this happens it really * indicates a bug in irq_disable */ - if (native_interrupts_enabled == 0) { - //printf("interrupts are off, but I caught a signal.\n"); + if (!_native_interrupts_enabled) { return; } if (_native_in_isr != 0) { - //real_write(STDOUT_FILENO, "interrupts in ISR!!\n", 20); return; } - if (_native_in_syscall != 0) { + if (_native_pending_syscalls != 0) { DEBUG_IRQ("\n\n\t\tnative_signal_action: return to syscall\n\n"); return; } @@ -368,13 +350,7 @@ void native_isr_entry(int sig, siginfo_t *info, void *context) #endif } -/** - * Add or remove handler for signal - * - * To be called with interrupts disabled - * - */ -void set_signal_handler(int sig, bool add) +static void _set_signal_handler(int sig, bool add) { struct sigaction sa; int ret; @@ -404,7 +380,7 @@ void set_signal_handler(int sig, bool add) if (add) { sa.sa_flags |= SA_SIGINFO; /* sa.sa_sigaction is used */ - sa.sa_sigaction = native_isr_entry; + sa.sa_sigaction = native_signal_action; } else { sa.sa_handler = SIG_IGN; @@ -417,38 +393,30 @@ void set_signal_handler(int sig, bool add) _native_syscall_leave(); } -/** - * register signal/interrupt handler for signal sig - * - * TODO: use appropriate data structure for signal - * handlers. - */ -int register_interrupt(int sig, _native_callback_t handler) +/* TODO: use appropriate data structure for signal handlers. */ +int native_register_interrupt(int sig, _native_callback_t handler) { DEBUG_IRQ("native_register_interrupt\n"); unsigned state = irq_disable(); - native_irq_handlers[sig] = handler; - set_signal_handler(sig, true); + _native_irq_handlers[sig] = handler; + _set_signal_handler(sig, true); irq_restore(state); return 0; } -/** - * empty signal mask - */ -int unregister_interrupt(int sig) +int native_unregister_interrupt(int sig) { /* empty signal mask */ DEBUG_IRQ("native_unregister_interrupt\n"); unsigned state = irq_disable(); - set_signal_handler(sig, false); - native_irq_handlers[sig] = NULL; + _set_signal_handler(sig, false); + _native_irq_handlers[sig] = NULL; irq_restore(state); @@ -464,14 +432,10 @@ static void native_shutdown(int sig, siginfo_t *info, void *context) pm_off(); } -/** - * register internal signal handler, - * initialize local variables - * - * TODO: see register_interrupt - */ void native_interrupt_init(void) { + /* register internal signal handler, initialize local variables + * TODO: see native_register_interrupt */ struct sigaction sa; DEBUG_IRQ("native_interrupt_init\n"); @@ -479,13 +443,10 @@ void native_interrupt_init(void) VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n", (void *)__isr_stack, (void*)(__isr_stack + sizeof(__isr_stack))); - _native_sigpend = 0; + _native_pending_signals = 0; + memset(_native_irq_handlers, 0, sizeof(_native_irq_handlers)); - for (int i = 0; i < 255; i++) { - native_irq_handlers[i] = NULL; - } - - sa.sa_sigaction = native_isr_entry; + sa.sa_sigaction = native_signal_action; if (sigfillset(&sa.sa_mask) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigfillset"); @@ -517,7 +478,7 @@ void native_interrupt_init(void) err(EXIT_FAILURE, "native_interrupt_init: sigaction"); } - if (getcontext(&native_isr_context) == -1) { + if (getcontext(_native_isr_context) == -1) { err(EXIT_FAILURE, "native_interrupt_init: getcontext"); } @@ -536,16 +497,14 @@ void native_interrupt_init(void) err(EXIT_FAILURE, "native_interrupt_init: sigaltstack"); } - makecontext(&native_isr_context, native_irq_handler, 0); + _native_pending_syscalls = 0; - _native_in_syscall = 0; - - if (real_pipe(_sig_pipefd) == -1) { + if (real_pipe(_signal_pipe_fd) == -1) { err(EXIT_FAILURE, "native_interrupt_init: pipe"); } /* allow for ctrl+c to shut down gracefully always */ - //register_interrupt(SIGINT, native_shutdown); + //native_register_interrupt(SIGINT, native_shutdown); sa.sa_sigaction = native_shutdown; if (sigdelset(&_native_sig_set, SIGINT) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigdelset"); diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index e544648545..dc043e6faa 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -1,43 +1,31 @@ /* + * Native CPU kernel_intern.h and sched.h implementation + * * Copyright (C) 2016 Kaspar Schleiser * 2013 Ludwig Knüpfer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. + * + * Author: Ludwig Knüpfer + * Author: Kaspar Schleiser */ /** - * @ingroup cpu_native - * @{ - * * @file * @brief Native CPU kernel_intern.h and sched.h implementation - * - * in-process preemptive context switching utilizes POSIX ucontexts. - * (ucontext provides for architecture independent stack handling) - * * @author Ludwig Knüpfer * @author Kaspar Schleiser + * + * In-process preemptive context switching utilizes POSIX ucontexts. + * (ucontext provides for architecture independent stack handling) */ -/* __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 -#include #include -#include #include -#if USE_LIBUCONTEXT -#include -#else -#include -#endif - #ifdef HAVE_VALGRIND_H #include #define VALGRIND_DEBUG DEBUG @@ -50,6 +38,8 @@ #endif #include +#include +#include #include "cpu.h" #include "cpu_conf.h" @@ -68,7 +58,7 @@ extern netdev_tap_t netdev_tap; #include "debug.h" #define DEBUG_CPU(...) DEBUG("[native] CPU: " __VA_ARGS__) -ucontext_t end_context; +static ucontext_t _end_context; /** * make the new context assign `_native_in_isr = 0` before resuming @@ -99,7 +89,7 @@ static void _native_mod_ctx_leave_sigh(ucontext_t *ctx) */ void thread_print_stack(void) { - DEBUG("thread_print_stack\n"); + CPU_DEBUG("thread_print_stack\n"); return; } diff --git a/cpu/native/netdev_tap/netdev_tap.c b/cpu/native/netdev_tap/netdev_tap.c index 444ac0f2c0..99cf572f07 100644 --- a/cpu/native/netdev_tap/netdev_tap.c +++ b/cpu/native/netdev_tap/netdev_tap.c @@ -16,6 +16,7 @@ * @author Kaspar Schleiser * @} */ + #include #include #include @@ -28,19 +29,20 @@ #include #include #include +#include /* needs to be included before native's declarations of ntohl etc. */ #include "byteorder.h" -#ifdef __FreeBSD__ -#include -#include -#include -#include +#if defined(__FreeBSD__) +# include +# include +# include +# include #else -#include -#include -#include +# include +# include +# include #endif #include "native_internal.h" @@ -209,14 +211,14 @@ static void _continue_reading(netdev_tap_t *dev) FD_ZERO(&rfds); FD_SET(dev->tap_fd, &rfds); - _native_in_syscall++; /* no switching here */ + _native_pending_syscalls_up(); /* no switching here */ if (real_select(dev->tap_fd + 1, &rfds, NULL, NULL, &t) == 1) { int sig = SIGIO; - extern int _sig_pipefd[2]; + extern int _signal_pipe_fd[2]; extern ssize_t (*real_write)(int fd, const void * buf, size_t count); - real_write(_sig_pipefd[1], &sig, sizeof(int)); - _native_sigpend++; + real_write(_signal_pipe_fd[1], &sig, sizeof(int)); + _native_pending_signals++; DEBUG("netdev_tap: sigpend++\n"); } else { @@ -224,7 +226,7 @@ static void _continue_reading(netdev_tap_t *dev) native_async_read_continue(dev->tap_fd); } - _native_in_syscall--; + _native_pending_syscalls_down(); } static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) @@ -342,20 +344,20 @@ static int _init(netdev_t *netdev) } char *name = dev->tap_name; -#ifdef __FreeBSD__ +# ifdef __FreeBSD__ char clonedev[255] = "/dev/"; /* XXX bad size */ strncpy(clonedev + 5, name, 250); -#else /* Linux */ +# else /* Linux */ struct ifreq ifr; const char *clonedev = "/dev/net/tun"; -#endif +# endif /* initialize device descriptor */ dev->promiscuous = 0; /* implicitly create the tap interface */ if ((dev->tap_fd = real_open(clonedev, O_RDWR | O_NONBLOCK)) == -1) { err(EXIT_FAILURE, "open(%s)", clonedev); } -#if __FreeBSD__ /* FreeBSD */ +# if __FreeBSD__ /* FreeBSD */ struct ifaddrs *iflist; if (real_getifaddrs(&iflist) == 0) { for (struct ifaddrs *cur = iflist; cur; cur = cur->ifa_next) { @@ -367,12 +369,12 @@ static int _init(netdev_t *netdev) } real_freeifaddrs(iflist); } -#else /* Linux */ +# else /* Linux */ memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, name, IFNAMSIZ); if (real_ioctl(dev->tap_fd, TUNSETIFF, (void *)&ifr) == -1) { - _native_in_syscall++; + _native_pending_syscalls_up(); warn("ioctl TUNSETIFF"); warnx("probably the tap interface (%s) does not exist or is already in use", name); real_exit(EXIT_FAILURE); @@ -382,7 +384,7 @@ static int _init(netdev_t *netdev) memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", name); if (real_ioctl(dev->tap_fd, SIOCGIFHWADDR, &ifr) == -1) { - _native_in_syscall++; + _native_pending_syscalls_up(); warn("ioctl SIOCGIFHWADDR"); if (real_close(dev->tap_fd) == -1) { warn("close"); @@ -393,7 +395,7 @@ static int _init(netdev_t *netdev) /* change mac addr so it differs from what the host is using */ dev->addr[5]++; -#endif +# endif DEBUG("gnrc_tapnet_init(): dev->addr = %02x:%02x:%02x:%02x:%02x:%02x\n", dev->addr[0], dev->addr[1], dev->addr[2], dev->addr[3], dev->addr[4], dev->addr[5]); diff --git a/cpu/native/panic.c b/cpu/native/panic.c index 127df9f005..67a79ce1bd 100644 --- a/cpu/native/panic.c +++ b/cpu/native/panic.c @@ -7,15 +7,11 @@ */ /** - * @ingroup cpu_native - * @{ - * * @file - * @brief Crash handling functions implementation for 'native' port - * - * @author Ludwig Knüpfer - * @author Kévin Roussel - * @author Oliver Hahm + * @brief Crash handling functions implementation for 'native' port + * @author Ludwig Knüpfer + * @author Kévin Roussel + * @author Oliver Hahm */ #include diff --git a/cpu/native/periph/gpio_linux.c b/cpu/native/periph/gpio_linux.c index 2b32790e99..f04e749b86 100644 --- a/cpu/native/periph/gpio_linux.c +++ b/cpu/native/periph/gpio_linux.c @@ -17,8 +17,6 @@ * @author Benjamin Valentin */ -#define _GNU_SOURCE - #include #include #include diff --git a/cpu/native/periph/pm.c b/cpu/native/periph/pm.c index a1215163ef..19de1c92c7 100644 --- a/cpu/native/periph/pm.c +++ b/cpu/native/periph/pm.c @@ -40,12 +40,12 @@ unsigned _native_retval = EXIT_SUCCESS; static void _native_sleep(void) { - _native_in_syscall++; /* no switching here */ + _native_pending_syscalls_up(); /* no switching here */ real_pause(); - _native_in_syscall--; + _native_pending_syscalls_down(); - if (_native_sigpend > 0) { - _native_in_syscall++; + if (_native_pending_signals > 0) { + _native_pending_syscalls_up(); _native_syscall_leave(); } } diff --git a/cpu/native/periph/timer.c b/cpu/native/periph/timer.c index 7a80baa2e3..479aeb4e64 100644 --- a/cpu/native/periph/timer.c +++ b/cpu/native/periph/timer.c @@ -121,7 +121,7 @@ int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg) return -1; } - if (register_interrupt(SIGALRM, native_isr_timer) != 0) { + if (native_register_interrupt(SIGALRM, native_isr_timer) != 0) { DEBUG_PUTS("Failed to register SIGALRM handler"); timer_delete(itimer_monotonic); return -1; diff --git a/cpu/native/socket_zep/socket_zep.c b/cpu/native/socket_zep/socket_zep.c index ea5617de5a..aaa432e5d4 100644 --- a/cpu/native/socket_zep/socket_zep.c +++ b/cpu/native/socket_zep/socket_zep.c @@ -88,19 +88,19 @@ static void _continue_reading(socket_zep_t *dev) FD_ZERO(&rfds); FD_SET(dev->sock_fd, &rfds); - _native_in_syscall++; /* no switching here */ + _native_pending_syscalls_up(); /* no switching here */ if (real_select(dev->sock_fd + 1, &rfds, NULL, NULL, &t) == 1) { int sig = SIGIO; - extern int _sig_pipefd[2]; - real_write(_sig_pipefd[1], &sig, sizeof(sig)); - _native_sigpend++; + extern int _signal_pipe_fd[2]; + real_write(_signal_pipe_fd[1], &sig, sizeof(sig)); + _native_pending_signals++; } else { native_async_read_continue(dev->sock_fd); } - _native_in_syscall--; + _native_pending_syscalls_down(); } static inline bool _dst_not_me(socket_zep_t *dev, const void *buf) diff --git a/cpu/native/startup.c b/cpu/native/startup.c index cc1abfaa38..b0959267e4 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -1,5 +1,4 @@ -/** - * Native CPU entry code +/* Native CPU entry code * * Copyright (C) 2013 Ludwig Knüpfer * 2017 Freie Universität Berlin @@ -8,24 +7,16 @@ * General Public License v2.1. See the file LICENSE in the top level * directory for more details. * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer - * @author Martine Lenders - * @} + * Author: Ludwig Knüpfer + * Author: Martine Lenders */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE #include -#else -#include -#endif #include #include #include #include +#include #include #include #include @@ -728,7 +719,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e periph_init(); board_init(); - register_interrupt(SIGUSR1, _reset_handler); + native_register_interrupt(SIGUSR1, _reset_handler); puts("RIOT native hardware initialization complete.\n"); irq_enable(); diff --git a/cpu/native/syscalls.c b/cpu/native/syscalls.c index 5d2230ac00..1ee05c3703 100644 --- a/cpu/native/syscalls.c +++ b/cpu/native/syscalls.c @@ -1,5 +1,4 @@ -/** - * Native CPU syscall managing +/* Native CPU syscall managing * * Wrap system calls and system call invoking library calls to make * sure no context switches happen during a system call. @@ -9,20 +8,9 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE #include -#else -#include -#endif - #include #include #include @@ -32,7 +20,7 @@ #include #include #ifdef MODULE_LIBC_GETTIMEOFDAY -#include +# include #endif #include #include @@ -40,8 +28,8 @@ #include "cpu.h" #include "irq.h" #ifdef MODULE_LIBC_GETTIMEOFDAY -#include "time_units.h" -#include "ztimer64.h" +# include "time_units.h" +# include "ztimer64.h" #endif #include "stdio_base.h" @@ -61,7 +49,7 @@ void _native_syscall_enter(void) { - _native_in_syscall++; + _native_pending_syscalls_up(); if (IS_ACTIVE(ENABLE_DEBUG)) { real_write(STDERR_FILENO, _SYSCALL_ENTER_MESSAGE, sizeof(_SYSCALL_ENTER_MESSAGE) - 1); @@ -74,12 +62,12 @@ void _native_syscall_leave(void) real_write(STDERR_FILENO, _SYSCALL_LEAVE_MESSAGE, sizeof(_SYSCALL_LEAVE_MESSAGE) - 1); } - _native_in_syscall--; + _native_pending_syscalls_down(); if ( - (_native_sigpend > 0) + (_native_pending_signals > 0) && (_native_in_isr == 0) - && (_native_in_syscall == 0) - && (native_interrupts_enabled == 1) + && (_native_pending_syscalls == 0) + && (_native_interrupts_enabled) && (thread_get_active() != NULL) ) { @@ -454,9 +442,6 @@ int _gettimeofday(struct timeval *tp, void *restrict tzp) } #endif -/** - * set up native internal syscall symbols - */ void _native_init_syscalls(void) { *(void **)(&real_read) = dlsym(RTLD_NEXT, "read"); diff --git a/sys/include/fs/native_fs.h b/sys/include/fs/native_fs.h index 1a521990fc..5abfd90922 100644 --- a/sys/include/fs/native_fs.h +++ b/sys/include/fs/native_fs.h @@ -7,14 +7,14 @@ */ /** - * @defgroup sys_fs_native native fs integration - * @ingroup cpu_native - * @brief Access to the host fs from RIOT native + * @defgroup sys_fs_native Native FS Integration + * @ingroup cpu_native + * @brief Access to the host filesystem from RIOT native * * @{ * * @file - * @brief native integration with vfs + * @brief Native integration with virtual filesystem (VFS) * * @author Benjamin Valentin */