diff --git a/core/include/flags.h b/core/include/flags.h index 97da2efa8a..462133ef70 100644 --- a/core/include/flags.h +++ b/core/include/flags.h @@ -15,9 +15,9 @@ #ifndef _FLAGS_H #define _FLAGS_H -#define CREATE_WOUT_YIELD 4 #define CREATE_SLEEPING 1 -#define EXPECTS_REPLY 2 +#define AUTO_FREE 2 +#define CREATE_WOUT_YIELD 4 #define CREATE_STACKTEST 8 /** diff --git a/core/include/thread.h b/core/include/thread.h index 9f75470acb..d2a4c8e7e8 100644 --- a/core/include/thread.h +++ b/core/include/thread.h @@ -19,7 +19,9 @@ /** * @brief Creates a new thread. * This version will allocate it's stack itself using malloc. - * + * + * @param cb Address of preallocated tcb structure + * @param stack Lowest address of preallocated stack space * @param stacksize * @param flags Options: * YIELD: force context switch. @@ -32,7 +34,7 @@ * * @return returns <0 on error, pid of newly created task else. */ -int thread_create(int stacksize, char priority, int flags, void (*function) (void), const char* name); +int thread_create(tcb *cb, char *stack, int stacksize, char priority, int flags, void (*function) (void), const char* name); /** * @brief returns the status of a process. diff --git a/core/kernel_init.c b/core/kernel_init.c index cc6e273c2f..7de3b50e3d 100644 --- a/core/kernel_init.c +++ b/core/kernel_init.c @@ -41,6 +41,7 @@ volatile int lpm_prevent_sleep = 0; extern void main(void); extern void fk_switch_context_exit(void); + void fk_idle(void) { while(1) { if (lpm_prevent_sleep) { @@ -57,6 +58,12 @@ void fk_idle(void) { const char *main_name = "main"; const char *idle_name = "idle"; +static tcb main_tcb; +static char main_stack[KERNEL_CONF_STACKSIZE_MAIN]; + +static tcb idle_tcb; +static char idle_stack[KERNEL_CONF_STACKSIZE_IDLE]; + #ifdef MODULE_AUTO_INIT #define MAIN_FUNC auto_init #else @@ -70,11 +77,11 @@ void kernel_init(void) scheduler_init(); - if (thread_create(KERNEL_CONF_STACKSIZE_IDLE, PRIORITY_IDLE, CREATE_WOUT_YIELD | CREATE_STACKTEST, fk_idle, idle_name) < 0) { + if (thread_create(&main_tcb, main_stack, sizeof(main_stack), PRIORITY_IDLE, CREATE_WOUT_YIELD | CREATE_STACKTEST, fk_idle, idle_name) < 0) { printf("kernel_init(): error creating idle task.\n"); } - if (thread_create(KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN, CREATE_WOUT_YIELD | CREATE_STACKTEST, MAIN_FUNC, main_name) < 0) { + if (thread_create(&idle_tcb, idle_stack, sizeof(idle_stack), PRIORITY_MAIN, CREATE_WOUT_YIELD | CREATE_STACKTEST, MAIN_FUNC, main_name) < 0) { printf("kernel_init(): error creating main task.\n"); } diff --git a/core/scheduler.c b/core/scheduler.c index 279bb456a2..f391bb386a 100644 --- a/core/scheduler.c +++ b/core/scheduler.c @@ -149,12 +149,17 @@ extern void fk_switch_context_exit(void); void fk_task_exit(void) { DEBUG("fk_task_exit(): ending task %s...\n", fk_thread->name); + tcb* thread = (tcb*)fk_thread; dINT(); fk_threads[fk_thread->pid] = NULL; num_tasks--; - sched_set_status((tcb*)fk_thread, STATUS_STOPPED); + sched_set_status(thread, STATUS_STOPPED); + +// if ( thread->flags & AUTO_FREE ) { +// free(thread)->stack_start); +// free(thread); +// } - free(((tcb*)fk_thread)->stack_start); fk_thread = NULL; fk_switch_context_exit(); } diff --git a/core/thread.c b/core/thread.c index a9f4663267..b6895a6764 100644 --- a/core/thread.c +++ b/core/thread.c @@ -74,7 +74,7 @@ int fk_measure_stack_free(char* stack) { return space; } -int thread_create(int stacksize, char priority, int flags, void (*function) (void), const char* name) +int thread_create(tcb *cb, char *stack, int stacksize, char priority, int flags, void (*function) (void), const char* name) { /* stacksize must be a multitude of 4 for alignment and stacktest */ // assert( ((stacksize & 0x03) == 0) && (stacksize > 0) ); @@ -86,20 +86,6 @@ int thread_create(int stacksize, char priority, int flags, void (*function) (voi return -EINVAL; } - tcb *pd = (tcb*)malloc(sizeof(tcb)); - if ( pd == NULL) { - DEBUG("thread_create(): out of memory\n"); - return -ENOMEM; - } - - char *stack = (char*)malloc(stacksize); - if (stack==NULL) - { - DEBUG("thread_create(): out of memory\n"); - free (pd); - return -ENOMEM; - } - if (flags & CREATE_STACKTEST) { /* assign each int of the stack the value of it's address */ unsigned int *stackmax = (unsigned int*) ((char*)stack + stacksize); @@ -120,8 +106,8 @@ int thread_create(int stacksize, char priority, int flags, void (*function) (voi int pid = 0; while (pid < MAXTHREADS) { if (fk_threads[pid] == NULL) { - fk_threads[pid] = pd; - pd->pid = pid; + fk_threads[pid] = cb; + cb->pid = pid; break; } pid++; @@ -130,42 +116,39 @@ int thread_create(int stacksize, char priority, int flags, void (*function) (voi if (pid == MAXTHREADS) { DEBUG("thread_create(): too many threads!\n"); - free (pd); - free (stack); - if (! inISR()) { eINT(); } return -EOVERFLOW; } - pd->sp = fk_stack_init(function,stack+stacksize); - pd->stack_start = stack; - pd->stack_size = stacksize; + cb->sp = fk_stack_init(function,stack+stacksize); + cb->stack_start = stack; + cb->stack_size = stacksize; - pd->priority = priority; - pd->status = 0; + cb->priority = priority; + cb->status = 0; - pd->name = name; + cb->name = name; - pd->wait_data = NULL; + cb->wait_data = NULL; - pd->msg_queue.data = 0; - pd->msg_queue.priority = 0; - pd->msg_queue.next = NULL; + cb->msg_queue.data = 0; + cb->msg_queue.priority = 0; + cb->msg_queue.next = NULL; - pd->rq_entry.data = (unsigned int) pd; - pd->rq_entry.next = NULL; - pd->rq_entry.prev = NULL; + cb->rq_entry.data = (unsigned int) cb; + cb->rq_entry.next = NULL; + cb->rq_entry.prev = NULL; num_tasks++; - DEBUG("Created thread %s. PID: %u. Priority: %u.\n", name, pd->pid, priority); + DEBUG("Created thread %s. PID: %u. Priority: %u.\n", name, cb->pid, priority); if (flags & CREATE_SLEEPING) { - sched_set_status(pd, STATUS_SLEEPING); + sched_set_status(cb, STATUS_SLEEPING); } else { - sched_set_status(pd, STATUS_PENDING); + sched_set_status(cb, STATUS_PENDING); if (!(flags & CREATE_WOUT_YIELD)) { if (! inISR()) { eINT(); diff --git a/drivers/cc110x/cc1100_phy.c b/drivers/cc110x/cc1100_phy.c index 036792ee2e..08594d1e3c 100644 --- a/drivers/cc110x/cc1100_phy.c +++ b/drivers/cc110x/cc1100_phy.c @@ -94,11 +94,15 @@ static const pm_table_t handler_table; static const char *cc1100_event_handler_name = "cc1100_event_handler"; static mutex_t cc1100_mutex; volatile int cc1100_mutex_pid; -static uint16_t cc1100_event_handler_pid; -static void cc1100_event_handler_function(void); static swtimer_t cc1100_watch_dog; static uint64_t cc1100_watch_dog_period = 0; +static uint16_t cc1100_event_handler_pid; +static void cc1100_event_handler_function(void); + +static tcb event_handler_tcb; +static char event_handler_stack[KERNEL_CONF_STACKSIZE_MAIN]; + /*---------------------------------------------------------------------------*/ // Sequence number buffer management data structures /*---------------------------------------------------------------------------*/ @@ -188,7 +192,7 @@ void cc1100_phy_init() mutex_init(&cc1100_mutex); // Allocate event numbers and start cc1100 event process - cc1100_event_handler_pid = thread_create(2500, PRIORITY_CC1100, CREATE_STACKTEST, + cc1100_event_handler_pid = thread_create(&event_handler_tcb, event_handler_stack, sizeof(event_handler_stack), PRIORITY_CC1100, CREATE_STACKTEST, cc1100_event_handler_function, cc1100_event_handler_name); // Active watchdog for the first time diff --git a/projects/pingpong/main.c b/projects/pingpong/main.c index daf898b88d..62b720a55a 100644 --- a/projects/pingpong/main.c +++ b/projects/pingpong/main.c @@ -15,13 +15,16 @@ void second_thread(void) { } } +tcb second_thread_tcb; +char second_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; + int main(void) { printf("Hello world!\n"); msg m; - int pid = thread_create(KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong"); + int pid = thread_create(&second_thread_tcb, second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong"); m.content.value = 1; diff --git a/projects/pingpong_sync/main.c b/projects/pingpong_sync/main.c index 739ec3acf7..d0468ffeac 100644 --- a/projects/pingpong_sync/main.c +++ b/projects/pingpong_sync/main.c @@ -15,13 +15,16 @@ void second_thread(void) { } } +tcb second_thread_tcb; +char second_thread_stack[8192]; + int main(void) { printf("Hello world!\n"); msg m; - int pid = thread_create(8192, PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong"); + int pid = thread_create(&second_thread_tcb, second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong"); m.content.value = 1; diff --git a/projects/test_sleep/main.c b/projects/test_sleep/main.c index 32e05f90b7..75a67e8938 100644 --- a/projects/test_sleep/main.c +++ b/projects/test_sleep/main.c @@ -18,6 +18,8 @@ void second_thread(void) { } } +tcb second_thread_tcb; +char second_thread_stack[KERNEL_CONF_STACKSIZE_DEFAULT]; int main(void) { @@ -25,7 +27,7 @@ int main(void) printf("Hello world!\n"); - int pid = thread_create(KERNEL_CONF_STACKSIZE_DEFAULT, PRIORITY_MAIN-1, CREATE_STACKTEST | CREATE_SLEEPING | CREATE_WOUT_YIELD, second_thread, "sleeper"); + int pid = thread_create(&second_thread_tcb, second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_STACKTEST | CREATE_SLEEPING | CREATE_WOUT_YIELD, second_thread, "sleeper"); if (pid < 0) { puts("Error creating second_thread! Stopping test."); diff --git a/projects/test_thread_exit/main.c b/projects/test_thread_exit/main.c index 3f09c7284e..4646c2679a 100644 --- a/projects/test_thread_exit/main.c +++ b/projects/test_thread_exit/main.c @@ -9,8 +9,11 @@ void second_thread(void) { puts("2nd: running..."); } +tcb second_thread_tcb; +char second_thread_stack[8192]; + int main(void) { - int pid = thread_create(8192, PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "nr2"); + int pid = thread_create(&second_thread_tcb, second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "nr2"); puts("Main thread exiting..."); } diff --git a/sys/uart0.c b/sys/uart0.c index e6ad35bc38..c4656d6cf2 100644 --- a/sys/uart0.c +++ b/sys/uart0.c @@ -13,15 +13,19 @@ int uart0_handler_pid; static char buffer[UART0_BUFSIZE]; +static tcb uart0_thread_tcb; +static char uart0_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; + static void uart0_loop() { chardev_loop(&uart0_ringbuffer); } void board_uart0_init() { ringbuffer_init(&uart0_ringbuffer, buffer, UART0_BUFSIZE); - int pid = thread_create(KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN-1, CREATE_STACKTEST, uart0_loop, "uart0"); + int pid = thread_create(&uart0_thread_tcb, uart0_thread_stack, sizeof(uart0_thread_stack), PRIORITY_MAIN-1, CREATE_STACKTEST, uart0_loop, "uart0"); uart0_handler_pid = pid; puts("uart0_init() [OK]"); + printf("%i\n", sizeof(uart0_thread_stack)); } void uart0_handle_incoming(int c) {