summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2014-04-27 18:02:08 +0200
committerRichard Braun <rbraun@sceen.net>2014-04-27 18:02:08 +0200
commitc8278303cc26f78da5072f0a457fa33271170f79 (patch)
tree2869afbba7d04cabd0735f38cd577a260a89b99c
parent7c1352c7fd91bf71604d88753e624cc0996a3ccc (diff)
kern/thread: implement thread-specific data
-rw-r--r--kern/thread.c26
-rw-r--r--kern/thread.h45
2 files changed, 71 insertions, 0 deletions
diff --git a/kern/thread.c b/kern/thread.c
index e9cb0c27..ec722898 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -99,6 +99,7 @@
#include <kern/string.h>
#include <kern/task.h>
#include <kern/thread.h>
+#include <machine/atomic.h>
#include <machine/cpu.h>
#include <machine/mb.h>
#include <machine/pmap.h>
@@ -272,6 +273,16 @@ static struct {
#define thread_ts_highest_round (thread_ts_highest_round_struct.value)
/*
+ * Number of TSD keys actually allocated.
+ */
+static unsigned int thread_nr_keys __read_mostly;
+
+/*
+ * Destructors installed for each key.
+ */
+static thread_dtor_fn_t thread_dtors[THREAD_KEYS_MAX] __read_mostly;
+
+/*
* List of threads pending for destruction by the reaper.
*/
static struct mutex thread_reap_lock;
@@ -1443,6 +1454,7 @@ thread_init(struct thread *thread, void *stack, const struct thread_attr *attr,
thread->sched_class = thread_policy_table[attr->policy];
cpumap_copy(&thread->cpumap, cpumap);
thread_init_sched(thread, attr->priority);
+ memset(thread->tsd, 0, sizeof(thread->tsd));
thread->task = task;
thread->stack = stack;
strlcpy(thread->name, attr->name, sizeof(thread->name));
@@ -1936,3 +1948,17 @@ thread_tick(void)
spinlock_unlock(&runq->lock);
}
+
+void
+thread_key_create(unsigned int *keyp, thread_dtor_fn_t dtor)
+{
+ unsigned int key;
+
+ key = atomic_fetchadd_uint(&thread_nr_keys, 1);
+
+ if (key >= THREAD_KEYS_MAX)
+ panic("thread: maximum number of keys exceeded");
+
+ thread_dtors[key] = dtor;
+ *keyp = key;
+}
diff --git a/kern/thread.h b/kern/thread.h
index fa8d2eca..97c4f041 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -131,6 +131,11 @@ struct thread_ts_data {
};
/*
+ * Maximum number of thread-specific data keys.
+ */
+#define THREAD_KEYS_MAX 4
+
+/*
* Thread structure.
*
* Thread members are normally protected by the lock of the run queue they're
@@ -163,6 +168,9 @@ struct thread {
struct thread_ts_data ts_data;
};
+ /* Thread-specific data */
+ void *tsd[THREAD_KEYS_MAX];
+
/* Read-only members */
struct task *task;
struct list task_node;
@@ -428,4 +436,41 @@ thread_preempt_disable(void)
barrier();
}
+/*
+ * Type for thread-specific data destructor.
+ */
+typedef void (*thread_dtor_fn_t)(void *);
+
+/*
+ * Allocate a TSD key.
+ *
+ * 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);
+
+/*
+ * Set the pointer associated with a key for the calling thread.
+ */
+static inline void
+thread_set_specific(unsigned int key, void *ptr)
+{
+ struct thread *self;
+
+ self = thread_self();
+ self->tsd[key] = ptr;
+}
+
+/*
+ * Return the pointer associated with a key for the calling thread.
+ */
+static inline void *
+thread_get_specific(unsigned int key)
+{
+ struct thread *self;
+
+ self = thread_self();
+ return self->tsd[key];
+}
+
#endif /* _KERN_THREAD_H */