Blame sysdeps/x86_64/nptl/tls.h

Packit Service 82fcde
/* Definition for thread-local data handling.  nptl/x86_64 version.
Packit Service 82fcde
   Copyright (C) 2002-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef _TLS_H
Packit Service 82fcde
#define _TLS_H	1
Packit Service 82fcde
Packit Service 82fcde
#ifndef __ASSEMBLER__
Packit Service 82fcde
# include <asm/prctl.h>	/* For ARCH_SET_FS.  */
Packit Service 82fcde
# include <stdbool.h>
Packit Service 82fcde
# include <stddef.h>
Packit Service 82fcde
# include <stdint.h>
Packit Service 82fcde
# include <stdlib.h>
Packit Service 82fcde
# include <sysdep.h>
Packit Service 82fcde
# include <libc-pointer-arith.h> /* For cast_to_integer.  */
Packit Service 82fcde
# include <kernel-features.h>
Packit Service 82fcde
# include <dl-dtv.h>
Packit Service 82fcde
Packit Service 82fcde
/* Replacement type for __m128 since this file is included by ld.so,
Packit Service 82fcde
   which is compiled with -mno-sse.  It must not change the alignment
Packit Service 82fcde
   of rtld_savespace_sse.  */
Packit Service 82fcde
typedef struct
Packit Service 82fcde
{
Packit Service 82fcde
  int i[4];
Packit Service 82fcde
} __128bits;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
typedef struct
Packit Service 82fcde
{
Packit Service 82fcde
  void *tcb;		/* Pointer to the TCB.  Not necessarily the
Packit Service 82fcde
			   thread descriptor used by libpthread.  */
Packit Service 82fcde
  dtv_t *dtv;
Packit Service 82fcde
  void *self;		/* Pointer to the thread descriptor.  */
Packit Service 82fcde
  int multiple_threads;
Packit Service 82fcde
  int gscope_flag;
Packit Service 82fcde
  uintptr_t sysinfo;
Packit Service 82fcde
  uintptr_t stack_guard;
Packit Service 82fcde
  uintptr_t pointer_guard;
Packit Service 82fcde
  unsigned long int vgetcpu_cache[2];
Packit Service 82fcde
  /* Bit 0: X86_FEATURE_1_IBT.
Packit Service 82fcde
     Bit 1: X86_FEATURE_1_SHSTK.
Packit Service 82fcde
   */
Packit Service 82fcde
  unsigned int feature_1;
Packit Service 82fcde
  int __glibc_unused1;
Packit Service 82fcde
  /* Reservation of some values for the TM ABI.  */
Packit Service 82fcde
  void *__private_tm[4];
Packit Service 82fcde
  /* GCC split stack support.  */
Packit Service 82fcde
  void *__private_ss;
Packit Service 82fcde
  /* The lowest address of shadow stack,  */
Packit Service 82fcde
  unsigned long long int ssp_base;
Packit Service 82fcde
  /* Must be kept even if it is no longer used by glibc since programs,
Packit Service 82fcde
     like AddressSanitizer, depend on the size of tcbhead_t.  */
Packit Service 82fcde
  __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32)));
Packit Service 82fcde
Packit Service 82fcde
  void *__padding[8];
Packit Service 82fcde
} tcbhead_t;
Packit Service 82fcde
Packit Service 82fcde
# ifdef __ILP32__
Packit Service 82fcde
/* morestack.S in libgcc uses offset 0x40 to access __private_ss,   */
Packit Service 82fcde
_Static_assert (offsetof (tcbhead_t, __private_ss) == 0x40,
Packit Service 82fcde
		"offset of __private_ss != 0x40");
Packit Service 82fcde
/* NB: ssp_base used to be "long int __glibc_reserved2", which was
Packit Service 82fcde
   changed from 32 bits to 64 bits.  Make sure that the offset of the
Packit Service 82fcde
   next field, __glibc_unused2, is unchanged.  */
Packit Service 82fcde
_Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x60,
Packit Service 82fcde
		"offset of __glibc_unused2 != 0x60");
Packit Service 82fcde
# else
Packit Service 82fcde
/* morestack.S in libgcc uses offset 0x70 to access __private_ss,   */
Packit Service 82fcde
_Static_assert (offsetof (tcbhead_t, __private_ss) == 0x70,
Packit Service 82fcde
		"offset of __private_ss != 0x70");
