summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2018-08-12 16:20:05 +0200
committerRichard Braun <rbraun@sceen.net>2018-08-12 17:12:31 +0200
commit6cd5e45e802df7c2cb7ad0f4061812897aa56cf2 (patch)
tree056a8bb0869056c819e74a838dba1752daa6c58a
parent56c5702a8c6b192a21f031747357eaa6170cec72 (diff)
kern/thread: make thread-specific data optional
-rw-r--r--kern/Kconfig10
-rw-r--r--kern/thread.c35
-rw-r--r--kern/thread.h12
-rw-r--r--kern/thread_i.h11
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.