pt-create.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /* Thread creation.
  2. Copyright (C) 2000-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <assert.h>
  16. #include <errno.h>
  17. #include <pthread.h>
  18. #include <signal.h>
  19. #include <resolv.h>
  20. #include <atomic.h>
  21. #include <hurd/resource.h>
  22. #include <sys/single_threaded.h>
  23. #include <shlib-compat.h>
  24. #include <ldsodefs.h>
  25. #include <pt-internal.h>
  26. #include <pthreadP.h>
  27. #include <ctype.h>
  28. #ifdef HAVE_USELOCALE
  29. # include <locale.h>
  30. #endif
  31. /* The entry-point for new threads. */
  32. static void
  33. entry_point (struct __pthread *self, void *(*start_routine) (void *), void *arg)
  34. {
  35. int err;
  36. ___pthread_self = self;
  37. __resp = &self->res_state;
  38. /* Initialize pointers to locale data. */
  39. __ctype_init ();
  40. #ifdef HAVE_USELOCALE
  41. /* A fresh thread needs to be bound to the global locale. */
  42. uselocale (LC_GLOBAL_LOCALE);
  43. #endif
  44. __pthread_startup ();
  45. /* We can now unleash signals. */
  46. err = __pthread_sigstate (self, SIG_SETMASK, &self->init_sigset, 0, 0);
  47. assert_perror (err);
  48. if (self->c11)
  49. {
  50. /* The function pointer of the c11 thread start is cast to an incorrect
  51. type on __pthread_create call, however it is casted back to correct
  52. one so the call behavior is well-defined (it is assumed that pointers
  53. to void are able to represent all values of int). */
  54. int (*start)(void*) = (int (*) (void*)) start_routine;
  55. __pthread_exit ((void*) (uintptr_t) start (arg));
  56. }
  57. else
  58. __pthread_exit (start_routine (arg));
  59. }
  60. /* Create a thread with attributes given by ATTR, executing
  61. START_ROUTINE with argument ARG. */
  62. int
  63. __pthread_create (pthread_t * thread, const pthread_attr_t * attr,
  64. void *(*start_routine) (void *), void *arg)
  65. {
  66. /* Avoid a data race in the multi-threaded case. */
  67. if (__libc_single_threaded)
  68. __libc_single_threaded = 0;
  69. return __libc_pthread_create (thread, attr, start_routine, arg);
  70. }
  71. versioned_symbol (libc, __pthread_create, pthread_create, GLIBC_2_43);
  72. #if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_12, GLIBC_2_43)
  73. compat_symbol (libpthread, __pthread_create, pthread_create, GLIBC_2_12);
  74. #endif
  75. hidden_def (__pthread_create)
  76. /* Version of pthread_create which does not make __libc_single_threaded zero.
  77. This is notably useful for the signal thread. */
  78. int
  79. __libc_pthread_create (pthread_t * thread, const pthread_attr_t * attr,
  80. void *(*start_routine) (void *), void *arg)
  81. {
  82. int err;
  83. struct __pthread *pthread;
  84. err = __pthread_create_internal (&pthread, attr, start_routine, arg);
  85. if (!err)
  86. *thread = pthread->thread;
  87. else if (err == ENOMEM)
  88. err = EAGAIN;
  89. return err;
  90. }
  91. /* Internal version of pthread_create. See comment in
  92. pt-internal.h. */
  93. int
  94. __pthread_create_internal (struct __pthread **thread,
  95. const pthread_attr_t * attr,
  96. void *(*start_routine) (void *), void *arg)
  97. {
  98. int err;
  99. struct __pthread *pthread;
  100. const struct __pthread_attr *setup;
  101. sigset_t sigset;
  102. size_t stacksize;
  103. /* Allocate a new thread structure. */
  104. err = __pthread_alloc (&pthread);
  105. if (err)
  106. goto failed;
  107. if (attr == ATTR_C11_THREAD)
  108. {
  109. attr = NULL;
  110. pthread->c11 = true;
  111. }
  112. else
  113. pthread->c11 = false;
  114. /* Use the default attributes if ATTR is NULL. */
  115. setup = attr ? attr : &__pthread_default_attr;
  116. stacksize = setup->__stacksize;
  117. if (stacksize == 0)
  118. {
  119. struct rlimit rlim;
  120. err = __getrlimit (RLIMIT_STACK, &rlim);
  121. if (err == 0 && rlim.rlim_cur != RLIM_INFINITY)
  122. stacksize = rlim.rlim_cur;
  123. if (stacksize == 0)
  124. stacksize = PTHREAD_STACK_DEFAULT;
  125. }
  126. /* Initialize the thread state. */
  127. pthread->state = (setup->__detachstate == PTHREAD_CREATE_DETACHED
  128. ? PTHREAD_DETACHED : PTHREAD_JOINABLE);
  129. if (setup->__stackaddr)
  130. {
  131. pthread->stackaddr = setup->__stackaddr;
  132. /* If the user supplied a stack, it is not our responsibility to
  133. setup a stack guard. */
  134. pthread->guardsize = 0;
  135. pthread->stack = 0;
  136. }
  137. else
  138. {
  139. /* Allocate a stack. */
  140. err = __pthread_stack_alloc (&pthread->stackaddr,
  141. ((setup->__guardsize + __vm_page_size - 1)
  142. / __vm_page_size) * __vm_page_size
  143. + stacksize);
  144. if (err)
  145. goto failed_stack_alloc;
  146. pthread->guardsize = setup->__guardsize;
  147. pthread->stack = 1;
  148. }
  149. pthread->stacksize = stacksize;
  150. /* Allocate the kernel thread and other required resources. */
  151. err = __pthread_thread_alloc (pthread);
  152. if (err)
  153. goto failed_thread_alloc;
  154. pthread->tcb = _dl_allocate_tls (NULL);
  155. if (pthread->tcb == NULL)
  156. {
  157. err = ENOMEM;
  158. goto failed_thread_tls_alloc;
  159. }
  160. #if TLS_TCB_AT_TP
  161. pthread->tcb->tcb = pthread->tcb;
  162. #endif
  163. /* And initialize the rest of the machine context. This may include
  164. additional machine- and system-specific initializations that
  165. prove convenient. */
  166. err = __pthread_setup (pthread, entry_point, start_routine, arg);
  167. if (err)
  168. goto failed_setup;
  169. /* Initialize the system-specific signal state for the new
  170. thread. */
  171. err = __pthread_sigstate_init (pthread);
  172. if (err)
  173. goto failed_sigstate;
  174. /* If the new thread is joinable, add a reference for the caller. */
  175. if (pthread->state == PTHREAD_JOINABLE)
  176. pthread->nr_refs++;
  177. /* Set the new thread's signal mask and set the pending signals to
  178. empty. POSIX says: "The signal mask shall be inherited from the
  179. creating thread. The set of signals pending for the new thread
  180. shall be empty." If the current thread is not a pthread then we
  181. just inherit the process' sigmask. */
  182. err = __pthread_sigmask (0, 0, &pthread->init_sigset);
  183. assert_perror (err);
  184. if (start_routine)
  185. /* But block the signals for now, until the thread is fully initialized. */
  186. __sigfillset (&sigset);
  187. else
  188. sigset = pthread->init_sigset;
  189. err = __pthread_sigstate (pthread, SIG_SETMASK, &sigset, 0, 1);
  190. assert_perror (err);
  191. /* Increase the total number of threads. We do this before actually
  192. starting the new thread, since the new thread might immediately
  193. call `pthread_exit' which decreases the number of threads and
  194. calls `exit' if the number of threads reaches zero. Increasing
  195. the number of threads from within the new thread isn't an option
  196. since this thread might return and call `pthread_exit' before the
  197. new thread runs. */
  198. atomic_fetch_add_relaxed (&__pthread_total, 1);
  199. /* Store a pointer to this thread in the thread ID lookup table. We
  200. could use __thread_setid, however, we only lock for reading as no
  201. other thread should be using this entry (we also assume that the
  202. store is atomic). */
  203. __libc_rwlock_rdlock (GL (dl_pthread_threads_lock));
  204. GL (dl_pthread_threads)[pthread->thread - 1] = pthread;
  205. __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
  206. /* At this point it is possible to guess our pthread ID. We have to
  207. make sure that all functions taking a pthread_t argument can
  208. handle the fact that this thread isn't really running yet. Since
  209. the new thread might be passed its ID through pthread_create (to
  210. avoid calling pthread_self), read it before starting the thread. */
  211. *thread = pthread;
  212. /* Schedule the new thread. */
  213. err = __pthread_thread_start (pthread);
  214. if (err)
  215. goto failed_starting;
  216. return 0;
  217. failed_starting:
  218. /* If joinable, a reference was added for the caller. */
  219. if (pthread->state == PTHREAD_JOINABLE)
  220. {
  221. __pthread_dealloc (pthread);
  222. __pthread_dealloc_finish (pthread);
  223. }
  224. __pthread_setid (pthread->thread, NULL);
  225. atomic_fetch_add_relaxed (&__pthread_total, -1);
  226. failed_sigstate:
  227. __pthread_sigstate_destroy (pthread);
  228. failed_setup:
  229. _dl_deallocate_tls (pthread->tcb, 1);
  230. pthread->tcb = NULL;
  231. failed_thread_tls_alloc:
  232. __pthread_thread_terminate (pthread);
  233. /* __pthread_thread_terminate has taken care of deallocating the stack and
  234. the thread structure. */
  235. goto failed;
  236. failed_thread_alloc:
  237. if (pthread->stack)
  238. __pthread_stack_dealloc (pthread->stackaddr,
  239. ((setup->__guardsize + __vm_page_size - 1)
  240. / __vm_page_size) * __vm_page_size + stacksize);
  241. failed_stack_alloc:
  242. __pthread_dealloc (pthread);
  243. __pthread_dealloc_finish (pthread);
  244. failed:
  245. return err;
  246. }