Packit Service 82fcde
_Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
Packit Service 82fcde
		"offset of __glibc_unused2 != 0x80");
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
#else /* __ASSEMBLER__ */
Packit Service 82fcde
# include <tcb-offsets.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Alignment requirement for the stack.  */
Packit Service 82fcde
#define STACK_ALIGN	16
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#ifndef __ASSEMBLER__
Packit Service 82fcde
/* Get system call information.  */
Packit Service 82fcde
# include <sysdep.h>
Packit Service 82fcde
Packit Service 82fcde
#ifndef LOCK_PREFIX
Packit Service 82fcde
# ifdef UP
Packit Service 82fcde
#  define LOCK_PREFIX	/* nothing */
Packit Service 82fcde
# else
Packit Service 82fcde
#  define LOCK_PREFIX	"lock;"
Packit Service 82fcde
# endif
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* This is the size of the initial TCB.  Can't be just sizeof (tcbhead_t),
Packit Service 82fcde
   because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole
Packit Service 82fcde
   struct pthread even when not linked with -lpthread.  */
Packit Service 82fcde
# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
Packit Service 82fcde
Packit Service 82fcde
/* Alignment requirements for the initial TCB.  */
Packit Service 82fcde
# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
Packit Service 82fcde
Packit Service 82fcde
/* This is the size of the TCB.  */
Packit Service 82fcde
# define TLS_TCB_SIZE sizeof (struct pthread)
Packit Service 82fcde
Packit Service 82fcde
/* Alignment requirements for the TCB.  */
Packit Service 82fcde
# define TLS_TCB_ALIGN __alignof__ (struct pthread)
Packit Service 82fcde
Packit Service 82fcde
/* The TCB can have any size and the memory following the address the
Packit Service 82fcde
   thread pointer points to is unspecified.  Allocate the TCB there.  */
Packit Service 82fcde
# define TLS_TCB_AT_TP	1
Packit Service 82fcde
# define TLS_DTV_AT_TP	0
Packit Service 82fcde
Packit Service 82fcde
/* Get the thread descriptor definition.  */
Packit Service 82fcde
# include <nptl/descr.h>
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Install the dtv pointer.  The pointer passed is to the element with
Packit Service 82fcde
   index -1 which contain the length.  */
Packit Service 82fcde
# define INSTALL_DTV(descr, dtvp) \
Packit Service 82fcde
  ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
Packit Service 82fcde
Packit Service 82fcde
/* Install new dtv for current thread.  */
Packit Service 82fcde
# define INSTALL_NEW_DTV(dtvp) \
Packit Service 82fcde
  ({ struct pthread *__pd;						      \
Packit Service 82fcde
     THREAD_SETMEM (__pd, header.dtv, (dtvp)); })
Packit Service 82fcde
Packit Service 82fcde
/* Return dtv of given thread descriptor.  */
Packit Service 82fcde
# define GET_DTV(descr) \
Packit Service 82fcde
  (((tcbhead_t *) (descr))->dtv)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Code to initially initialize the thread pointer.  This might need
Packit Service 82fcde
   special attention since 'errno' is not yet available and if the
Packit Service 82fcde
   operation can cause a failure 'errno' must not be touched.
Packit Service 82fcde
Packit Service 82fcde
   We have to make the syscall for both uses of the macro since the
Packit Service 82fcde
   address might be (and probably is) different.  */
Packit Service 82fcde
# define TLS_INIT_TP(thrdescr) \
Packit Service 82fcde
  ({ void *_thrdescr = (thrdescr);					      \
Packit Service 82fcde
     tcbhead_t *_head = _thrdescr;					      \
Packit Service 82fcde
     int _result;							      \
Packit Service 82fcde
									      \
Packit Service 82fcde
     _head->tcb = _thrdescr;						      \
Packit Service 82fcde
     /* For now the thread descriptor is at the same address.  */	      \
Packit Service 82fcde
     _head->self = _thrdescr;						      \
Packit Service 82fcde
									      \
Packit Service 82fcde
     /* It is a simple syscall to set the %fs value for the thread.  */	      \
Packit Service 82fcde
     asm volatile ("syscall"						      \
Packit Service 82fcde
		   : "=a" (_result)					      \
Packit Service 82fcde
		   : "0" ((unsigned long int) __NR_arch_prctl),		      \
Packit Service 82fcde
		     "D" ((unsigned long int) ARCH_SET_FS),		      \
Packit Service 82fcde
		     "S" (_thrdescr)					      \
Packit Service 82fcde
		   : "memory", "cc", "r11", "cx");			      \
Packit Service 82fcde
									      \
Packit Service 82fcde
    _result ? "cannot set %fs base address for thread-local storage" : 0;     \
Packit Service 82fcde
  })
