From d9373f57721279b65794de4342c583e613eeef5f Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Mon, 13 Jan 2014 19:50:49 +0100 Subject: [PATCH 1/5] Added a way to reserve thread local memory --- core/include/tcb.h | 2 ++ core/include/thread.h | 32 ++++++++++++++++++++++++++++++++ core/thread.c | 25 +++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/core/include/tcb.h b/core/include/tcb.h index 6b186f51595e..67616331b17f 100644 --- a/core/include/tcb.h +++ b/core/include/tcb.h @@ -55,6 +55,8 @@ typedef struct tcb_t { cib_t msg_queue; msg_t *msg_array; + char *lcoal_mem; + const char *name; char *stack_start; int stack_size; diff --git a/core/include/thread.h b/core/include/thread.h index 39c973703a34..d365aeec94f8 100644 --- a/core/include/thread.h +++ b/core/include/thread.h @@ -17,6 +17,7 @@ * * @author Freie Universität Berlin, Computer Systems & Telematics * @author Kaspar Schleiser + * @author Hauke Petersen */ #ifndef __THREAD_H @@ -49,6 +50,37 @@ */ int thread_create(char *stack, int stacksize, char priority, int flags, void (*function) (void), const char *name); + +/** + * @brief Reserve a given amount of memory on the top of the stack as thread local memory + * + * Always reserve the full number size of bytes or none, do not try to fit as many bytes as possible into the stack + * + * @param stack Lowest address of preallocated stack space + * @param stacksize + * @param localmemsize number of bytes to reserve for the thread-local memory (taken from given stack memory) + * @param flags Options: + * YIELD: force context switch. + * CREATE_SLEEPING: set new thread to sleeping state, thread must be woken up manually. + * CREATE_STACKTEST: initialize stack with values needed for stack overflow testing. + * + * @param priority Priority of newly created thread. Lower number means higher + * priority. 0 means highest possible priority. Lowest priority is + * PRIORITY_IDLE-1, usually 30. + * + * @return returns <0 on error, pid of newly created task else. + */ +int thread_create_with_local_mem(char *stack, int stacksize, int localmemsize, char priority, + int flags, void (*function) (void), const char *name); + +/** + * @brief Acces the threads local memory + * + * @param[in] pid pid of the thread to access + * @return pointer to the threads local memory, 0 on error + */ +char *thread_get_local_mem(int pid); + /** * @brief returns the status of a process. * @return STATUS_NOT_FOUND if pid is unknown diff --git a/core/thread.c b/core/thread.c index 339d25030696..22d68b88bc39 100644 --- a/core/thread.c +++ b/core/thread.c @@ -14,6 +14,7 @@ * @brief Threading implementation * * @author Kaspar Schleiser + * @author Hauke Petersen * * @} */ @@ -199,6 +200,8 @@ int thread_create(char *stack, int stacksize, char priority, int flags, void (*f cb->rq_entry.next = NULL; cb->rq_entry.prev = NULL; + cb->local_mem = NULL; + cb->name = name; cb->wait_data = NULL; @@ -237,3 +240,25 @@ int thread_create(char *stack, int stacksize, char priority, int flags, void (*f return pid; } + +int thread_create_with_local_mem(char *stack, int stacksize, int localmemsize, char priority, + int flags, void (*function) (void), const char *name) +{ + // the thread-local memory is put in the beginning + char *localmam = stack; + stack += localmemsize; + stacksize -= localmemsize; + + // create the thread + int pid = thread_create(stack, stacksize, priority, flags, function, name); + + // set pointer to local mem + sched_threads[pid]->local_mem = localmem; + + return pid; +} + +char *thread_get_local_mem(int pid) +{ + return sched_threads[pid]->local_mem; +} From c1f7450ef77c4e6c606a267103b6c92ab5bc66dd Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Wed, 15 Jan 2014 14:13:18 +0100 Subject: [PATCH 2/5] Fixed typo in tcb.h --- core/include/tcb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/tcb.h b/core/include/tcb.h index 67616331b17f..e25bc02dde68 100644 --- a/core/include/tcb.h +++ b/core/include/tcb.h @@ -55,7 +55,7 @@ typedef struct tcb_t { cib_t msg_queue; msg_t *msg_array; - char *lcoal_mem; + char *local_mem; const char *name; char *stack_start; From d084b96a2ccbbdec063d4804061bb5450bb09d9d Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Wed, 15 Jan 2014 14:46:00 +0100 Subject: [PATCH 3/5] Thread local memory V2 --- core/include/tcb.h | 3 +-- core/thread.c | 20 +++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/core/include/tcb.h b/core/include/tcb.h index e25bc02dde68..4a0a59ff83ba 100644 --- a/core/include/tcb.h +++ b/core/include/tcb.h @@ -39,6 +39,7 @@ #define STATUS_SEND_BLOCKED (0x0080) #define STATUS_REPLY_BLOCKED (0x0100) #define STATUS_TIMER_WAITING (0x0200) +#define STATUS_LOCAL_MEMORY (0x8000) ///< flag is set if thread-local memory was reserved typedef struct tcb_t { char *sp; @@ -55,8 +56,6 @@ typedef struct tcb_t { cib_t msg_queue; msg_t *msg_array; - char *local_mem; - const char *name; char *stack_start; int stack_size; diff --git a/core/thread.c b/core/thread.c index 22d68b88bc39..65d2117c9c79 100644 --- a/core/thread.c +++ b/core/thread.c @@ -244,21 +244,15 @@ int thread_create(char *stack, int stacksize, char priority, int flags, void (*f int thread_create_with_local_mem(char *stack, int stacksize, int localmemsize, char priority, int flags, void (*function) (void), const char *name) { - // the thread-local memory is put in the beginning - char *localmam = stack; - stack += localmemsize; - stacksize -= localmemsize; - - // create the thread - int pid = thread_create(stack, stacksize, priority, flags, function, name); - - // set pointer to local mem - sched_threads[pid]->local_mem = localmem; - - return pid; + return thread_create(stack, stacksize - localmemsize, priority, flags, function, name); } char *thread_get_local_mem(int pid) { - return sched_threads[pid]->local_mem; + if (sched_threads[pid]->status & STATUS_LOCAL_MEMORY) { + return sched_threads[pid]->stack_start + sched_threads[pid]->stack_size; + } else { + return NULL; + } + } From 70bc6beb9c4b6a6458905198dd7dec427a81ebf2 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Wed, 15 Jan 2014 14:50:37 +0100 Subject: [PATCH 4/5] Fixed thread.c - new setting the STATUS_LOCAL_MEMORY flag - not trying to set the tcb->local_mem field anymore --- core/thread.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/thread.c b/core/thread.c index 65d2117c9c79..3553c2529346 100644 --- a/core/thread.c +++ b/core/thread.c @@ -200,8 +200,6 @@ int thread_create(char *stack, int stacksize, char priority, int flags, void (*f cb->rq_entry.next = NULL; cb->rq_entry.prev = NULL; - cb->local_mem = NULL; - cb->name = name; cb->wait_data = NULL; @@ -244,7 +242,9 @@ int thread_create(char *stack, int stacksize, char priority, int flags, void (*f int thread_create_with_local_mem(char *stack, int stacksize, int localmemsize, char priority, int flags, void (*function) (void), const char *name) { - return thread_create(stack, stacksize - localmemsize, priority, flags, function, name); + int pid = thread_create(stack, stacksize - localmemsize, priority, flags, function, name); + sched_threads[pid]->status |= STATUS_LOCAL_MEMORY; + return pid; } char *thread_get_local_mem(int pid) From 6c140ec8fda0f9929d0b5bc5a68891eff2ef379b Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Wed, 15 Jan 2014 17:19:30 +0100 Subject: [PATCH 5/5] Remove guard for getting local memory pointer --- core/include/tcb.h | 1 - core/include/thread.h | 10 ++++++++-- core/thread.c | 11 ++--------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/core/include/tcb.h b/core/include/tcb.h index 4a0a59ff83ba..6b186f51595e 100644 --- a/core/include/tcb.h +++ b/core/include/tcb.h @@ -39,7 +39,6 @@ #define STATUS_SEND_BLOCKED (0x0080) #define STATUS_REPLY_BLOCKED (0x0100) #define STATUS_TIMER_WAITING (0x0200) -#define STATUS_LOCAL_MEMORY (0x8000) ///< flag is set if thread-local memory was reserved typedef struct tcb_t { char *sp; diff --git a/core/include/thread.h b/core/include/thread.h index d365aeec94f8..a296a66495e8 100644 --- a/core/include/thread.h +++ b/core/include/thread.h @@ -54,7 +54,8 @@ int thread_create(char *stack, int stacksize, char priority, int flags, void (*f /** * @brief Reserve a given amount of memory on the top of the stack as thread local memory * - * Always reserve the full number size of bytes or none, do not try to fit as many bytes as possible into the stack + * CAUTION: The function will not check wether there is actually enough space on the stack + * memory for the local memory. So it is up to the caller to make sure that stacksize >> localmemsize. * * @param stack Lowest address of preallocated stack space * @param stacksize @@ -75,9 +76,14 @@ int thread_create_with_local_mem(char *stack, int stacksize, int localmemsize, c /** * @brief Acces the threads local memory + * + * CAUTION: This function should only be called when the thread identified pid was created + * using thread_create_with_local_mem(), otherwise an invalid pointer poiting to how-knows-what + * will be returned and something hard to debug will break! * * @param[in] pid pid of the thread to access - * @return pointer to the threads local memory, 0 on error + * @return pointer to the threads local memory, random invalid memory location if + * no local memory was defined */ char *thread_get_local_mem(int pid); diff --git a/core/thread.c b/core/thread.c index 3553c2529346..2a04dbf25baa 100644 --- a/core/thread.c +++ b/core/thread.c @@ -242,17 +242,10 @@ int thread_create(char *stack, int stacksize, char priority, int flags, void (*f int thread_create_with_local_mem(char *stack, int stacksize, int localmemsize, char priority, int flags, void (*function) (void), const char *name) { - int pid = thread_create(stack, stacksize - localmemsize, priority, flags, function, name); - sched_threads[pid]->status |= STATUS_LOCAL_MEMORY; - return pid; + return thread_create(stack, stacksize - localmemsize, priority, flags, function, name); } char *thread_get_local_mem(int pid) { - if (sched_threads[pid]->status & STATUS_LOCAL_MEMORY) { - return sched_threads[pid]->stack_start + sched_threads[pid]->stack_size; - } else { - return NULL; - } - + return sched_threads[pid]->stack_start + sched_threads[pid]->stack_size; }