diff --git a/cpu/native/include/cpu-conf.h b/cpu/native/include/cpu-conf.h index 1a6d31ba81..f83318f582 100644 --- a/cpu/native/include/cpu-conf.h +++ b/cpu/native/include/cpu-conf.h @@ -17,16 +17,10 @@ #include /* TODO: choose more sensibly? */ -#ifndef KERNEL_CONF_STACKSIZE_DEFAULT -#define KERNEL_CONF_STACKSIZE_DEFAULT 8192 -#endif - -#define KERNEL_CONF_STACKSIZE_IDLE 4096 -#define NATIVE_ISR_STACKSIZE 8192 - -#define _SIG_LTC4150 SIGRTMIN + 0 - -/* TODO: check for overflow (SIGRTMAX) */ +#define KERNEL_CONF_STACKSIZE_DEFAULT (16384) +#define KERNEL_CONF_STACKSIZE_IDLE (4096) +#define NATIVE_ISR_STACKSIZE (16384) +#define TRANSCEIVER_STACK_SIZE (16384) /* for cc110x_ng */ #define RX_BUF_SIZE (10) diff --git a/cpu/native/include/cpu.h b/cpu/native/include/cpu.h index d2c0fbd144..0d64a967d3 100644 --- a/cpu/native/include/cpu.h +++ b/cpu/native/include/cpu.h @@ -46,5 +46,6 @@ int unregister_interrupt(int sig); /* this should be defined elsewhere */ void thread_yield(void); +extern volatile ucontext_t *interrupted_contexts[MAXTHREADS]; /** @} */ #endif //_CPU_H diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index 4ac6f47ea0..0defac2949 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -37,6 +37,74 @@ struct int_handler_t { }; static struct int_handler_t native_irq_handlers[255]; +volatile ucontext_t *interrupted_contexts[MAXTHREADS]; + +void print_thread_sigmask(ucontext_t *cp) +{ + sigset_t *p = &cp->uc_sigmask; + if (sigemptyset(p) == -1) { + err(1, "print_thread_sigmask: sigemptyset"); + } + + for (int i = 1; i<(SIGRTMAX); i++) { + if (native_irq_handlers[i].func != NULL) { + printf("%s: %s\n", + strsignal(i), + (sigismember(&native_sig_set, i) ? "blocked": "unblocked") + ); + } + if (sigismember(p, i)) { + printf("%s: pending\n", strsignal(i)); + } + } +} + +void print_sigmasks(void) +{ + ucontext_t *p; + //tcb_t *cb = NULL; + + for (int i=0; iname); + //print_thread_sigmask(sched_threads[i]->sp); + p = sched_threads[i]->stack_start; + print_thread_sigmask(p); + puts(""); + } + } +} + +void native_print_signals() +{ + sigset_t p, q; + puts("native signals:\n"); + if (sigemptyset(&p) == -1) { + err(1, "native_print_signals: sigemptyset"); + } + if (sigpending(&p) == -1) { + err(1, "native_print_signals: sigpending"); + } + if (sigprocmask(SIG_SETMASK, NULL, &q) == -1) { + err(1, "native_print_signals(): sigprocmask"); + } + + for (int i = 1; i<(SIGRTMAX); i++) { + if (native_irq_handlers[i].func != NULL || i == SIGUSR1) { + printf("%s: %s\n", + strsignal(i), + (sigismember(&native_sig_set, i) ? "blocked": "unblocked") + ); + } + if (sigismember(&p, i)) { + printf("%s: pending\n", strsignal(i)); + } + if (sigismember(&q, i)) { + printf("%s: currently blocked\n", strsignal(i)); + } + } +} + /** * block signals */ @@ -83,6 +151,9 @@ unsigned enableIRQ(void) prev_state = native_interrupts_enabled; native_interrupts_enabled = 1; + //print_sigmasks(); + //native_print_signals(); + return prev_state; } @@ -188,6 +259,15 @@ void native_isr_entry(int sig, siginfo_t *info, void *context) makecontext(&native_context, native_irq_handler, 0); +#ifdef NATIVEUSESWAPCONTEXT + /** + * XXX: + * This seems to be the cause of undefined behavior. Try saving + * the context passed to this function and using setcontext to + * leave the handler. + * Also it is probably wise to makecontext the isr context + * elsewehere. + * */ if ((swapcontext((ucontext_t*)active_thread->sp, &native_context)) == -1) { err(1, "swapcontext failed"); } @@ -196,6 +276,15 @@ void native_isr_entry(int sig, siginfo_t *info, void *context) } native_in_irs = 0; enableIRQ(); +#else + interrupted_contexts[thread_getpid()] = context; + /** + * signal masks are broken + */ + //active_thread->sp = context; + setcontext(&native_context); + DEBUG("\n\n\tnever reached\n\n\n"); +#endif } /** @@ -210,13 +299,14 @@ int register_interrupt(int sig, void *handler) struct sigaction sa; DEBUG("XXX: register_interrupt()\n"); - if (sigaddset(&native_sig_set, sig)) { - err(1, "register_interrupt: sigaddset"); + if (sigdelset(&native_sig_set, sig)) { + err(1, "register_interrupt: sigdelset"); } native_irq_handlers[sig].func = handler; sa.sa_sigaction = (void*) native_isr_entry; + /* sa.sa_handler = (void*) native_isr_entry; */ if (sigemptyset(&sa.sa_mask) == -1) { err(1, "register_interrupt: sigemptyset"); @@ -242,12 +332,13 @@ int unregister_interrupt(int sig) struct sigaction sa; DEBUG("XXX: unregister_interrupt()\n"); - if (sigdelset(&native_sig_set, sig) == -1) { - err(1, "unregister_interrupt: sigdelset"); + if (sigaddset(&native_sig_set, sig) == -1) { + err(1, "unregister_interrupt: sigaddset"); } native_irq_handlers[sig].func = NULL; - sa.sa_sigaction = SIG_IGN; + /* sa.sa_sigaction = SIG_IGN; */ + sa.sa_handler = SIG_IGN; if (sigemptyset(&sa.sa_mask) == -1) { err(1, "unregister_interrupt: sigemptyset"); } @@ -271,6 +362,8 @@ void native_interrupt_init(void) struct sigaction sa; DEBUG("XXX: native_interrupt_init()\n"); + native_interrupts_enabled = 1; + for (int i = 0; i<255; i++) { native_irq_handlers[i].func = NULL; } @@ -281,17 +374,38 @@ void native_interrupt_init(void) } sa.sa_flags = SA_RESTART | SA_SIGINFO; + /* if (sigemptyset(&native_sig_set) == -1) { err(1, "native_interrupt_init: sigemptyset"); } - if (sigaddset(&native_sig_set, SIGUSR1) == -1) { - err(1, "native_interrupt_init: sigaddset"); + */ + if (sigprocmask(SIG_SETMASK, NULL, &native_sig_set) == -1) { + err(1, "native_interrupt_init(): sigprocmask"); + } + + if (sigdelset(&native_sig_set, SIGUSR1) == -1) { + err(1, "native_interrupt_init: sigdelset"); } if (sigaction(SIGUSR1, &sa, NULL)) { err(1, "native_interrupt_init: sigaction"); } + if (sigdelset(&native_sig_set, SIGALRM) == -1) { + err(1, "native_interrupt_init: sigdelset"); + } + + if (sigaction(SIGALRM, &sa, NULL)) { + err(1, "native_interrupt_init: sigaction"); + } + if (sigprocmask(SIG_SETMASK, &native_sig_set, NULL) == -1) { + err(1, "native_interrupt_init(): sigprocmask"); + } + + for (int i = 0; iname); - if (setcontext((ucontext_t*)(active_thread->sp)) == -1) { + if (interrupted_contexts[thread_getpid()] == NULL) { + ctx = (ucontext_t*)(active_thread->sp); + } + else { + ctx = interrupted_contexts[thread_getpid()]; + interrupted_contexts[thread_getpid()] = NULL; + } + if (setcontext(ctx) == -1) { err(1, "cpu_switch_context_exit(): setcontext():"); } } void thread_yield() { - ucontext_t *oc; + /** + * XXX: check whether it is advisable to switch context for sched_run() + */ + ucontext_t *oc, *nc; DEBUG("thread_yield()\n"); - oc = (ucontext_t*)(active_thread->sp); + if (interrupted_contexts[thread_getpid()] == NULL) { + oc = (ucontext_t*)(active_thread->sp); + } + else { + oc = interrupted_contexts[thread_getpid()]; + interrupted_contexts[thread_getpid()] = NULL; + } + sched_run(); - DEBUG("thread_yield(): calling swapcontext(%s)\n\n", active_thread->name); - if (swapcontext(oc, (ucontext_t*)(active_thread->sp)) == -1) { - err(1, "thread_yield(): swapcontext()"); + nc = (ucontext_t*)(active_thread->sp); + if (nc != oc) { + DEBUG("thread_yield(): calling swapcontext(%s)\n\n", active_thread->name); + if (swapcontext(oc, nc) == -1) { + err(1, "thread_yield(): swapcontext()"); + } + } + else { + DEBUG("thread_yield(): old = new, returning to context (%s)\n\n", active_thread->name); } } diff --git a/sys/include/transceiver.h b/sys/include/transceiver.h index 9d2732baf0..f6cb927684 100644 --- a/sys/include/transceiver.h +++ b/sys/include/transceiver.h @@ -4,11 +4,13 @@ #include /* Stack size for transceiver thread */ +#ifndef TRANSCEIVER_STACK_SIZE #ifdef ENABLE_DEBUG #define TRANSCEIVER_STACK_SIZE (2048) #else #define TRANSCEIVER_STACK_SIZE (512) #endif +#endif #define PAYLOAD_SIZE (58)