From: kosmirror <kos...@us...> - 2025-08-05 03:05:05
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 3df833497711472b1b0d8546dfcdf5031d3c6fe7 (commit) from 5a91091e37421e9b15678dc086d111386f80fbbb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3df833497711472b1b0d8546dfcdf5031d3c6fe7 Author: Falco Girgis <gyr...@gm...> Date: Mon Aug 4 22:04:49 2025 -0500 Added flag for disabling TLS for individual threads. (#1045) I thought of a potential optimization the other day for how we handle TLS that could lead to some RAM savings... Say that we KNOW a thread is just some little simple task that is never accessing any TLS variables. If we were able to tell the kernel this is the case, we could avoid allocating a TLS segment that will never be used for that particular thread. ...and we already have two very good use-cases immediately within the kernel: the reaper and idle threads are not going to be accessing any TLS variables, yet they're getting their own copies of them allocated upon their creation. 1) Added THD_DISABLE_TLS to kthread_flags_t for signaling to the kernel that we're not using TLS for a particular thread. 2) Added kthread_attr_t::disable_tls flag for telling the kernel we don't want TLS when spawning a thread and passing its attributes. - notice it's the last member of the struct, so I don't break backwards compat, also it's the NEGATIVE so a 0 default value keeps the old functionality 3) Added checks to thread.c when creating and destroying threads to see whether THD_DISABLE_TLS is used, and if so, skip TLS segment processing. 4) Made the [reaper] and [idle] threads, by default, disable TLS. I validated these changes by rerunning my TLS test located in: examples/dreamcast/basic/threading/compiler_tls. Everything looks good! ----------------------------------------------------------------------- Summary of changes: include/kos/thread.h | 18 ++++++++++-------- kernel/thread/thread.c | 33 +++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/include/kos/thread.h b/include/kos/thread.h index 98457f43..581dc1af 100644 --- a/include/kos/thread.h +++ b/include/kos/thread.h @@ -4,7 +4,7 @@ Copyright (C) 2000, 2001, 2002, 2003 Megan Potter Copyright (C) 2009, 2010, 2016, 2023 Lawrence Sebald Copyright (C) 2023 Colton Pawielski - Copyright (C) 2023, 2024 Falco Girgis + Copyright (C) 2023, 2024, 2025 Falco Girgis */ @@ -128,11 +128,12 @@ LIST_HEAD(ktlist, kthread); @{ */ -#define THD_DEFAULTS 0 /**< \brief Defaults: no flags */ -#define THD_USER 1 /**< \brief Thread runs in user mode */ -#define THD_QUEUED 2 /**< \brief Thread is in the run queue */ -#define THD_DETACHED 4 /**< \brief Thread is detached */ -#define THD_OWNS_STACK 8 /**< \brief Thread manages stack lifetime */ +#define THD_DEFAULTS 0x0 /**< \brief Defaults: no flags */ +#define THD_USER 0x1 /**< \brief Thread runs in user mode */ +#define THD_QUEUED 0x2 /**< \brief Thread is in the run queue */ +#define THD_DETACHED 0x4 /**< \brief Thread is detached */ +#define THD_OWNS_STACK 0x8 /**< \brief Thread manages stack lifetime */ +#define THD_DISABLE_TLS 0x10 /**< \brief Thread does not use TLS variables */ /** @} */ /** \brief Kernel thread flags type */ @@ -150,8 +151,6 @@ typedef enum kthread_state { STATE_FINISHED = 0x0004 /**< \brief Finished execution */ } kthread_state_t; - - /** \brief Structure describing one running thread. Each thread has one of these structures assigned to it, which holds all the @@ -289,6 +288,9 @@ typedef struct kthread_attr { /** \brief Thread label. */ const char *label; + + /** \brief 1 if the thread doesn't use thread_local variables. */ + bool disable_tls; } kthread_attr_t; /** \brief kthread mode values diff --git a/kernel/thread/thread.c b/kernel/thread/thread.c index 374235a2..1a4b20f0 100644 --- a/kernel/thread/thread.c +++ b/kernel/thread/thread.c @@ -4,7 +4,7 @@ Copyright (C) 2000, 2001, 2002, 2003 Megan Potter Copyright (C) 2010, 2016, 2023 Lawrence Sebald Copyright (C) 2023 Colton Pawielski - Copyright (C) 2023, 2024 Falco Girgis + Copyright (C) 2023, 2024, 2025 Falco Girgis */ #include <assert.h> @@ -368,7 +368,7 @@ kthread_t *thd_create_ex(const kthread_attr_t *restrict attr, kthread_t *nt = NULL; tid_t tid; uint32_t params[4]; - kthread_attr_t real_attr = { false, THD_STACK_SIZE, NULL, PRIO_DEFAULT, NULL }; + kthread_attr_t real_attr = { false, THD_STACK_SIZE, NULL, PRIO_DEFAULT, NULL, false }; if(attr) real_attr = *attr; @@ -430,8 +430,10 @@ kthread_t *thd_create_ex(const kthread_attr_t *restrict attr, ((uint32_t)nt->stack) + nt->stack_size, (uint32_t)thd_birth, params, 0); - /* Create static TLS data */ - if(!arch_tls_setup_data(nt)) { + /* Create static TLS data if the thread hasn't disabled it. */ + if(real_attr.disable_tls) { + nt->flags |= THD_DISABLE_TLS; + } else if(!arch_tls_setup_data(nt)) { if(nt->flags & THD_OWNS_STACK) free(nt->stack); free(nt); @@ -526,8 +528,9 @@ int thd_destroy(kthread_t *thd) { if(thd->flags & THD_OWNS_STACK) free(thd->stack); - /* Free static TLS segment */ - arch_tls_destroy_data(thd); + /* Free static TLS segment (if it hasn't been disabled for the thread). */ + if(!(thd->flags & THD_DISABLE_TLS)) + arch_tls_destroy_data(thd); /* Free the thread */ free(thd); @@ -1004,17 +1007,19 @@ int thd_init(void) { }; const kthread_attr_t reaper_attr = { - .stack_size = sizeof(thd_reaper_stack), - .stack_ptr = thd_reaper_stack, - .prio = 1, - .label = "[reaper]" + .stack_size = sizeof(thd_reaper_stack), + .stack_ptr = thd_reaper_stack, + .prio = 1, + .label = "[reaper]" + .disable_tls = true }; const kthread_attr_t idle_attr = { - .stack_size = sizeof(thd_idle_stack), - .stack_ptr = thd_idle_stack, - .prio = PRIO_MAX, - .label = "[idle]" + .stack_size = sizeof(thd_idle_stack), + .stack_ptr = thd_idle_stack, + .prio = PRIO_MAX, + .label = "[idle]" + .disable_tls = true }; kthread_t *kern; hooks/post-receive -- A pseudo Operating System for the Dreamcast. |