Merge pull request #1268 from Kijewski/issue-1267
core: align stack on a 32bit boundary
This commit is contained in:
commit
c11a575ec0
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user