(root)/
glibc-2.38/
sysdeps/
s390/
nptl/
tls.h
       1  /* Definition for thread-local data handling.  NPTL/s390 version.
       2     Copyright (C) 2003-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #ifndef _TLS_H
      20  #define _TLS_H	1
      21  
      22  #include <dl-sysdep.h>
      23  #ifndef __ASSEMBLER__
      24  # include <stdbool.h>
      25  # include <stddef.h>
      26  # include <stdint.h>
      27  # include <stdlib.h>
      28  # include <list.h>
      29  # include <kernel-features.h>
      30  # include <dl-dtv.h>
      31  
      32  typedef struct
      33  {
      34    void *tcb;		/* Pointer to the TCB.  Not necessary the
      35  			   thread descriptor used by libpthread.  */
      36    dtv_t *dtv;
      37    void *self;		/* Pointer to the thread descriptor.  */
      38    int multiple_threads;
      39    uintptr_t sysinfo;
      40    uintptr_t stack_guard;
      41    int gscope_flag;
      42    int __glibc_reserved1;
      43    /* GCC split stack support.  */
      44    void *__private_ss;
      45  } tcbhead_t;
      46  
      47  # ifndef __s390x__
      48  #  define TLS_MULTIPLE_THREADS_IN_TCB 1
      49  # endif
      50  
      51  #else /* __ASSEMBLER__ */
      52  # include <tcb-offsets.h>
      53  #endif
      54  
      55  
      56  /* Alignment requirement for the stack.  For IA-32 this is governed by
      57     the SSE memory functions.  */
      58  #define STACK_ALIGN	16
      59  
      60  #ifndef __ASSEMBLER__
      61  /* Get system call information.  */
      62  # include <sysdep.h>
      63  
      64  /* This is the size of the initial TCB.  Can't be just sizeof (tcbhead_t),
      65     because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole
      66     struct pthread even when not linked with -lpthread.  */
      67  # define TLS_INIT_TCB_SIZE sizeof (struct pthread)
      68  
      69  /* This is the size of the TCB.  */
      70  # define TLS_TCB_SIZE sizeof (struct pthread)
      71  
      72  /* The TCB can have any size and the memory following the address the
      73     thread pointer points to is unspecified.  Allocate the TCB there.  */
      74  # define TLS_TCB_AT_TP	1
      75  # define TLS_DTV_AT_TP	0
      76  
      77  /* Get the thread descriptor definition.  */
      78  # include <nptl/descr.h>
      79  
      80  
      81  /* Install the dtv pointer.  The pointer passed is to the element with
      82     index -1 which contain the length.  */
      83  #  define INSTALL_DTV(descr, dtvp) \
      84    ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
      85  
      86  /* Install new dtv for current thread.  */
      87  #  define INSTALL_NEW_DTV(dtv) \
      88    (((tcbhead_t *) __builtin_thread_pointer ())->dtv = (dtv))
      89  
      90  /* Return dtv of given thread descriptor.  */
      91  #  define GET_DTV(descr) \
      92    (((tcbhead_t *) (descr))->dtv)
      93  
      94  #if defined NEED_DL_SYSINFO && defined SHARED
      95  # define INIT_SYSINFO \
      96    _head->sysinfo = GLRO(dl_sysinfo)
      97  #else
      98  # define INIT_SYSINFO
      99  #endif
     100  
     101  /* Code to initially initialize the thread pointer.  This might need
     102     special attention since 'errno' is not yet available and if the
     103     operation can cause a failure 'errno' must not be touched.  */
     104  # define TLS_INIT_TP(thrdescr) \
     105    ({ void *_thrdescr = (thrdescr);					      \
     106       tcbhead_t *_head = _thrdescr;					      \
     107  									      \
     108       _head->tcb = _thrdescr;						      \
     109       /* For now the thread descriptor is at the same address.  */	      \
     110       _head->self = _thrdescr;						      \
     111       /* New syscall handling support.  */				      \
     112       INIT_SYSINFO;							      \
     113  									      \
     114      __builtin_set_thread_pointer (_thrdescr);				      \
     115      true;								      \
     116    })
     117  
     118  /* Value passed to 'clone' for initialization of the thread register.  */
     119  # define TLS_DEFINE_INIT_TP(tp, pd) void *tp = (pd)
     120  
     121  /* Return the address of the dtv for the current thread.  */
     122  #  define THREAD_DTV() \
     123    (((tcbhead_t *) __builtin_thread_pointer ())->dtv)
     124  
     125  /* Return the thread descriptor for the current thread.  */
     126  # define THREAD_SELF ((struct pthread *) __builtin_thread_pointer ())
     127  
     128  /* Magic for libthread_db to know how to do THREAD_SELF.  */
     129  # define DB_THREAD_SELF REGISTER (32, 32, 18 * 4, 0) \
     130  			REGISTER (64, __WORDSIZE, 18 * 8, 0)
     131  
     132  # include <tcb-access.h>
     133  
     134  /* Set the stack guard field in TCB head.  */
     135  #define THREAD_SET_STACK_GUARD(value) \
     136    do									      \
     137     {									      \
     138       __asm__ __volatile__ ("" : : : "a0", "a1");			      \
     139       THREAD_SETMEM (THREAD_SELF, header.stack_guard, value);		      \
     140     }									      \
     141    while (0)
     142  #define THREAD_COPY_STACK_GUARD(descr) \
     143    ((descr)->header.stack_guard						      \
     144     = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
     145  
     146  /* s390 doesn't have HP_TIMING_*, so for the time being
     147     use stack_guard as pointer_guard.  */
     148  #define THREAD_GET_POINTER_GUARD() \
     149    THREAD_GETMEM (THREAD_SELF, header.stack_guard)
     150  #define THREAD_SET_POINTER_GUARD(value)	((void) (value))
     151  #define THREAD_COPY_POINTER_GUARD(descr)
     152  
     153  /* Get and set the global scope generation counter in struct pthread.  */
     154  #define THREAD_GSCOPE_FLAG_UNUSED 0
     155  #define THREAD_GSCOPE_FLAG_USED   1
     156  #define THREAD_GSCOPE_FLAG_WAIT   2
     157  #define THREAD_GSCOPE_RESET_FLAG() \
     158    do									     \
     159      { int __res								     \
     160  	= atomic_exchange_release (&THREAD_SELF->header.gscope_flag,	     \
     161  			       THREAD_GSCOPE_FLAG_UNUSED);		     \
     162        if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
     163  	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
     164      }									     \
     165    while (0)
     166  #define THREAD_GSCOPE_SET_FLAG() \
     167    do									     \
     168      {									     \
     169        THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
     170        atomic_write_barrier ();						     \
     171      }									     \
     172    while (0)
     173  
     174  #endif /* __ASSEMBLER__ */
     175  
     176  #endif	/* tls.h */