1 /* 2 * Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org> 3 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by John Birrell. 17 * 4. Neither the name of the author nor the names of any co-contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $FreeBSD$ 34 */ 35 36 /* Allocate space for global thread variables here: */ 37 #define GLOBAL_PTHREAD_PRIVATE 38 39 #include "namespace.h" 40 #include <sys/param.h> 41 #include <sys/types.h> 42 #include <sys/signalvar.h> 43 #include <machine/reg.h> 44 45 #include <sys/ioctl.h> 46 #include <sys/mount.h> 47 #include <sys/uio.h> 48 #include <sys/socket.h> 49 #include <sys/event.h> 50 #include <sys/stat.h> 51 #include <sys/sysctl.h> 52 #include <sys/time.h> 53 #include <sys/ttycom.h> 54 #include <sys/wait.h> 55 #include <sys/mman.h> 56 #include <dirent.h> 57 #include <errno.h> 58 #include <fcntl.h> 59 #include <paths.h> 60 #include <pthread.h> 61 #include <pthread_np.h> 62 #include <signal.h> 63 #include <stdio.h> 64 #include <stdlib.h> 65 #include <string.h> 66 #include <unistd.h> 67 #include "un-namespace.h" 68 69 #include "libc_private.h" 70 #include "thr_private.h" 71 72 void *_usrstack; 73 struct pthread *_thr_initial; 74 int _thr_scope_system; 75 int _libthr_debug; 76 int _thread_event_mask; 77 struct pthread *_thread_last_event; 78 pthreadlist _thread_list = TAILQ_HEAD_INITIALIZER(_thread_list); 79 pthreadlist _thread_gc_list = TAILQ_HEAD_INITIALIZER(_thread_gc_list); 80 int _thread_active_threads = 1; 81 atfork_head _thr_atfork_list = TAILQ_HEAD_INITIALIZER(_thr_atfork_list); 82 umtx_t _thr_atfork_lock; 83 84 struct pthread_attr _pthread_attr_default = { 85 .sched_policy = SCHED_RR, 86 .sched_inherit = 0, 87 .sched_interval = TIMESLICE_USEC, 88 .prio = THR_DEFAULT_PRIORITY, 89 .suspend = THR_CREATE_RUNNING, 90 .flags = 0, 91 .arg_attr = NULL, 92 .cleanup_attr = NULL, 93 .stackaddr_attr = NULL, 94 .stacksize_attr = THR_STACK_DEFAULT, 95 .guardsize_attr = 0 96 }; 97 98 struct pthread_mutex_attr _pthread_mutexattr_default = { 99 .m_type = PTHREAD_MUTEX_DEFAULT, 100 .m_protocol = PTHREAD_PRIO_NONE, 101 .m_ceiling = 0, 102 .m_flags = 0 103 }; 104 105 /* Default condition variable attributes: */ 106 struct pthread_cond_attr _pthread_condattr_default = { 107 .c_pshared = PTHREAD_PROCESS_PRIVATE, 108 .c_clockid = CLOCK_REALTIME 109 }; 110 111 pid_t _thr_pid; 112 int _thr_guard_default; 113 int _thr_stack_default = THR_STACK_DEFAULT; 114 int _thr_stack_initial = THR_STACK_INITIAL; 115 int _thr_page_size; 116 int _gc_count; 117 umtx_t _mutex_static_lock; 118 umtx_t _cond_static_lock; 119 umtx_t _rwlock_static_lock; 120 umtx_t _keytable_lock; 121 umtx_t _thr_list_lock; 122 umtx_t _thr_event_lock; 123 124 int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); 125 int __pthread_mutex_lock(pthread_mutex_t *); 126 int __pthread_mutex_trylock(pthread_mutex_t *); 127 void _thread_init_hack(void) __attribute__ ((constructor)); 128 129 static void init_private(void); 130 static void init_main_thread(struct pthread *thread); 131 132 /* 133 * All weak references used within libc should be in this table. 134 * This is so that static libraries will work. 135 */ 136 static void *references[] = { 137 &_accept, 138 &_bind, 139 &_close, 140 &_connect, 141 &_dup, 142 &_dup2, 143 &_execve, 144 &_fcntl, 145 &_flock, 146 &_flockfile, 147 &_fstat, 148 &_fstatfs, 149 &_fsync, 150 &_funlockfile, 151 &_getdirentries, 152 &_getlogin, 153 &_getpeername, 154 &_getsockname, 155 &_getsockopt, 156 &_ioctl, 157 &_kevent, 158 &_listen, 159 &_nanosleep, 160 &_open, 161 &_pthread_getspecific, 162 &_pthread_key_create, 163 &_pthread_key_delete, 164 &_pthread_mutex_destroy, 165 &_pthread_mutex_init, 166 &_pthread_mutex_lock, 167 &_pthread_mutex_trylock, 168 &_pthread_mutex_unlock, 169 &_pthread_mutexattr_init, 170 &_pthread_mutexattr_destroy, 171 &_pthread_mutexattr_settype, 172 &_pthread_once, 173 &_pthread_setspecific, 174 &_read, 175 &_readv, 176 &_recvfrom, 177 &_recvmsg, 178 &_select, 179 &_sendmsg, 180 &_sendto, 181 &_setsockopt, 182 &_sigaction, 183 &_sigprocmask, 184 &_sigsuspend, 185 &_socket, 186 &_socketpair, 187 &_thread_init_hack, 188 &_wait4, 189 &_write, 190 &_writev 191 }; 192 193 /* 194 * These are needed when linking statically. All references within 195 * libgcc (and in the future libc) to these routines are weak, but 196 * if they are not (strongly) referenced by the application or other 197 * libraries, then the actual functions will not be loaded. 198 */ 199 static void *libgcc_references[] = { 200 &_pthread_once, 201 &_pthread_key_create, 202 &_pthread_key_delete, 203 &_pthread_getspecific, 204 &_pthread_setspecific, 205 &_pthread_mutex_init, 206 &_pthread_mutex_destroy, 207 &_pthread_mutex_lock, 208 &_pthread_mutex_trylock, 209 &_pthread_mutex_unlock, 210 &_pthread_create 211 }; 212 213 #define DUAL_ENTRY(entry) \ 214 (pthread_func_t)entry, (pthread_func_t)entry 215 216 static pthread_func_t jmp_table[][2] = { 217 {DUAL_ENTRY(_pthread_cond_broadcast)}, /* PJT_COND_BROADCAST */ 218 {DUAL_ENTRY(_pthread_cond_destroy)}, /* PJT_COND_DESTROY */ 219 {DUAL_ENTRY(_pthread_cond_init)}, /* PJT_COND_INIT */ 220 {DUAL_ENTRY(_pthread_cond_signal)}, /* PJT_COND_SIGNAL */ 221 {(pthread_func_t)__pthread_cond_wait, 222 (pthread_func_t)_pthread_cond_wait}, /* PJT_COND_WAIT */ 223 {DUAL_ENTRY(_pthread_getspecific)}, /* PJT_GETSPECIFIC */ 224 {DUAL_ENTRY(_pthread_key_create)}, /* PJT_KEY_CREATE */ 225 {DUAL_ENTRY(_pthread_key_delete)}, /* PJT_KEY_DELETE*/ 226 {DUAL_ENTRY(_pthread_main_np)}, /* PJT_MAIN_NP */ 227 {DUAL_ENTRY(_pthread_mutex_destroy)}, /* PJT_MUTEX_DESTROY */ 228 {DUAL_ENTRY(_pthread_mutex_init)}, /* PJT_MUTEX_INIT */ 229 {(pthread_func_t)__pthread_mutex_lock, 230 (pthread_func_t)_pthread_mutex_lock}, /* PJT_MUTEX_LOCK */ 231 {(pthread_func_t)__pthread_mutex_trylock, 232 (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */ 233 {DUAL_ENTRY(_pthread_mutex_unlock)}, /* PJT_MUTEX_UNLOCK */ 234 {DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */ 235 {DUAL_ENTRY(_pthread_mutexattr_init)}, /* PJT_MUTEXATTR_INIT */ 236 {DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */ 237 {DUAL_ENTRY(_pthread_once)}, /* PJT_ONCE */ 238 {DUAL_ENTRY(_pthread_rwlock_destroy)}, /* PJT_RWLOCK_DESTROY */ 239 {DUAL_ENTRY(_pthread_rwlock_init)}, /* PJT_RWLOCK_INIT */ 240 {DUAL_ENTRY(_pthread_rwlock_rdlock)}, /* PJT_RWLOCK_RDLOCK */ 241 {DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */ 242 {DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */ 243 {DUAL_ENTRY(_pthread_rwlock_unlock)}, /* PJT_RWLOCK_UNLOCK */ 244 {DUAL_ENTRY(_pthread_rwlock_wrlock)}, /* PJT_RWLOCK_WRLOCK */ 245 {DUAL_ENTRY(_pthread_self)}, /* PJT_SELF */ 246 {DUAL_ENTRY(_pthread_setspecific)}, /* PJT_SETSPECIFIC */ 247 {DUAL_ENTRY(_pthread_sigmask)} /* PJT_SIGMASK */ 248 }; 249 250 extern int _thread_state_running; 251 static int init_once = 0; 252 253 /* 254 * For the shared version of the threads library, the above is sufficient. 255 * But for the archive version of the library, we need a little bit more. 256 * Namely, we must arrange for this particular module to be pulled in from 257 * the archive library at link time. To accomplish that, we define and 258 * initialize a variable, "_thread_autoinit_dummy_decl". This variable is 259 * referenced (as an extern) from libc/stdlib/exit.c. This will always 260 * create a need for this module, ensuring that it is present in the 261 * executable. 262 */ 263 extern int _thread_autoinit_dummy_decl; 264 int _thread_autoinit_dummy_decl = 0; 265 266 void 267 _thread_init_hack(void) 268 { 269 270 _libpthread_init(NULL); 271 } 272 273 274 /* 275 * Threaded process initialization. 276 * 277 * This is only called under two conditions: 278 * 279 * 1) Some thread routines have detected that the library hasn't yet 280 * been initialized (_thr_initial == NULL && curthread == NULL), or 281 * 282 * 2) An explicit call to reinitialize after a fork (indicated 283 * by curthread != NULL) 284 */ 285 void 286 _libpthread_init(struct pthread *curthread) 287 { 288 int fd, first = 0; 289 sigset_t sigset, oldset; 290 291 /* Check if this function has already been called: */ 292 if ((_thr_initial != NULL) && (curthread == NULL)) 293 /* Only initialize the threaded application once. */ 294 return; 295 296 /* 297 * Make gcc quiescent about {,libgcc_}references not being 298 * referenced: 299 */ 300 if ((references[0] == NULL) || (libgcc_references[0] == NULL)) 301 PANIC("Failed loading mandatory references in _thread_init"); 302 303 /* Pull debug symbols in for static binary */ 304 _thread_state_running = PS_RUNNING; 305 306 /* 307 * Check the size of the jump table to make sure it is preset 308 * with the correct number of entries. 309 */ 310 if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2)) 311 PANIC("Thread jump table not properly initialized"); 312 memcpy(__thr_jtable, jmp_table, sizeof(jmp_table)); 313 314 /* 315 * Check for the special case of this process running as 316 * or in place of init as pid = 1: 317 */ 318 if ((_thr_pid = getpid()) == 1) { 319 /* 320 * Setup a new session for this process which is 321 * assumed to be running as root. 322 */ 323 if (setsid() == -1) 324 PANIC("Can't set session ID"); 325 if (revoke(_PATH_CONSOLE) != 0) 326 PANIC("Can't revoke console"); 327 if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) 328 PANIC("Can't open console"); 329 if (setlogin("root") == -1) 330 PANIC("Can't set login to root"); 331 if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1) 332 PANIC("Can't set controlling terminal"); 333 } 334 335 /* Initialize pthread private data. */ 336 init_private(); 337 338 /* Set the initial thread. */ 339 if (curthread == NULL) { 340 first = 1; 341 /* Create and initialize the initial thread. */ 342 curthread = _thr_alloc(NULL); 343 if (curthread == NULL) 344 PANIC("Can't allocate initial thread"); 345 init_main_thread(curthread); 346 } 347 /* 348 * Add the thread to the thread list queue. 349 */ 350 THR_LIST_ADD(curthread); 351 _thread_active_threads = 1; 352 353 /* Setup the thread specific data */ 354 _tcb_set(curthread->tcb); 355 356 if (first) { 357 SIGFILLSET(sigset); 358 SIGDELSET(sigset, SIGTRAP); 359 __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset); 360 _thr_signal_init(); 361 _thr_initial = curthread; 362 SIGDELSET(oldset, SIGCANCEL); 363 __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); 364 if (_thread_event_mask & TD_CREATE) 365 _thr_report_creation(curthread, curthread); 366 } 367 } 368 369 /* 370 * This function and pthread_create() do a lot of the same things. 371 * It'd be nice to consolidate the common stuff in one place. 372 */ 373 static void 374 init_main_thread(struct pthread *thread) 375 { 376 /* Setup the thread attributes. */ 377 thr_self(&thread->tid); 378 thread->attr = _pthread_attr_default; 379 /* 380 * Set up the thread stack. 381 * 382 * Create a red zone below the main stack. All other stacks 383 * are constrained to a maximum size by the parameters 384 * passed to mmap(), but this stack is only limited by 385 * resource limits, so this stack needs an explicitly mapped 386 * red zone to protect the thread stack that is just beyond. 387 */ 388 if (mmap((void *)_usrstack - _thr_stack_initial - 389 _thr_guard_default, _thr_guard_default, 0, MAP_ANON, 390 -1, 0) == MAP_FAILED) 391 PANIC("Cannot allocate red zone for initial thread"); 392 393 /* 394 * Mark the stack as an application supplied stack so that it 395 * isn't deallocated. 396 * 397 * XXX - I'm not sure it would hurt anything to deallocate 398 * the main thread stack because deallocation doesn't 399 * actually free() it; it just puts it in the free 400 * stack queue for later reuse. 401 */ 402 thread->attr.stackaddr_attr = (void *)_usrstack - _thr_stack_initial; 403 thread->attr.stacksize_attr = _thr_stack_initial; 404 thread->attr.guardsize_attr = _thr_guard_default; 405 thread->attr.flags |= THR_STACK_USER; 406 407 /* 408 * Write a magic value to the thread structure 409 * to help identify valid ones: 410 */ 411 thread->magic = THR_MAGIC; 412 413 thread->cancelflags = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; 414 thread->name = strdup("initial thread"); 415 416 /* Default the priority of the initial thread: */ 417 thread->base_priority = THR_DEFAULT_PRIORITY; 418 thread->active_priority = THR_DEFAULT_PRIORITY; 419 thread->inherited_priority = 0; 420 421 /* Initialize the mutex queue: */ 422 TAILQ_INIT(&thread->mutexq); 423 TAILQ_INIT(&thread->pri_mutexq); 424 425 thread->state = PS_RUNNING; 426 427 /* Others cleared to zero by thr_alloc() */ 428 } 429 430 static void 431 init_private(void) 432 { 433 size_t len; 434 int mib[2]; 435 436 _thr_umtx_init(&_mutex_static_lock); 437 _thr_umtx_init(&_cond_static_lock); 438 _thr_umtx_init(&_rwlock_static_lock); 439 _thr_umtx_init(&_keytable_lock); 440 _thr_umtx_init(&_thr_atfork_lock); 441 _thr_umtx_init(&_thr_event_lock); 442 _thr_spinlock_init(); 443 _thr_list_init(); 444 _thr_timer_init(); 445 446 /* 447 * Avoid reinitializing some things if they don't need to be, 448 * e.g. after a fork(). 449 */ 450 if (init_once == 0) { 451 /* Find the stack top */ 452 mib[0] = CTL_KERN; 453 mib[1] = KERN_USRSTACK; 454 len = sizeof (_usrstack); 455 if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1) 456 PANIC("Cannot get kern.usrstack from sysctl"); 457 _thr_page_size = getpagesize(); 458 _thr_guard_default = _thr_page_size; 459 _pthread_attr_default.guardsize_attr = _thr_guard_default; 460 _pthread_attr_default.stacksize_attr = _thr_stack_default; 461 462 TAILQ_INIT(&_thr_atfork_list); 463 #ifdef SYSTEM_SCOPE_ONLY 464 _thr_scope_system = 1; 465 #else 466 if (getenv("LIBPTHREAD_SYSTEM_SCOPE") != NULL) 467 _thr_scope_system = 1; 468 else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL) 469 _thr_scope_system = -1; 470 #endif 471 } 472 init_once = 1; 473 } 474