ensure that thread dtv pointer is never null to optimize __tls_get_addr
[musl] / src / thread / pthread_self.c
1 #include "pthread_impl.h"
2
3 static struct pthread *main_thread = &(struct pthread){0};
4
5 /* pthread_key_create.c overrides this */
6 static const void *dummy[1] = { 0 };
7 weak_alias(dummy, __pthread_tsd_main);
8
9 static int init_main_thread()
10 {
11         __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
12                 SIGPT_SET, 0, _NSIG/8);
13         if (__set_thread_area(TP_ADJ(main_thread)) < 0) return -1;
14         main_thread->canceldisable = libc.canceldisable;
15         main_thread->tsd = (void **)__pthread_tsd_main;
16         main_thread->errno_ptr = __errno_location();
17         main_thread->self = main_thread;
18         main_thread->tid = main_thread->pid =
19                 __syscall(SYS_set_tid_address, &main_thread->tid);
20         if (!main_thread->dtv)
21                 main_thread->dtv = (void *)dummy;
22         libc.main_thread = main_thread;
23         return 0;
24 }
25
26 pthread_t __pthread_self_def()
27 {
28         static int init, failed;
29         if (!init) {
30                 if (failed) return 0;
31                 if (init_main_thread() < 0) failed = 1;
32                 if (failed) return 0;
33                 init = 1;
34         }
35         return __pthread_self();
36 }
37
38 weak_alias(__pthread_self_def, pthread_self);
39 weak_alias(__pthread_self_def, __pthread_self_init);
40
41 void *__install_initial_tls(void *p)
42 {
43         main_thread = p;
44         return __pthread_self_def();
45 }