From c329658b759936c722c178d75fa599be27fabfd2 Mon Sep 17 00:00:00 2001 From: Yuan Liu Date: Wed, 9 Nov 2016 16:39:57 -0800 Subject: [PATCH] lkl: Change tls key to a struct lkl_tls_key So the key can be a compound structure allowing flexible custom tls implementation Signed-off-by: Yuan Liu --- arch/lkl/include/uapi/asm/host_ops.h | 9 ++++---- arch/lkl/kernel/syscalls.c | 12 +++++------ tools/lkl/lib/nt-host.c | 32 ++++++++++++++++++---------- tools/lkl/lib/posix-host.c | 29 ++++++++++++++++++------- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/arch/lkl/include/uapi/asm/host_ops.h b/arch/lkl/include/uapi/asm/host_ops.h index 9e352d932131e5..0a30d77bd1b8d8 100644 --- a/arch/lkl/include/uapi/asm/host_ops.h +++ b/arch/lkl/include/uapi/asm/host_ops.h @@ -4,6 +4,7 @@ /* Defined in {posix,nt}-host.c */ struct lkl_mutex; struct lkl_sem; +struct lkl_tls_key; typedef unsigned long lkl_thread_t; struct lkl_jmp_buf { unsigned long buf[32]; @@ -93,10 +94,10 @@ struct lkl_host_operations { lkl_thread_t (*thread_self)(void); int (*thread_equal)(lkl_thread_t a, lkl_thread_t b); - int (*tls_alloc)(unsigned int *key, void (*destructor)(void *)); - int (*tls_free)(unsigned int key); - int (*tls_set)(unsigned int key, void *data); - void *(*tls_get)(unsigned int key); + struct lkl_tls_key *(*tls_alloc)(void (*destructor)(void *)); + void (*tls_free)(struct lkl_tls_key *key); + int (*tls_set)(struct lkl_tls_key *key, void *data); + void *(*tls_get)(struct lkl_tls_key *key); void* (*mem_alloc)(unsigned long); void (*mem_free)(void *); diff --git a/arch/lkl/kernel/syscalls.c b/arch/lkl/kernel/syscalls.c index ba733b8a8e4030..2a818d4911865c 100644 --- a/arch/lkl/kernel/syscalls.c +++ b/arch/lkl/kernel/syscalls.c @@ -88,7 +88,7 @@ static void del_host_task(void *arg) do_exit(0); } -static unsigned int task_key; +static struct lkl_tls_key *task_key; long lkl_syscall(long no, long *params) { @@ -121,19 +121,17 @@ long lkl_syscall(long no, long *params) int syscalls_init(void) { - int ret = 0; - snprintf(current->comm, sizeof(current->comm), "host0"); set_thread_flag(TIF_HOST_THREAD); host0 = current; if (lkl_ops->tls_alloc) { - ret = lkl_ops->tls_alloc(&task_key, del_host_task); - if (ret) - return ret; + task_key = lkl_ops->tls_alloc(del_host_task); + if (!task_key) + return -1; } - return ret; + return 0; } void syscalls_cleanup(void) diff --git a/tools/lkl/lib/nt-host.c b/tools/lkl/lib/nt-host.c index e34f01c0d395c1..f42cf884e2563b 100644 --- a/tools/lkl/lib/nt-host.c +++ b/tools/lkl/lib/nt-host.c @@ -17,6 +17,10 @@ struct lkl_sem { HANDLE sem; }; +struct lkl_tls_key { + DWORD key; +}; + static struct lkl_sem *sem_alloc(int count) { struct lkl_sem *sem = malloc(sizeof(struct lkl_sem)); @@ -122,28 +126,34 @@ static int thread_equal(lkl_thread_t a, lkl_thread_t b) return a == b; } -static int tls_alloc(unsigned int *key, void (*destructor)(void *)) +static struct lkl_tls_key *tls_alloc(void (*destructor)(void *)) { - *key = FlsAlloc((PFLS_CALLBACK_FUNCTION)destructor); - return *key == TLS_OUT_OF_INDEXES ? -1 : 0; + struct lkl_tls_key *ret = malloc(sizeof(struct lkl_tls_key)); + + ret->key = FlsAlloc((PFLS_CALLBACK_FUNCTION)destructor); + if (ret->key == TLS_OUT_OF_INDEXES) { + free(ret); + return -1; + } + return 0; } -static int tls_free(unsigned int key) +static void tls_free(struct lkl_tls_key *key) { /* setting to NULL first to prevent the callback from being called */ - if (!FlsSetValue(key, NULL)) - return -1; - return FlsFree(key) ? 0 : -1; + FlsSetValue(key->key, NULL); + FlsFree(key->key); + free(key); } -static int tls_set(unsigned int key, void *data) +static int tls_set(struct lkl_tls_key *key, void *data) { - return FlsSetValue(key, data) ? 0 : -1; + return FlsSetValue(key->key, data) ? 0 : -1; } -static void *tls_get(unsigned int key) +static void *tls_get(struct lkl_tls_key *key) { - return FlsGetValue(key); + return FlsGetValue(key->key); } diff --git a/tools/lkl/lib/posix-host.c b/tools/lkl/lib/posix-host.c index 9300aa0b1b6f6d..33c577ba339e0d 100644 --- a/tools/lkl/lib/posix-host.c +++ b/tools/lkl/lib/posix-host.c @@ -49,6 +49,10 @@ struct lkl_sem { #endif /* _POSIX_SEMAPHORES */ }; +struct lkl_tls_key { + pthread_key_t key; +}; + #define WARN_UNLESS(exp) do { \ if (exp < 0) \ lkl_printf("%s: %s\n", #exp, strerror(errno)); \ @@ -216,24 +220,33 @@ static int thread_equal(lkl_thread_t a, lkl_thread_t b) return pthread_equal(a, b); } -static int tls_alloc(unsigned int *key, void (*destructor)(void *)) +static struct lkl_tls_key *tls_alloc(void (*destructor)(void *)) { - return pthread_key_create((pthread_key_t *)key, destructor); + struct lkl_tls_key *ret = malloc(sizeof(struct lkl_tls_key)); + + if (WARN_PTHREAD(pthread_key_create(&ret->key, destructor))) { + free(ret); + return NULL; + } + return ret; } -static int tls_free(unsigned int key) +static void tls_free(struct lkl_tls_key *key) { - return pthread_key_delete(key); + WARN_PTHREAD(pthread_key_delete(key->key)); + free(key); } -static int tls_set(unsigned int key, void *data) +static int tls_set(struct lkl_tls_key *key, void *data) { - return pthread_setspecific(key, data); + if (WARN_PTHREAD(pthread_setspecific(key->key, data))) + return -1; + return 0; } -static void *tls_get(unsigned int key) +static void *tls_get(struct lkl_tls_key *key) { - return pthread_getspecific(key); + return pthread_getspecific(key->key); } static unsigned long long time_ns(void)