Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
git-mirror
/
glibc
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
0
Security
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security
Insights
Files
f7d78e1
abilist
aout
argp
assert
bare
bits
catgets
conf
conform
crypt
csu
ctype
debug
dirent
dlfcn
elf
gmon
gnulib
grp
hesiod
hurd
iconv
iconvdata
include
inet
intl
io
libidn
libio
linuxthreads
linuxthreads_db
locale
localedata
login
mach
malloc
manual
math
misc
nis
nptl
sysdeps
alpha
generic
i386
ia64
mips
powerpc
pthread
s390
sh
sparc
unix
x86_64
Makefile
jmpbuf-unwind.h
pthread_spin_init.c
pthread_spin_lock.c
pthread_spin_trylock.S
pthread_spin_unlock.S
pthreaddef.h
tcb-offsets.sym
tls.h
ANNOUNCE
Banner
ChangeLog
DESIGN-barrier.txt
DESIGN-condvar.txt
DESIGN-rwlock.txt
DESIGN-sem.txt
Makeconfig
Makefile
TODO
TODO-kernel
TODO-testing
Versions
alloca_cutoff.c
allocatestack.c
cancellation.c
cleanup.c
cleanup_compat.c
cleanup_defer.c
cleanup_defer_compat.c
cleanup_routine.c
cond-perf.c
configure
descr.h
eintr.c
events.c
forward.c
herrno.c
init.c
libc-cancellation.c
old_pthread_atfork.c
old_pthread_cond_broadcast.c
old_pthread_cond_destroy.c
old_pthread_cond_init.c
old_pthread_cond_signal.c
old_pthread_cond_timedwait.c
old_pthread_cond_wait.c
perf.c
pt-allocrtsig.c
pt-cleanup.c
pt-system.c
pthread-errnos.sym
pthreadP.h
pthread_atfork.c
pthread_attr_destroy.c
pthread_attr_getdetachstate.c
pthread_attr_getguardsize.c
pthread_attr_getinheritsched.c
pthread_attr_getschedparam.c
pthread_attr_getschedpolicy.c
pthread_attr_getscope.c
pthread_attr_getstack.c
pthread_attr_getstackaddr.c
pthread_attr_getstacksize.c
pthread_attr_init.c
pthread_attr_setdetachstate.c
pthread_attr_setguardsize.c
pthread_attr_setinheritsched.c
pthread_attr_setschedparam.c
pthread_attr_setschedpolicy.c
pthread_attr_setscope.c
pthread_attr_setstack.c
pthread_attr_setstackaddr.c
pthread_attr_setstacksize.c
pthread_barrier_destroy.c
pthread_barrier_init.c
pthread_barrierattr_destroy.c
pthread_barrierattr_getpshared.c
pthread_barrierattr_init.c
pthread_barrierattr_setpshared.c
pthread_cancel.c
pthread_clock_gettime.c
pthread_clock_settime.c
pthread_cond_destroy.c
pthread_cond_init.c
pthread_condattr_destroy.c
pthread_condattr_getclock.c
pthread_condattr_getpshared.c
pthread_condattr_init.c
pthread_condattr_setclock.c
pthread_condattr_setpshared.c
pthread_create.c
pthread_detach.c
pthread_equal.c
pthread_exit.c
pthread_getattr_np.c
pthread_getconcurrency.c
pthread_getschedparam.c
pthread_getspecific.c
pthread_join.c
pthread_key_create.c
pthread_key_delete.c
pthread_kill_other_threads.c
pthread_mutex_destroy.c
pthread_mutex_init.c
pthread_mutex_lock.c
pthread_mutex_timedlock.c
pthread_mutex_trylock.c
pthread_mutex_unlock.c
pthread_mutexattr_destroy.c
pthread_mutexattr_getpshared.c
pthread_mutexattr_gettype.c
pthread_mutexattr_init.c
pthread_mutexattr_setpshared.c
pthread_mutexattr_settype.c
pthread_rwlock_destroy.c
pthread_rwlock_init.c
pthread_rwlock_tryrdlock.c
pthread_rwlock_trywrlock.c
pthread_rwlockattr_destroy.c
pthread_rwlockattr_getkind_np.c
pthread_rwlockattr_getpshared.c
pthread_rwlockattr_init.c
pthread_rwlockattr_setkind_np.c
pthread_rwlockattr_setpshared.c
pthread_self.c
pthread_setcancelstate.c
pthread_setcanceltype.c
pthread_setconcurrency.c
pthread_setegid.c
pthread_seteuid.c
pthread_setgid.c
pthread_setregid.c
pthread_setresgid.c
pthread_setresuid.c
pthread_setreuid.c
pthread_setschedparam.c
pthread_setschedprio.c
pthread_setspecific.c
pthread_setuid.c
pthread_testcancel.c
pthread_timedjoin.c
pthread_tryjoin.c
res.c
sem_close.c
sem_destroy.c
sem_getvalue.c
sem_init.c
sem_open.c
sem_unlink.c
semaphore.h
semaphoreP.h
shlib-versions
sockperf.c
tst-_res1.c
tst-_res1mod1.c
tst-_res1mod2.c
tst-align.c
tst-align2.c
tst-atfork1.c
tst-atfork2.c
tst-atfork2mod.c
tst-attr1.c
tst-attr2.c
tst-attr3.c
tst-backtrace1.c
tst-barrier1.c
tst-barrier2.c
tst-barrier3.c
tst-barrier4.c
tst-basic1.c
tst-basic2.c
tst-basic3.c
tst-basic4.c
tst-basic5.c
tst-basic6.c
tst-cancel-wrappers.sh
tst-cancel1.c
tst-cancel10.c
tst-cancel11.c
tst-cancel12.c
tst-cancel13.c
tst-cancel14.c
tst-cancel15.c
tst-cancel16.c
tst-cancel17.c
tst-cancel18.c
tst-cancel19.c
tst-cancel2.c
tst-cancel20.c
tst-cancel21.c
tst-cancel22.c
tst-cancel23.c
tst-cancel3.c
tst-cancel4.c
tst-cancel5.c
tst-cancel6.c
tst-cancel7.c
tst-cancel8.c
tst-cancel9.c
tst-cancelx1.c
tst-cancelx10.c
tst-cancelx11.c
tst-cancelx12.c
tst-cancelx13.c
tst-cancelx14.c
tst-cancelx15.c
tst-cancelx16.c
tst-cancelx17.c
tst-cancelx18.c
tst-cancelx2.c
tst-cancelx20.c
tst-cancelx21.c
tst-cancelx3.c
tst-cancelx4.c
tst-cancelx5.c
tst-cancelx6.c
tst-cancelx7.c
tst-cancelx8.c
tst-cancelx9.c
tst-cleanup0.c
tst-cleanup0.expect
tst-cleanup1.c
tst-cleanup2.c
tst-cleanup3.c
tst-cleanup4.c
tst-cleanup4aux.c
tst-cleanupx0.c
tst-cleanupx0.expect
tst-cleanupx1.c
tst-cleanupx2.c
tst-cleanupx3.c
tst-cleanupx4.c
tst-clock1.c
tst-clock2.c
tst-cond1.c
tst-cond10.c
tst-cond11.c
tst-cond12.c
tst-cond13.c
tst-cond14.c
tst-cond15.c
tst-cond16.c
tst-cond17.c
tst-cond18.c
tst-cond19.c
tst-cond2.c
tst-cond20.c
tst-cond21.c
tst-cond3.c
tst-cond4.c
tst-cond5.c
tst-cond6.c
tst-cond7.c
tst-cond8.c
tst-cond9.c
tst-context1.c
tst-detach1.c
tst-dlsym1.c
tst-eintr1.c
tst-eintr2.c
tst-eintr3.c
tst-eintr4.c
tst-eintr5.c
tst-exec1.c
tst-exec2.c
tst-exec3.c
tst-exec4.c
tst-execstack-mod.c
tst-execstack.c
tst-exit1.c
tst-exit2.c
tst-exit3.c
tst-fini1.c
tst-fini1mod.c
tst-flock1.c
tst-flock2.c
tst-fork1.c
tst-fork2.c
tst-fork3.c
tst-fork4.c
tst-getpid1.c
tst-getpid2.c
tst-join1.c
tst-join2.c
tst-join3.c
tst-join4.c
tst-join5.c
tst-key1.c
tst-key2.c
tst-key3.c
tst-key4.c
tst-kill1.c
tst-kill2.c
tst-kill3.c
tst-kill4.c
tst-kill5.c
tst-kill6.c
tst-locale1.c
tst-locale2.c
tst-mutex1.c
tst-mutex2.c
tst-mutex3.c
tst-mutex4.c
tst-mutex5.c
tst-mutex5a.c
tst-mutex6.c
tst-mutex7.c
tst-mutex7a.c
tst-mutex8.c
tst-mutex9.c
tst-oddstacklimit.c
tst-once1.c
tst-once2.c
tst-once3.c
tst-once4.c
tst-oncex3.c
tst-oncex4.c
tst-popen1.c
tst-raise1.c
tst-rwlock1.c
tst-rwlock10.c
tst-rwlock11.c
tst-rwlock12.c
tst-rwlock13.c
tst-rwlock14.c
tst-rwlock2.c
tst-rwlock3.c
tst-rwlock4.c
tst-rwlock5.c
tst-rwlock6.c
tst-rwlock7.c
tst-rwlock8.c
tst-rwlock9.c
tst-sched1.c
tst-sem1.c
tst-sem2.c
tst-sem3.c
tst-sem4.c
tst-sem5.c
tst-sem6.c
tst-sem7.c
tst-sem8.c
tst-sem9.c
tst-setuid1-static.c
tst-setuid1.c
tst-signal1.c
tst-signal2.c
tst-signal3.c
tst-signal4.c
tst-signal5.c
tst-signal6.c
tst-spin1.c
tst-spin2.c
tst-spin3.c
tst-stack1.c
tst-stack2.c
tst-stack3.c
tst-stdio1.c
tst-stdio2.c
tst-sysconf.c
tst-tls1.c
tst-tls2.c
tst-tls3.c
tst-tls3mod.c
tst-tls4.c
tst-tls4moda.c
tst-tls4modb.c
tst-tls5.c
tst-tls5.h
tst-tls5mod.c
tst-tls5moda.c
tst-tls5modb.c
tst-tls5modc.c
tst-tls5modd.c
tst-tls5mode.c
tst-tls5modf.c
tst-tls6.sh
tst-tsd1.c
tst-tsd2.c
tst-tsd3.c
tst-tsd4.c
tst-tsd5.c
tst-umask1.c
tst-unload.c
tst-vfork1.c
tst-vfork1x.c
tst-vfork2.c
tst-vfork2x.c
unwind.c
vars.c
version.c
nptl_db
nscd
nss
po
posix
pwd
resolv
resource
rt
scripts
setjmp
shadow
signal
socket
soft-fp
stdio-common
stdlib
streams
string
sunrpc
sysdeps
sysvipc
termios
time
timezone
wcsmbs
wctype
.cvsignore
BUGS
CANCEL-FCT-WAIVE
CANCEL-FILE-WAIVE
CONFORMANCE
COPYING
COPYING.LIB
ChangeLog
ChangeLog.1
ChangeLog.10
ChangeLog.11
ChangeLog.12
ChangeLog.13
ChangeLog.14
ChangeLog.15
ChangeLog.2
ChangeLog.3
ChangeLog.4
ChangeLog.5
ChangeLog.6
ChangeLog.7
ChangeLog.8
ChangeLog.9
FAQ
FAQ.in
INSTALL
INTERFACE
LICENSES
MakeTAGS
Makeconfig
Makefile
Makefile.in
Makerules
NAMESPACE
NEWS
NOTES
PROJECTS
README
README.libm
README.template
Rules
Versions.def
WUR-REPORT
abi-tags
aclocal.m4
config-name.in
config.h.in
config.make.in
configure
configure.in
cppflags-iterator.mk
extra-lib.mk
extra-modules.mk
o-iterator.mk
shlib-versions
test-skeleton.c
tls.make.c
version.h
Breadcrumbs
glibc
/
nptl
/
sysdeps
/
x86_64
/
tls.h
Blame
Blame
Latest commit
History
History
325 lines (268 loc) · 10.9 KB
Breadcrumbs
glibc
/
nptl
/
sysdeps
/
x86_64
/
tls.h
Top
File metadata and controls
Code
Blame
325 lines (268 loc) · 10.9 KB
Raw
/* Definition for thread-local data handling. nptl/x86_64 version. Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #ifndef _TLS_H #define _TLS_H 1 #include <asm/prctl.h> /* For ARCH_SET_FS. */ #ifndef __ASSEMBLER__ # include <stdbool.h> # include <stddef.h> # include <stdint.h> # include <stdlib.h> /* Type for the dtv. */ typedef union dtv { size_t counter; struct { void *val; bool is_static; } pointer; } dtv_t; typedef struct { void *tcb; /* Pointer to the TCB. Not necessary the thread descriptor used by libpthread. */ dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ int multiple_threads; } tcbhead_t; #else /* __ASSEMBLER__ */ # include <tcb-offsets.h> #endif /* We require TLS support in the tools. */ #ifndef HAVE_TLS_SUPPORT # error "TLS support is required." #endif /* Signal that TLS support is available. */ #define USE_TLS 1 /* Alignment requirement for the stack. */ #define STACK_ALIGN 16 #ifndef __ASSEMBLER__ /* Get system call information. */ # include <sysdep.h> /* Get the thread descriptor definition. */ # include <nptl/descr.h> #ifndef LOCK_PREFIX # ifdef UP # define LOCK_PREFIX /* nothing */ # else # define LOCK_PREFIX "lock;" # endif #endif /* This is the size of the initial TCB. Can't be just sizeof (tcbhead_t), because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole struct pthread even when not linked with -lpthread. */ # define TLS_INIT_TCB_SIZE sizeof (struct pthread) /* Alignment requirements for the initial TCB. */ # define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) /* This is the size of the TCB. */ # define TLS_TCB_SIZE sizeof (struct pthread) /* Alignment requirements for the TCB. */ # define TLS_TCB_ALIGN __alignof__ (struct pthread) /* The TCB can have any size and the memory following the address the thread pointer points to is unspecified. Allocate the TCB there. */ # define TLS_TCB_AT_TP 1 /* Install the dtv pointer. The pointer passed is to the element with index -1 which contain the length. */ # define INSTALL_DTV(descr, dtvp) \ ((tcbhead_t *) (descr))->dtv = (dtvp) + 1 /* Install new dtv for current thread. */ # define INSTALL_NEW_DTV(dtvp) \ ({ struct pthread *__pd; \ THREAD_SETMEM (__pd, header.dtv, (dtvp)); }) /* Return dtv of given thread descriptor. */ # define GET_DTV(descr) \ (((tcbhead_t *) (descr))->dtv) /* Macros to load from and store into segment registers. */ # define TLS_GET_FS() \ ({ int __seg; __asm ("movl %%fs, %0" : "=q" (__seg)); __seg; }) # define TLS_SET_FS(val) \ __asm ("movl %0, %%fs" :: "q" (val)) /* Code to initially initialize the thread pointer. This might need special attention since 'errno' is not yet available and if the operation can cause a failure 'errno' must not be touched. We have to make the syscall for both uses of the macro since the address might be (and probably is) different. */ # define TLS_INIT_TP(thrdescr, secondcall) \ ({ void *_thrdescr = (thrdescr); \ tcbhead_t *_head = _thrdescr; \ int _result; \ \ _head->tcb = _thrdescr; \ /* For now the thread descriptor is at the same address. */ \ _head->self = _thrdescr; \ \ /* It is a simple syscall to set the %fs value for the thread. */ \ asm volatile ("syscall" \ : "=a" (_result) \ : "0" ((unsigned long int) __NR_arch_prctl), \ "D" ((unsigned long int) ARCH_SET_FS), \ "S" (_thrdescr) \ : "memory", "cc", "r11", "cx"); \ \ _result ? "cannot set %fs base address for thread-local storage" : 0; \ }) /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ ({ struct pthread *__pd; \ THREAD_GETMEM (__pd, header.dtv); }) /* Return the thread descriptor for the current thread. The contained asm must *not* be marked volatile since otherwise assignments like pthread_descr self = thread_self(); do not get optimized away. */ # define THREAD_SELF \ ({ struct pthread *__self; \ asm ("movq %%fs:%c1,%q0" : "=r" (__self) \ : "i" (offsetof (struct pthread, header.self))); \ __self;}) /* Magic for libthread_db to know how to do THREAD_SELF. */ # define DB_THREAD_SELF_INCLUDE <sys/reg.h> /* For the FS constant. */ # define DB_THREAD_SELF CONST_THREAD_AREA (64, FS) /* Read member of the thread descriptor directly. */ # define THREAD_GETMEM(descr, member) \ ({ __typeof (descr->member) __value; \ if (sizeof (__value) == 1) \ asm volatile ("movb %%fs:%P2,%b0" \ : "=q" (__value) \ : "0" (0), "i" (offsetof (struct pthread, member))); \ else if (sizeof (__value) == 4) \ asm volatile ("movl %%fs:%P1,%0" \ : "=r" (__value) \ : "i" (offsetof (struct pthread, member))); \ else \ { \ if (sizeof (__value) != 8) \ /* There should not be any value with a size other than 1, \ 4 or 8. */ \ abort (); \ \ asm volatile ("movq %%fs:%P1,%q0" \ : "=r" (__value) \ : "i" (offsetof (struct pthread, member))); \ } \ __value; }) /* Same as THREAD_GETMEM, but the member offset can be non-constant. */ # define THREAD_GETMEM_NC(descr, member, idx) \ ({ __typeof (descr->member[0]) __value; \ if (sizeof (__value) == 1) \ asm volatile ("movb %%fs:%P2(%q3),%b0" \ : "=q" (__value) \ : "0" (0), "i" (offsetof (struct pthread, member[0])), \ "r" (idx)); \ else if (sizeof (__value) == 4) \ asm volatile ("movl %%fs:%P1(,%q2,4),%0" \ : "=r" (__value) \ : "i" (offsetof (struct pthread, member[0])), "r" (idx));\ else \ { \ if (sizeof (__value) != 8) \ /* There should not be any value with a size other than 1, \ 4 or 8. */ \ abort (); \ \ asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \ : "=r" (__value) \ : "i" (offsetof (struct pthread, member[0])), \ "r" (idx)); \ } \ __value; }) /* Loading addresses of objects on x86-64 needs to be treated special when generating PIC code. */ #ifdef __pic__ # define IMM_MODE "nr" #else # define IMM_MODE "ir" #endif /* Same as THREAD_SETMEM, but the member offset can be non-constant. */ # define THREAD_SETMEM(descr, member, value) \ ({ if (sizeof (descr->member) == 1) \ asm volatile ("movb %b0,%%fs:%P1" : \ : "iq" (value), \ "i" (offsetof (struct pthread, member))); \ else if (sizeof (descr->member) == 4) \ asm volatile ("movl %0,%%fs:%P1" : \ : IMM_MODE (value), \ "i" (offsetof (struct pthread, member))); \ else \ { \ if (sizeof (descr->member) != 8) \ /* There should not be any value with a size other than 1, \ 4 or 8. */ \ abort (); \ \ asm volatile ("movq %q0,%%fs:%P1" : \ : IMM_MODE ((unsigned long int) value), \ "i" (offsetof (struct pthread, member))); \ }}) /* Set member of the thread descriptor directly. */ # define THREAD_SETMEM_NC(descr, member, idx, value) \ ({ if (sizeof (descr->member[0]) == 1) \ asm volatile ("movb %b0,%%fs:%P1(%q2)" : \ : "iq" (value), \ "i" (offsetof (struct pthread, member[0])), \ "r" (idx)); \ else if (sizeof (descr->member[0]) == 4) \ asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \ : IMM_MODE (value), \ "i" (offsetof (struct pthread, member[0])), \ "r" (idx)); \ else \ { \ if (sizeof (descr->member[0]) != 8) \ /* There should not be any value with a size other than 1, \ 4 or 8. */ \ abort (); \ \ asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \ : IMM_MODE ((unsigned long int) value), \ "i" (offsetof (struct pthread, member[0])), \ "r" (idx)); \ }}) /* Atomic compare and exchange on TLS, returning old value. */ #define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \ ({ __typeof (descr->member) __ret; \ __typeof (oldval) __old = (oldval); \ if (sizeof (descr->member) == 4) \ asm volatile (LOCK_PREFIX "cmpxchgl %2, %%fs:%P3" \ : "=a" (__ret) \ : "0" (__old), "r" (newval), \ "i" (offsetof (struct pthread, member))); \ else \ /* Not necessary for other sizes in the moment. */ \ abort (); \ __ret; }) /* Atomic set bit. */ #define THREAD_ATOMIC_BIT_SET(descr, member, bit) \ (void) ({ if (sizeof ((descr)->member) == 4) \ asm volatile (LOCK_PREFIX "orl %1, %%fs:%P0" \ :: "i" (offsetof (struct pthread, member)), \ "ir" (1 << (bit))); \ else \ /* Not necessary for other sizes in the moment. */ \ abort (); }) #define CALL_THREAD_FCT(descr) \ ({ void *__res; \ asm volatile ("movq %%fs:%P2, %%rdi\n\t" \ "callq *%%fs:%P1" \ : "=a" (__res) \ : "i" (offsetof (struct pthread, start_routine)), \ "i" (offsetof (struct pthread, arg)) \ : "di", "si", "cx", "dx", "r8", "r9", "r10", "r11", \ "memory", "cc"); \ __res; }) #endif /* __ASSEMBLER__ */ #endif /* tls.h */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
You can’t perform that action at this time.