unsigned int rust_valgrind_stack_register(void *start, void *end) { return VALGRIND_STACK_REGISTER(start, end); }
void register_valgrind_stack(stk_seg *stk) { stk->valgrind_id = VALGRIND_STACK_REGISTER(&stk->data[0], stk->end); }
_st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinable, int stk_size) { _st_thread_t *thread; _st_stack_t *stack; void **ptds; char *sp; #ifdef __ia64__ char *bsp; #endif /* Adjust stack size */ if (stk_size == 0) stk_size = ST_DEFAULT_STACK_SIZE; stk_size = ((stk_size + _ST_PAGE_SIZE - 1) / _ST_PAGE_SIZE) * _ST_PAGE_SIZE; stack = _st_stack_new(stk_size); if (!stack) return NULL; /* Allocate thread object and per-thread data off the stack */ #if defined (MD_STACK_GROWS_DOWN) sp = stack->stk_top; #ifdef __ia64__ /* * The stack segment is split in the middle. The upper half is used * as backing store for the register stack which grows upward. * The lower half is used for the traditional memory stack which * grows downward. Both stacks start in the middle and grow outward * from each other. */ sp -= (stk_size >> 1); bsp = sp; /* Make register stack 64-byte aligned */ if ((unsigned long)bsp & 0x3f) bsp = bsp + (0x40 - ((unsigned long)bsp & 0x3f)); stack->bsp = bsp + _ST_STACK_PAD_SIZE; #endif sp = sp - (ST_KEYS_MAX * sizeof(void *)); ptds = (void **) sp; sp = sp - sizeof(_st_thread_t); thread = (_st_thread_t *) sp; /* Make stack 64-byte aligned */ if ((unsigned long)sp & 0x3f) sp = sp - ((unsigned long)sp & 0x3f); stack->sp = sp - _ST_STACK_PAD_SIZE; #elif defined (MD_STACK_GROWS_UP) sp = stack->stk_bottom; thread = (_st_thread_t *) sp; sp = sp + sizeof(_st_thread_t); ptds = (void **) sp; sp = sp + (ST_KEYS_MAX * sizeof(void *)); /* Make stack 64-byte aligned */ if ((unsigned long)sp & 0x3f) sp = sp + (0x40 - ((unsigned long)sp & 0x3f)); stack->sp = sp + _ST_STACK_PAD_SIZE; #else #error Unknown OS #endif memset(thread, 0, sizeof(_st_thread_t)); memset(ptds, 0, ST_KEYS_MAX * sizeof(void *)); /* Initialize thread */ thread->private_data = ptds; thread->stack = stack; thread->start = start; thread->arg = arg; #ifndef __ia64__ _ST_INIT_CONTEXT(thread, stack->sp, _st_thread_main); #else _ST_INIT_CONTEXT(thread, stack->sp, stack->bsp, _st_thread_main); #endif /* If thread is joinable, allocate a termination condition variable */ if (joinable) { thread->term = st_cond_new(); if (thread->term == NULL) { _st_stack_free(thread->stack); return NULL; } } /* Make thread runnable */ thread->state = _ST_ST_RUNNABLE; _st_active_count++; _ST_ADD_RUNQ(thread); #ifdef DEBUG _ST_ADD_THREADQ(thread); #endif #ifndef NVALGRIND thread->stack->valgrind_stack_id = VALGRIND_STACK_REGISTER(thread->stack->stk_top, thread->stack->stk_bottom); #endif return thread; }
/** * register internal signal handler, * initalize local variables * * TODO: see register_interrupt */ void native_interrupt_init(void) { struct sigaction sa; DEBUG("XXX: native_interrupt_init()\n"); VALGRIND_STACK_REGISTER(__isr_stack, __isr_stack + sizeof(__isr_stack)); VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n", __isr_stack, (void*)((int)__isr_stack + sizeof(__isr_stack))); native_interrupts_enabled = 1; _native_sigpend = 0; for (int i = 0; i < 255; i++) { native_irq_handlers[i].func = NULL; } sa.sa_sigaction = native_isr_entry; if (sigfillset(&sa.sa_mask) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigfillset"); } sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; /* get current process interrupt masks */ if (sigprocmask(SIG_SETMASK, NULL, &_native_sig_set) == -1) { err(EXIT_FAILURE, "native_interrupt_init(): sigprocmask"); } /* we need to disable all signals during our signal handler as it * can not cope with interrupted signals ... */ if (sigfillset(&_native_sig_set_dint) == -1) { err(EXIT_FAILURE, "native_isr_entry(): sigfillset"); } /* SIGUSR1 is intended for debugging purposes and shall always be * enabled */ if (sigdelset(&_native_sig_set, SIGUSR1) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigdelset"); } if (sigdelset(&_native_sig_set_dint, SIGUSR1) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigdelset"); } /* SIGUSR1 is handled like a regular interrupt */ if (sigaction(SIGUSR1, &sa, NULL)) { err(EXIT_FAILURE, "native_interrupt_init: sigaction"); } if (getcontext(&native_isr_context) == -1) { err(EXIT_FAILURE, "native_isr_entry(): getcontext()"); } native_isr_context.uc_stack.ss_sp = __isr_stack; native_isr_context.uc_stack.ss_size = SIGSTKSZ; native_isr_context.uc_stack.ss_flags = 0; _native_isr_ctx = &native_isr_context; static stack_t sigstk; sigstk.ss_sp = sigalt_stk; sigstk.ss_size = SIGSTKSZ; sigstk.ss_flags = 0; if (sigaltstack(&sigstk, NULL) < 0) { err(EXIT_FAILURE, "main: sigaltstack"); } makecontext(&native_isr_context, native_irq_handler, 0); _native_in_syscall = 0; if (real_pipe(_sig_pipefd) == -1) { err(EXIT_FAILURE, "native_interrupt_init(): pipe()"); } /* allow for ctrl+c to shut down gracefully always */ //register_interrupt(SIGINT, shutdown); sa.sa_sigaction = shutdown; if (sigdelset(&_native_sig_set, SIGINT) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigdelset"); } if (sigdelset(&_native_sig_set_dint, SIGINT) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigdelset"); } if (sigaction(SIGINT, &sa, NULL)) { err(EXIT_FAILURE, "native_interrupt_init: sigaction"); } puts("RIOT native interrupts/signals initialized."); }
/// Register a stack with valgrind, so that it doesn't incorrectly complain /// about stack accesses. static int _register(ustack_t *thread) { void *begin = &thread->stack[0]; void *end = &thread->stack[_thread_size - sizeof(*thread)]; return VALGRIND_STACK_REGISTER(begin, end); }