From a8661c1fb81a035ebfdf134393eec4c476a7b51b Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 30 Dec 2015 09:51:03 +0100 Subject: [PATCH] add a platform independent function to manage the TLS --- hermit/arch/x86/include/asm/processor.h | 18 ++++++++++++++++++ hermit/kernel/main.c | 4 ++-- hermit/kernel/tasks.c | 8 ++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hermit/arch/x86/include/asm/processor.h b/hermit/arch/x86/include/asm/processor.h index 09ef6f1ec..b77e8fca0 100644 --- a/hermit/arch/x86/include/asm/processor.h +++ b/hermit/arch/x86/include/asm/processor.h @@ -477,6 +477,24 @@ extern func_read_fsgs readgs; extern func_write_fsgs writefs; extern func_write_fsgs writegs; +/** @brife Get thread local storage + * + * Helper function to get the TLS of the current task + */ +static inline size_t get_tls(void) +{ + return readfs(); +} + +/** @brief Set thread local storage + * + * Helper function to set the TLS of the current task + */ +static inline void set_tls(size_t addr) +{ + writefs(addr); +} + /** @brief Flush cache * * The wbinvd asm instruction which stands for "Write back and invalidate" diff --git a/hermit/kernel/main.c b/hermit/kernel/main.c index b6c226b37..f17d3dcef 100644 --- a/hermit/kernel/main.c +++ b/hermit/kernel/main.c @@ -290,9 +290,9 @@ static int initd(void* arg) memcpy((void*) tls_addr, (void*) curr_task->tls_addr, curr_task->tls_size); // set fs register to the TLS segment - writefs((size_t) tls_addr); + set_tls((size_t) tls_addr); kprintf("Task %d set fs to 0x%zx\n", curr_task->id, tls_addr); - } else writefs(0); // no TLS => clear fs register + } else set_tls(0); // no TLS => clear fs register //init_rcce(); diff --git a/hermit/kernel/tasks.c b/hermit/kernel/tasks.c index 53cf60717..baa666733 100644 --- a/hermit/kernel/tasks.c +++ b/hermit/kernel/tasks.c @@ -222,6 +222,7 @@ void finish_task_switch(void) void NORETURN do_exit(int arg) { task_t* curr_task = per_core(current_task); + void* tls_addr = NULL; const uint32_t core_id = CORE_ID; kprintf("Terminate task: %u, return value %d\n", curr_task->id, arg); @@ -237,6 +238,13 @@ void NORETURN do_exit(int arg) readyqueues[core_id].nr_tasks--; spinlock_irqsave_unlock(&readyqueues[core_id].lock); + // do we need to release the TLS? + tls_addr = (void*)get_tls(); + if (tls_addr) { + kprintf("Release TLS %p\n", tls_addr); + kfree(tls_addr); + } + curr_task->status = TASK_FINISHED; reschedule();