Merge pull request #1268 from Kijewski/issue-1267

core: align stack on a 32bit boundary
This commit is contained in:
René Kijewski 2014-10-21 01:05:47 +02:00
commit c11a575ec0
3 changed files with 40 additions and 30 deletions

View File

@ -19,6 +19,8 @@
#ifndef ATTRIBUTES_H_ #ifndef ATTRIBUTES_H_
#define ATTRIBUTES_H_ #define ATTRIBUTES_H_
#include <stddef.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -72,6 +74,14 @@
#define UNREACHABLE() do { /* nothing */ } while (1) #define UNREACHABLE() do { /* nothing */ } while (1)
#endif #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -156,7 +156,7 @@ static inline kernel_pid_t thread_getpid(void)
* *
* @return the amount of unused space of the thread's stack * @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 #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -90,62 +90,62 @@ int thread_wakeup(kernel_pid_t pid)
} }
#ifdef DEVELHELP #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 comparison fails before or after end of stack */
/* assume that the stack grows "downwards" */ /* assume that the stack grows "downwards" */
while (*stackp == (unsigned int)stackp) { while (*stackp == (uintptr_t) stackp) {
stackp++; stackp++;
} }
int space_free = (unsigned int)stackp - (unsigned int)stack; uintptr_t space_free = (uintptr_t) stackp - (uintptr_t) stack;
return space_free; return space_free;
} }
#endif #endif
kernel_pid_t thread_create(char *stack, int stacksize, char priority, int flags, void *(*function)(void *arg), void *arg, const char *name) 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 */
#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--;
}
if (tcb_address & 2) {
tcb_address -= 2;
stacksize -= 2;
}
tcb_t *cb = (tcb_t *) tcb_address;
if (priority >= SCHED_PRIO_LEVELS) { if (priority >= SCHED_PRIO_LEVELS) {
return -EINVAL; return -EINVAL;
} }
#ifdef DEVELHELP
int total_stacksize = stacksize;
#endif
/* 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;
}
/* make room for the thread control block */
stacksize -= sizeof(tcb_t);
/* round down the stacksize to a multiple of tcb_t alignments (usually 16/32bit) */
stacksize -= stacksize % ALIGN_OF(tcb_t);
/* allocate our thread control block at the top of our stackspace */
tcb_t *cb = (tcb_t *) (stack + stacksize);
#ifdef DEVELHELP #ifdef DEVELHELP
if (flags & CREATE_STACKTEST) { if (flags & CREATE_STACKTEST) {
/* assign each int of the stack the value of it's address */ /* assign each int of the stack the value of it's address */
unsigned int *stackmax = (unsigned int *)((char *)stack + stacksize); uintptr_t *stackmax = (uintptr_t *) (stack + stacksize);
unsigned int *stackp = (unsigned int *)stack; uintptr_t *stackp = (uintptr_t *) stack;
while (stackp < stackmax) { while (stackp < stackmax) {
*stackp = (unsigned int)stackp; *stackp = (uintptr_t) stackp;
stackp++; stackp++;
} }
} }
else { else {
/* create stack guard */ /* create stack guard */
*stack = (unsigned int)stack; *stack = (uintptr_t) stack;
} }
#endif #endif