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 <fredrik.holmqvist@gmail.com>
This commit is contained in:
parent
d13981d199
commit
a44af2ec16
@ -74,9 +74,9 @@ _thread_do_exit_work(void)
|
|||||||
|
|
||||||
tls_set(TLS_ON_EXIT_THREAD_SLOT, NULL);
|
tls_set(TLS_ON_EXIT_THREAD_SLOT, NULL);
|
||||||
|
|
||||||
__gRuntimeLoader->destroy_thread_tls();
|
|
||||||
|
|
||||||
__pthread_destroy_thread();
|
__pthread_destroy_thread();
|
||||||
|
|
||||||
|
__gRuntimeLoader->destroy_thread_tls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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_test : posix_spawn_pipe_test.c ;
|
||||||
SimpleTest posix_spawn_pipe_err : posix_spawn_pipe_err.c ;
|
SimpleTest posix_spawn_pipe_err : posix_spawn_pipe_err.c ;
|
||||||
SimpleTest pthread_attr_stack_test : pthread_attr_stack_test.cpp ;
|
SimpleTest pthread_attr_stack_test : pthread_attr_stack_test.cpp ;
|
||||||
|
SimpleTest thread_local_test : thread_local_test.cpp : [ TargetLibstdc++ ] ;
|
||||||
|
|
||||||
# XSI tests
|
# XSI tests
|
||||||
SimpleTest xsi_msg_queue_test1 : xsi_msg_queue_test1.cpp ;
|
SimpleTest xsi_msg_queue_test1 : xsi_msg_queue_test1.cpp ;
|
||||||
|
67
src/tests/system/libroot/posix/thread_local_test.cpp
Normal file
67
src/tests/system/libroot/posix/thread_local_test.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021, Jérôme Duval, jerome.duval@gmail.com.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user