diff options
author | Richard Braun <rbraun@sceen.net> | 2018-08-12 16:20:05 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2018-08-12 17:12:31 +0200 |
commit | 6cd5e45e802df7c2cb7ad0f4061812897aa56cf2 (patch) | |
tree | 056a8bb0869056c819e74a838dba1752daa6c58a | |
parent | 56c5702a8c6b192a21f031747357eaa6170cec72 (diff) |
kern/thread: make thread-specific data optional
-rw-r--r-- | kern/Kconfig | 10 | ||||
-rw-r--r-- | kern/thread.c | 35 | ||||
-rw-r--r-- | kern/thread.h | 12 | ||||
-rw-r--r-- | kern/thread_i.h | 11 |
4 files changed, 49 insertions, 19 deletions
diff --git a/kern/Kconfig b/kern/Kconfig index ea61937f..782b0ec4 100644 --- a/kern/Kconfig +++ b/kern/Kconfig @@ -94,6 +94,16 @@ config THREAD_STACK_GUARD If unsure, disable. +config THREAD_MAX_TSD_KEYS + int "Maximum number of thread-specific data (TSD) keys" + default 0 + ---help--- + This option is intended for application code embedded in the kernel + which may use TSD. The kernel itself never uses them. A value of 0 + completely disables TSD support. + + If unsure, set to 0. + config PERFMON def_bool n diff --git a/kern/thread.c b/kern/thread.c index b2e360b9..4800fa84 100644 --- a/kern/thread.c +++ b/kern/thread.c @@ -330,15 +330,20 @@ static struct { #define thread_fs_highest_round (thread_fs_highest_round_struct.value) +#if CONFIG_THREAD_MAX_TSD_KEYS != 0 + /* - * Number of TSD keys actually allocated. + * Number of allocated TSD keys. */ -static unsigned int thread_nr_keys __read_mostly; +static unsigned int thread_nr_tsd_keys __read_mostly; /* * Destructors installed for each key. */ -static thread_dtor_fn_t thread_dtors[THREAD_KEYS_MAX] __read_mostly; +static thread_tsd_dtor_fn_t thread_tsd_dtors[CONFIG_THREAD_MAX_TSD_KEYS] + __read_mostly; + +#endif /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */ /* * Number of processors which have requested the scheduler to run. @@ -1724,7 +1729,9 @@ thread_init_booter(unsigned int cpu) thread_set_user_sched_class(booter, THREAD_SCHED_CLASS_IDLE); thread_set_user_priority(booter, 0); thread_reset_real_priority(booter); +#if CONFIG_THREAD_MAX_TSD_KEYS memset(booter->tsd, 0, sizeof(booter->tsd)); +#endif /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */ booter->task = task_get_kernel_task(); snprintf(booter->name, sizeof(booter->name), THREAD_KERNEL_PREFIX "thread_boot/%u", cpu); @@ -1777,6 +1784,7 @@ thread_main(void (*fn)(void *), void *arg) thread_exit(); } +#if CONFIG_THREAD_MAX_TSD_KEYS != 0 static void thread_destroy_tsd(struct thread *thread) { @@ -1785,8 +1793,8 @@ thread_destroy_tsd(struct thread *thread) i = 0; - while (i < thread_nr_keys) { - if ((thread->tsd[i] == NULL) || (thread_dtors[i] == NULL)) { + while (i < thread_nr_tsd_keys) { + if ((thread->tsd[i] == NULL) || (thread_tsd_dtors[i] == NULL)) { i++; continue; } @@ -1797,13 +1805,16 @@ thread_destroy_tsd(struct thread *thread) */ ptr = thread->tsd[i]; thread->tsd[i] = NULL; - thread_dtors[i](ptr); + thread_tsd_dtors[i](ptr); if (thread->tsd[i] == NULL) { i++; } } } +#else /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */ +#define thread_destroy_tsd(thread) ((void)(thread)) +#endif /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */ static int thread_init(struct thread *thread, void *stack, @@ -1852,7 +1863,9 @@ thread_init(struct thread *thread, void *stack, thread_set_user_sched_class(thread, thread_policy_to_class(attr->policy)); thread_set_user_priority(thread, attr->priority); thread_reset_real_priority(thread); +#if CONFIG_THREAD_MAX_TSD_KEYS != 0 memset(thread->tsd, 0, sizeof(thread->tsd)); +#endif /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */ thread->join_waiter = NULL; spinlock_init(&thread->join_lock); thread->terminating = false; @@ -2923,20 +2936,22 @@ thread_propagate_priority(void) turnstile_td_propagate_priority(thread_turnstile_td(thread)); } +#if CONFIG_THREAD_MAX_TSD_KEYS != 0 void -thread_key_create(unsigned int *keyp, thread_dtor_fn_t dtor) +thread_key_create(unsigned int *keyp, thread_tsd_dtor_fn_t dtor) { unsigned int key; - key = atomic_fetch_add(&thread_nr_keys, 1, ATOMIC_RELAXED); + key = atomic_fetch_add(&thread_nr_tsd_keys, 1, ATOMIC_RELAXED); - if (key >= THREAD_KEYS_MAX) { + if (key >= ARRAY_SIZE(thread_tsd_dtors)) { panic("thread: maximum number of keys exceeded"); } - thread_dtors[key] = dtor; + thread_tsd_dtors[key] = dtor; *keyp = key; } +#endif /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */ unsigned int thread_cpu(const struct thread *thread) diff --git a/kern/thread.h b/kern/thread.h index 49d8b109..787fc083 100644 --- a/kern/thread.h +++ b/kern/thread.h @@ -664,9 +664,15 @@ thread_rcu_reader(struct thread *thread) } /* + * Thread-specific data functions. + */ + +#if CONFIG_THREAD_MAX_TSD_KEYS != 0 + +/* * Type for thread-specific data destructor. */ -typedef void (*thread_dtor_fn_t)(void *); +typedef void (*thread_tsd_dtor_fn_t)(void *); /* * Allocate a TSD key. @@ -674,7 +680,7 @@ typedef void (*thread_dtor_fn_t)(void *); * If not NULL, the destructor is called on thread destruction on the pointer * associated with the allocated key. */ -void thread_key_create(unsigned int *keyp, thread_dtor_fn_t dtor); +void thread_key_create(unsigned int *keyp, thread_tsd_dtor_fn_t dtor); /* * Set the pointer associated with a key for the given thread. @@ -712,6 +718,8 @@ thread_get_specific(unsigned int key) return thread_tsd_get(thread_self(), key); } +#endif /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */ + static inline const char * thread_name(const struct thread *thread) { diff --git a/kern/thread_i.h b/kern/thread_i.h index 9c9a705b..57871cd0 100644 --- a/kern/thread_i.h +++ b/kern/thread_i.h @@ -66,11 +66,6 @@ struct thread_fs_data { }; /* - * Maximum number of thread-specific data keys. - */ -#define THREAD_KEYS_MAX 4 - -/* * Thread structure. * * Threads don't have their own lock. Instead, the associated run queue @@ -152,9 +147,11 @@ struct thread { /* * Thread-specific data. * - * TODO Make optional. + * TSD are reserved for application use. */ - void *tsd[THREAD_KEYS_MAX]; +#if CONFIG_THREAD_MAX_TSD_KEYS != 0 + void *tsd[CONFIG_THREAD_MAX_TSD_KEYS]; +#endif /* CONFIG_THREAD_MAX_TSD_KEYS != 0 */ /* * Members related to termination. |