htl: Implement some support for TLS_DTV_AT_TP

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-ID: <20240323173301.151066-19-bugaevc@gmail.com>
This commit is contained in:
Sergey Bugaev 2024-03-23 20:32:59 +03:00 committed by Samuel Thibault
parent a4273efa21
commit dc1a77269c
3 changed files with 25 additions and 2 deletions

View File

@ -177,7 +177,9 @@ __pthread_create_internal (struct __pthread **thread,
err = ENOMEM; err = ENOMEM;
goto failed_thread_tls_alloc; goto failed_thread_tls_alloc;
} }
#if TLS_TCB_AT_TP
pthread->tcb->tcb = pthread->tcb; pthread->tcb->tcb = pthread->tcb;
#endif
/* And initialize the rest of the machine context. This may include /* And initialize the rest of the machine context. This may include
additional machine- and system-specific initializations that additional machine- and system-specific initializations that

View File

@ -20,6 +20,18 @@
#include <pthread.h> #include <pthread.h>
#include <htl/pt-internal.h> #include <htl/pt-internal.h>
static inline int *
thread_gscope_flag (struct __pthread *t)
{
#if TLS_TCB_AT_TP
return &t->tcb->gscope_flag;
#elif TLS_DTV_AT_TP
return &((tcbprehead_t *) t->tcb - 1)->gscope_flag;
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
}
void void
__thread_gscope_wait (void) __thread_gscope_wait (void)
{ {
@ -33,10 +45,10 @@ __thread_gscope_wait (void)
for (i = 0; i < GL (dl_pthread_num_threads); ++i) for (i = 0; i < GL (dl_pthread_num_threads); ++i)
{ {
t = GL (dl_pthread_threads[i]); t = GL (dl_pthread_threads[i]);
if (t == NULL || t->tcb->gscope_flag == THREAD_GSCOPE_FLAG_UNUSED) if (t == NULL || *thread_gscope_flag (t) == THREAD_GSCOPE_FLAG_UNUSED)
continue; continue;
gscope_flagp = &t->tcb->gscope_flag; gscope_flagp = thread_gscope_flag (t);
/* We have to wait until this thread is done with the global /* We have to wait until this thread is done with the global
scope. First tell the thread that we are waiting and scope. First tell the thread that we are waiting and

View File

@ -100,7 +100,16 @@ _init_routine (void *stack)
to the new stack. Pretend it wasn't allocated so that it remains to the new stack. Pretend it wasn't allocated so that it remains
valid if the main thread terminates. */ valid if the main thread terminates. */
thread->stack = 0; thread->stack = 0;
#if TLS_TCB_AT_TP
thread->tcb = THREAD_SELF; thread->tcb = THREAD_SELF;
#elif TLS_DTV_AT_TP
/* Assuming THREAD_SELF is implemented as subtracting TLS_PRE_TCB_SIZE
from the value of a thread pointer regsiter, this should optimize
down to simply reading that register. */
thread->tcb = (tcbhead_t *) (((char *) THREAD_SELF) + TLS_PRE_TCB_SIZE);
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
#ifndef PAGESIZE #ifndef PAGESIZE
__pthread_default_attr.__guardsize = __vm_page_size; __pthread_default_attr.__guardsize = __vm_page_size;