diff --git a/core/include/attributes.h b/core/include/attributes.h index b01a581f7..f9fa7ac64 100644 --- a/core/include/attributes.h +++ b/core/include/attributes.h @@ -19,6 +19,8 @@ #ifndef ATTRIBUTES_H_ #define ATTRIBUTES_H_ +#include + #ifdef __cplusplus extern "C" { #endif @@ -72,6 +74,14 @@ #define UNREACHABLE() do { /* nothing */ } while (1) #endif +/** + * @def ALIGN_OF(T) + * @brief Calculate the minimal alignment for type T. + * @param[in] T Type to examine + * @returns The minimal alignment of T. + */ +#define ALIGN_OF(T) (offsetof(struct { char c; T t; }, t)) + #ifdef __cplusplus } #endif diff --git a/core/include/thread.h b/core/include/thread.h index 47569d078..4ee1253e1 100644 --- a/core/include/thread.h +++ b/core/include/thread.h @@ -156,7 +156,7 @@ static inline kernel_pid_t thread_getpid(void) * * @return the amount of unused space of the thread's stack */ -int thread_measure_stack_free(char *stack); +uintptr_t thread_measure_stack_free(char *stack); #endif #ifdef __cplusplus diff --git a/core/thread.c b/core/thread.c index de066a6fa..91f9c8822 100644 --- a/core/thread.c +++ b/core/thread.c @@ -90,62 +90,62 @@ int thread_wakeup(kernel_pid_t pid) } #ifdef DEVELHELP -int thread_measure_stack_free(char *stack) +uintptr_t thread_measure_stack_free(char *stack) { - unsigned int *stackp = (unsigned int *)stack; + uintptr_t *stackp = (uintptr_t *)stack; /* assume that the comparison fails before or after end of stack */ /* assume that the stack grows "downwards" */ - while (*stackp == (unsigned int)stackp) { + while (*stackp == (uintptr_t) stackp) { stackp++; } - int space_free = (unsigned int)stackp - (unsigned int)stack; + uintptr_t space_free = (uintptr_t) stackp - (uintptr_t) stack; return space_free; } #endif kernel_pid_t thread_create(char *stack, int stacksize, char priority, int flags, void *(*function)(void *arg), void *arg, const char *name) { - /* allocate our thread control block at the top of our stackspace */ + if (priority >= SCHED_PRIO_LEVELS) { + return -EINVAL; + } + #ifdef DEVELHELP int total_stacksize = stacksize; #endif - stacksize -= sizeof(tcb_t); - - /* align tcb address on 32bit boundary */ - unsigned int tcb_address = (unsigned int) stack + stacksize; - if (tcb_address & 1) { - tcb_address--; - stacksize--; + /* align the stack on a 16/32bit boundary */ + uintptr_t misalignment = (uintptr_t) stack % ALIGN_OF(void *); + if (misalignment) { + misalignment = ALIGN_OF(void *) - misalignment; + stack += misalignment; + stacksize -= misalignment; } - if (tcb_address & 2) { - tcb_address -= 2; - stacksize -= 2; - } + /* make room for the thread control block */ + stacksize -= sizeof(tcb_t); - tcb_t *cb = (tcb_t *) tcb_address; + /* round down the stacksize to a multiple of tcb_t alignments (usually 16/32bit) */ + stacksize -= stacksize % ALIGN_OF(tcb_t); - if (priority >= SCHED_PRIO_LEVELS) { - return -EINVAL; - } + /* allocate our thread control block at the top of our stackspace */ + tcb_t *cb = (tcb_t *) (stack + stacksize); #ifdef DEVELHELP if (flags & CREATE_STACKTEST) { /* assign each int of the stack the value of it's address */ - unsigned int *stackmax = (unsigned int *)((char *)stack + stacksize); - unsigned int *stackp = (unsigned int *)stack; + uintptr_t *stackmax = (uintptr_t *) (stack + stacksize); + uintptr_t *stackp = (uintptr_t *) stack; while (stackp < stackmax) { - *stackp = (unsigned int)stackp; + *stackp = (uintptr_t) stackp; stackp++; } } else { /* create stack guard */ - *stack = (unsigned int)stack; + *stack = (uintptr_t) stack; } #endif