| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 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 | } |