Packit Service 82fcde
Packit Service 82fcde
# define TLS_DEFINE_INIT_TP(tp, pd) void *tp = (pd)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Return the address of the dtv for the current thread.  */
Packit Service 82fcde
# define THREAD_DTV() \
Packit Service 82fcde
  ({ struct pthread *__pd;						      \
Packit Service 82fcde
     THREAD_GETMEM (__pd, header.dtv); })
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Return the thread descriptor for the current thread.
Packit Service 82fcde
Packit Service 82fcde
   The contained asm must *not* be marked volatile since otherwise
Packit Service 82fcde
   assignments like
Packit Service 82fcde
	pthread_descr self = thread_self();
Packit Service 82fcde
   do not get optimized away.  */
Packit Service 82fcde
# define THREAD_SELF \
Packit Service 82fcde
  ({ struct pthread *__self;						      \
Packit Service 82fcde
     asm ("mov %%fs:%c1,%0" : "=r" (__self)				      \
Packit Service 82fcde
	  : "i" (offsetof (struct pthread, header.self)));	 	      \
Packit Service 82fcde
     __self;})
Packit Service 82fcde
Packit Service 82fcde
/* Magic for libthread_db to know how to do THREAD_SELF.  */
Packit Service 82fcde
# define DB_THREAD_SELF_INCLUDE  <sys/reg.h> /* For the FS constant.  */
Packit Service 82fcde
# define DB_THREAD_SELF CONST_THREAD_AREA (64, FS)
Packit Service 82fcde
Packit Service 82fcde
/* Read member of the thread descriptor directly.  */
Packit Service 82fcde
# define THREAD_GETMEM(descr, member) \
Packit Service 82fcde
  ({ __typeof (descr->member) __value;					      \
Packit Service 82fcde
     if (sizeof (__value) == 1)						      \
Packit Service 82fcde
       asm volatile ("movb %%fs:%P2,%b0"				      \
Packit Service 82fcde
		     : "=q" (__value)					      \
Packit Service 82fcde
		     : "0" (0), "i" (offsetof (struct pthread, member)));     \
Packit Service 82fcde
     else if (sizeof (__value) == 4)					      \
Packit Service 82fcde
       asm volatile ("movl %%fs:%P1,%0"					      \
Packit Service 82fcde
		     : "=r" (__value)					      \
Packit Service 82fcde
		     : "i" (offsetof (struct pthread, member)));	      \
Packit Service 82fcde
     else								      \
Packit Service 82fcde
       {								      \
Packit Service 82fcde
	 if (sizeof (__value) != 8)					      \
Packit Service 82fcde
	   /* There should not be any value with a size other than 1,	      \
Packit Service 82fcde
	      4 or 8.  */						      \
Packit Service 82fcde
	   abort ();							      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	 asm volatile ("movq %%fs:%P1,%q0"				      \
Packit Service 82fcde
		       : "=r" (__value)					      \
Packit Service 82fcde
		       : "i" (offsetof (struct pthread, member)));	      \
Packit Service 82fcde
       }								      \
Packit Service 82fcde
     __value; })
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
Packit Service 82fcde
# define THREAD_GETMEM_NC(descr, member, idx) \
Packit Service 82fcde
  ({ __typeof (descr->member[0]) __value;				      \
Packit Service 82fcde
     if (sizeof (__value) == 1)						      \
Packit Service 82fcde
       asm volatile ("movb %%fs:%P2(%q3),%b0"				      \
Packit Service 82fcde
		     : "=q" (__value)					      \
Packit Service 82fcde
		     : "0" (0), "i" (offsetof (struct pthread, member[0])),   \
Packit Service 82fcde
		       "r" (idx));					      \
Packit Service 82fcde
     else if (sizeof (__value) == 4)					      \
Packit Service 82fcde
       asm volatile ("movl %%fs:%P1(,%q2,4),%0"				      \
Packit Service 82fcde
		     : "=r" (__value)					      \
Packit Service 82fcde
		     : "i" (offsetof (struct pthread, member[0])), "r" (idx));\
Packit Service 82fcde
     else								      \
Packit Service 82fcde
       {								      \
Packit Service 82fcde
	 if (sizeof (__value) != 8)					      \
Packit Service 82fcde
	   /* There should not be any value with a size other than 1,	      \
Packit Service 82fcde
	      4 or 8.  */						      \
Packit Service 82fcde
	   abort ();							      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	 asm volatile ("movq %%fs:%P1(,%q2,8),%q0"			      \
Packit Service 82fcde
		       : "=r" (__value)					      \
Packit Service 82fcde
		       : "i" (offsetof (struct pthread, member[0])),	      \
Packit Service 82fcde
			 "r" (idx));					      \
Packit Service 82fcde
       }								      \
Packit Service 82fcde
     __value; })
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Loading addresses of objects on x86-64 needs to be treated special
Packit Service 82fcde
   when generating PIC code.  */
