From a44af2ec16c64ea229a66d6ce0123d646110a2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Fri, 5 Mar 2021 09:04:06 +0100 Subject: [PATCH] libroot: call thread exit hooks before destroying tls Change-Id: Ide2799ccf8620e42650a8f45177fb5fac4f09696 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3762 Reviewed-by: Fredrik Holmqvist --- src/system/libroot/os/thread.c | 4 +- src/tests/system/libroot/posix/Jamfile | 1 + .../libroot/posix/thread_local_test.cpp | 67 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/tests/system/libroot/posix/thread_local_test.cpp diff --git a/src/system/libroot/os/thread.c b/src/system/libroot/os/thread.c index c5a5e7cb94..c278e660f1 100644 --- a/src/system/libroot/os/thread.c +++ b/src/system/libroot/os/thread.c @@ -74,9 +74,9 @@ _thread_do_exit_work(void) tls_set(TLS_ON_EXIT_THREAD_SLOT, NULL); - __gRuntimeLoader->destroy_thread_tls(); - __pthread_destroy_thread(); + + __gRuntimeLoader->destroy_thread_tls(); } diff --git a/src/tests/system/libroot/posix/Jamfile b/src/tests/system/libroot/posix/Jamfile index a6d2056944..8974881f00 100644 --- a/src/tests/system/libroot/posix/Jamfile +++ b/src/tests/system/libroot/posix/Jamfile @@ -45,6 +45,7 @@ SimpleTest posix_spawn_redir_err : posix_spawn_redir_err.c ; SimpleTest posix_spawn_pipe_test : posix_spawn_pipe_test.c ; SimpleTest posix_spawn_pipe_err : posix_spawn_pipe_err.c ; SimpleTest pthread_attr_stack_test : pthread_attr_stack_test.cpp ; +SimpleTest thread_local_test : thread_local_test.cpp : [ TargetLibstdc++ ] ; # XSI tests SimpleTest xsi_msg_queue_test1 : xsi_msg_queue_test1.cpp ; diff --git a/src/tests/system/libroot/posix/thread_local_test.cpp b/src/tests/system/libroot/posix/thread_local_test.cpp new file mode 100644 index 0000000000..19d1e3ac8d --- /dev/null +++ b/src/tests/system/libroot/posix/thread_local_test.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2021, Jérôme Duval, jerome.duval@gmail.com. + * Distributed under the terms of the MIT License. + */ +#include +#include +#include +#include +#include + +#define CYCLES 2 + + +class MyClass +{ +public: + MyClass() { i=0; printf("MyClass() called() %p\n", this); } + ~MyClass() { printf("~MyClass() called() %d %p\n", i, this); } + + void Touch() { i++; printf("Touch() called() %d %p\n", i, this); } + +private: + int j; + int i; +}; + +thread_local MyClass myClass1; +thread_local MyClass myClass2; + +void* threadFn(void* id_ptr) +{ + int thread_id = *(int*)id_ptr; + + for (int i = 0; i < CYCLES; ++i) { + int wait_sec = 1; + sleep(wait_sec); + myClass1.Touch(); + myClass2.Touch(); + } + + return NULL; +} + + +int thread_local_test(int count) +{ + pthread_t ids[count]; + int short_ids[count]; + + srand(time(NULL)); + + for (int i = 0; i < count; i++) { + short_ids[i] = i; + pthread_create(&ids[i], NULL, threadFn, &short_ids[i]); + } + + for (int i = 0; i < count; i++) + pthread_join(ids[i], NULL); + + return 0; +} + + +int main() +{ + thread_local_test(1); +}