]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/nacl/pthread-pids.h
80cd98e06a190cac548312325d3e82d88e661a96
[thirdparty/glibc.git] / sysdeps / nacl / pthread-pids.h
1 /* Initialize pid and tid fields of struct pthread. NaCl version.
2 Copyright (C) 2015-2016 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 <http://www.gnu.org/licenses/>. */
18
19 #include <pthreadP.h>
20
21
22 /* NaCl has no concept of PID or TID, nor even any notion of an
23 identifier for a thread within the process. But various places in
24 the NPTL implementation rely on using the 'tid' field of the TCB
25 (struct pthread) as an identifier that is unique at least among all
26 live threads in the process. So we must synthesize some number to
27 use. Conveniently, the 'pthread_t' value itself is already unique
28 in exactly this way (because it's the 'struct pthread' pointer).
29
30 The only wrinkle is that 'tid' is a (32-bit) 'int' and its high
31 (sign) bit is used for special purposes, so we must be absolutely
32 sure that we never use a pointer value with the high bit set. (It
33 also cannot be zero, but zero is never a valid pointer anyway.)
34 The NaCl sandbox models for 32-bit machines limit the address space
35 to less than 3GB (in fact, to 1GB), so it's already impossible that
36 a valid pointer will have its high bit set. But the NaCl x86-64
37 sandbox model allows a full 4GB of address space, so we cannot
38 assume that an arbitrary pointer value will not have the high bit
39 set. Conveniently, there are always unused bits in the pointer
40 value for a 'struct pthread', because it is always aligned to at
41 least 32 bits and so the low bits are always zero. Hence, we can
42 safely avoid the danger of a nonzero high bit just by shifting the
43 pointer value right. */
44
45 static inline int
46 __nacl_get_tid (struct pthread *pd)
47 {
48 uintptr_t id = (uintptr_t) pd;
49 int tid = id >> 1;
50 assert ((id & 1) == 0);
51 assert (sizeof id == sizeof tid);
52 assert (tid > 0);
53 /* This ensures that NACL_EXITING_TID (lowlevellock.h) can never
54 be a valid TID value. */
55 assert ((tid & 1) == 0);
56 return tid;
57 }
58
59
60 /* Initialize PD->pid and PD->tid for the initial thread. If there is
61 setup required to arrange that __exit_thread causes PD->tid to be
62 cleared and futex-woken, then this function should do that as well. */
63 static inline void
64 __pthread_initialize_pids (struct pthread *pd)
65 {
66 pd->tid = __nacl_get_tid (pd);
67 pd->pid = -1;
68 }