Packit Service 82fcde
#ifdef __pic__
Packit Service 82fcde
# define IMM_MODE "nr"
Packit Service 82fcde
#else
Packit Service 82fcde
# define IMM_MODE "ir"
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Set member of the thread descriptor directly.  */
Packit Service 82fcde
# define THREAD_SETMEM(descr, member, value) \
Packit Service 82fcde
  ({ if (sizeof (descr->member) == 1)					      \
Packit Service 82fcde
       asm volatile ("movb %b0,%%fs:%P1" :				      \
Packit Service 82fcde
		     : "iq" (value),					      \
Packit Service 82fcde
		       "i" (offsetof (struct pthread, member)));	      \
Packit Service 82fcde
     else if (sizeof (descr->member) == 4)				      \
Packit Service 82fcde
       asm volatile ("movl %0,%%fs:%P1" :				      \
Packit Service 82fcde
		     : IMM_MODE (value),				      \
Packit Service 82fcde
		       "i" (offsetof (struct pthread, member)));	      \
Packit Service 82fcde
     else								      \
Packit Service 82fcde
       {								      \
Packit Service 82fcde
	 if (sizeof (descr->member) != 8)				      \
Packit Service 82fcde
	   /* There should not be any value with a size other than 1,	      \
Packit Service 82fcde
	      4 or 8.  */						      \
Packit Service 82fcde
	   abort ();							      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	 asm volatile ("movq %q0,%%fs:%P1" :				      \
Packit Service 82fcde
		       : IMM_MODE ((uint64_t) cast_to_integer (value)),	      \
Packit Service 82fcde
			 "i" (offsetof (struct pthread, member)));	      \
Packit Service 82fcde
       }})
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
Packit Service 82fcde
# define THREAD_SETMEM_NC(descr, member, idx, value) \
Packit Service 82fcde
  ({ if (sizeof (descr->member[0]) == 1)				      \
Packit Service 82fcde
       asm volatile ("movb %b0,%%fs:%P1(%q2)" :				      \
Packit Service 82fcde
		     : "iq" (value),					      \
Packit Service 82fcde
		       "i" (offsetof (struct pthread, member[0])),	      \
Packit Service 82fcde
		       "r" (idx));					      \
Packit Service 82fcde
     else if (sizeof (descr->member[0]) == 4)				      \
Packit Service 82fcde
       asm volatile ("movl %0,%%fs:%P1(,%q2,4)" :			      \
Packit Service 82fcde
		     : IMM_MODE (value),				      \
Packit Service 82fcde
		       "i" (offsetof (struct pthread, member[0])),	      \
Packit Service 82fcde
		       "r" (idx));					      \
Packit Service 82fcde
     else								      \
Packit Service 82fcde
       {								      \
Packit Service 82fcde
	 if (sizeof (descr->member[0]) != 8)				      \
Packit Service 82fcde
	   /* There should not be any value with a size other than 1,	      \
Packit Service 82fcde
	      4 or 8.  */						      \
Packit Service 82fcde
	   abort ();							      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	 asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" :			      \
Packit Service 82fcde
		       : IMM_MODE ((uint64_t) cast_to_integer (value)),	      \
Packit Service 82fcde
			 "i" (offsetof (struct pthread, member[0])),	      \
Packit Service 82fcde
			 "r" (idx));					      \
Packit Service 82fcde
       }})
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Atomic compare and exchange on TLS, returning old value.  */
Packit Service 82fcde
# define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \
Packit Service 82fcde
  ({ __typeof (descr->member) __ret;					      \
Packit Service 82fcde
     __typeof (oldval) __old = (oldval);				      \
Packit Service 82fcde
     if (sizeof (descr->member) == 4)					      \
Packit Service 82fcde
       asm volatile (LOCK_PREFIX "cmpxchgl %2, %%fs:%P3"		      \
Packit Service 82fcde
		     : "=a" (__ret)					      \
Packit Service 82fcde
		     : "0" (__old), "r" (newval),			      \
Packit Service 82fcde
		       "i" (offsetof (struct pthread, member)));	      \
Packit Service 82fcde
     else								      \
Packit Service 82fcde
       /* Not necessary for other sizes in the moment.  */		      \
Packit Service 82fcde
       abort ();							      \
Packit Service 82fcde
     __ret; })
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Atomic logical and.  */
Packit Service 82fcde
# define THREAD_ATOMIC_AND(descr, member, val) \
Packit Service 82fcde
  (void) ({ if (sizeof ((descr)->member) == 4)				      \
Packit Service 82fcde
	      asm volatile (LOCK_PREFIX "andl %1, %%fs:%P0"		      \
Packit Service 82fcde
			    :: "i" (offsetof (struct pthread, member)),	      \
Packit Service 82fcde
			       "ir" (val));				      \
Packit Service 82fcde
	    else							      \
Packit Service 82fcde
	      /* Not necessary for other sizes in the moment.  */	      \
Packit Service 82fcde
	      abort (); })
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Atomic set bit.  */
Packit Service 82fcde
# define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
Packit Service 82fcde
  (void) ({ if (sizeof ((descr)->member) == 4)				      \
Packit Service 82fcde
	      asm volatile (LOCK_PREFIX "orl %1, %%fs:%P0"		      \
Packit Service 82fcde
			    :: "i" (offsetof (struct pthread, member)),	      \
Packit Service 82fcde
			       "ir" (1 << (bit)));			      \
Packit Service 82fcde
	    else							      \
Packit Service 82fcde
	      /* Not necessary for other sizes in the moment.  */	      \
Packit Service 82fcde
	      abort (); })
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Set the stack guard field in TCB head.  */
Packit Service 82fcde
# define THREAD_SET_STACK_GUARD(value) \
Packit Service 82fcde
    THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)
