htl: Initialize ___pthread_self early

When using jemalloc, malloc() needs to use TSD, while libpthread
initialization needs malloc(). Having ___pthread_self set early to some
static storage allows TSD to work early, thus allowing jemalloc and
libpthread to initialize together.

This incidentaly simplifies __pthread_enable/disable_asynccancel and
__pthread_self, now that ___pthread_self is always initialized.
This commit is contained in:
Samuel Thibault 2023-08-08 12:19:29 +02:00
parent 644aa127b9
commit 53da64d1cf
3 changed files with 15 additions and 17 deletions

View File

@ -25,10 +25,6 @@ int __pthread_enable_asynccancel (void)
struct __pthread *p = _pthread_self (); struct __pthread *p = _pthread_self ();
int oldtype; int oldtype;
if (___pthread_self == NULL)
/* We are not initialized yet, we can't be cancelled anyway. */
return PTHREAD_CANCEL_DEFERRED;
__pthread_mutex_lock (&p->cancel_lock); __pthread_mutex_lock (&p->cancel_lock);
oldtype = p->cancel_type; oldtype = p->cancel_type;
p->cancel_type = PTHREAD_CANCEL_ASYNCHRONOUS; p->cancel_type = PTHREAD_CANCEL_ASYNCHRONOUS;
@ -43,10 +39,6 @@ void __pthread_disable_asynccancel (int oldtype)
{ {
struct __pthread *p = _pthread_self (); struct __pthread *p = _pthread_self ();
if (___pthread_self == NULL)
/* We are not initialized yet, we can't be cancelled anyway. */
return;
__pthread_mutex_lock (&p->cancel_lock); __pthread_mutex_lock (&p->cancel_lock);
p->cancel_type = oldtype; p->cancel_type = oldtype;
__pthread_mutex_unlock (&p->cancel_lock); __pthread_mutex_unlock (&p->cancel_lock);

View File

@ -24,15 +24,7 @@
pthread_t pthread_t
__pthread_self (void) __pthread_self (void)
{ {
struct __pthread *self; struct __pthread *self = _pthread_self ();
if (___pthread_self == NULL)
/* We are not initialized yet, we are the first thread. */
return 1;
self = _pthread_self ();
assert (self != NULL);
return self->thread; return self->thread;
} }

View File

@ -26,6 +26,10 @@
#include <pt-internal.h> #include <pt-internal.h>
#include <pthreadP.h> #include <pthreadP.h>
/* Initial thread structure used temporarily during initialization, so various
* functions can already work at least basically. */
static struct __pthread init_thread;
static void static void
reset_pthread_total (void) reset_pthread_total (void)
{ {
@ -47,6 +51,10 @@ _init_routine (void *stack)
/* Already initialized */ /* Already initialized */
return; return;
/* Initialize early thread structure. */
init_thread.thread = 1;
___pthread_self = &init_thread;
/* Initialize the library. */ /* Initialize the library. */
___pthread_init (); ___pthread_init ();
@ -74,6 +82,12 @@ _init_routine (void *stack)
__pthread_default_attr.__guardsize = __vm_page_size; __pthread_default_attr.__guardsize = __vm_page_size;
#endif #endif
/* Copy over the thread-specific state */
assert (!init_thread.thread_specifics);
memcpy (&thread->static_thread_specifics,
&init_thread.static_thread_specifics,
sizeof (thread->static_thread_specifics));
___pthread_self = thread; ___pthread_self = thread;
/* Decrease the number of threads, to take into account that the /* Decrease the number of threads, to take into account that the