Packit Service 82fcde
# define THREAD_COPY_STACK_GUARD(descr) \
Packit Service 82fcde
    ((descr)->header.stack_guard					      \
Packit Service 82fcde
     = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Set the pointer guard field in the TCB head.  */
Packit Service 82fcde
# define THREAD_SET_POINTER_GUARD(value) \
Packit Service 82fcde
  THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
Packit Service 82fcde
# define THREAD_COPY_POINTER_GUARD(descr) \
Packit Service 82fcde
  ((descr)->header.pointer_guard					      \
Packit Service 82fcde
   = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Get and set the global scope generation counter in the TCB head.  */
Packit Service 82fcde
# define THREAD_GSCOPE_IN_TCB      1
Packit Service 82fcde
# define THREAD_GSCOPE_FLAG_UNUSED 0
Packit Service 82fcde
# define THREAD_GSCOPE_FLAG_USED   1
Packit Service 82fcde
# define THREAD_GSCOPE_FLAG_WAIT   2
Packit Service 82fcde
# define THREAD_GSCOPE_RESET_FLAG() \
Packit Service 82fcde
  do									      \
Packit Service 82fcde
    { int __res;							      \
Packit Service 82fcde
      asm volatile ("xchgl %0, %%fs:%P1"				      \
Packit Service 82fcde
		    : "=r" (__res)					      \
Packit Service 82fcde
		    : "i" (offsetof (struct pthread, header.gscope_flag)),    \
Packit Service 82fcde
		      "0" (THREAD_GSCOPE_FLAG_UNUSED));			      \
Packit Service 82fcde
      if (__res == THREAD_GSCOPE_FLAG_WAIT)				      \
Packit Service 82fcde
	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);    \
Packit Service 82fcde
    }									      \
Packit Service 82fcde
  while (0)
Packit Service 82fcde
# define THREAD_GSCOPE_SET_FLAG() \
Packit Service 82fcde
  THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED)
Packit Service 82fcde
# define THREAD_GSCOPE_WAIT() \
Packit Service 82fcde
  GL(dl_wait_lookup_done) ()
Packit Service 82fcde
Packit Service 82fcde
#endif /* __ASSEMBLER__ */
Packit Service 82fcde
Packit Service 82fcde
#endif	/* tls.h */