thr_init.c revision 139023
17857Sgibbs/* 27857Sgibbs * Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org> 34568Sgibbs * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> 47857Sgibbs * All rights reserved. 57857Sgibbs * 67857Sgibbs * Redistribution and use in source and binary forms, with or without 77857Sgibbs * modification, are permitted provided that the following conditions 87857Sgibbs * are met: 97857Sgibbs * 1. Redistributions of source code must retain the above copyright 107857Sgibbs * notice, this list of conditions and the following disclaimer. 117857Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 127857Sgibbs * notice, this list of conditions and the following disclaimer in the 137857Sgibbs * documentation and/or other materials provided with the distribution. 147857Sgibbs * 3. All advertising materials mentioning features or use of this software 157857Sgibbs * must display the following acknowledgement: 167857Sgibbs * This product includes software developed by John Birrell. 177857Sgibbs * 4. Neither the name of the author nor the names of any co-contributors 187857Sgibbs * may be used to endorse or promote products derived from this software 197857Sgibbs * without specific prior written permission. 207857Sgibbs * 217857Sgibbs * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 227857Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 237857Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 247857Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 257857Sgibbs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 267857Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 277857Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 287857Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 297857Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 307857Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 317857Sgibbs * SUCH DAMAGE. 327857Sgibbs * 337857Sgibbs * $FreeBSD: head/lib/libkse/thread/thr_init.c 139023 2004-12-18 18:07:37Z deischen $ 347857Sgibbs */ 357857Sgibbs 367857Sgibbs/* Allocate space for global thread variables here: */ 377857Sgibbs#define GLOBAL_PTHREAD_PRIVATE 384568Sgibbs 396608Sgibbs#include "namespace.h" 406608Sgibbs#include <sys/param.h> 415647Sgibbs#include <sys/types.h> 427857Sgibbs#include <sys/signalvar.h> 434568Sgibbs#include <machine/reg.h> 449917Sgibbs 455647Sgibbs#include <sys/ioctl.h> 469928Sgibbs#include <sys/mount.h> 474568Sgibbs#include <sys/uio.h> 484568Sgibbs#include <sys/socket.h> 498104Sgibbs#include <sys/event.h> 504568Sgibbs#include <sys/stat.h> 514568Sgibbs#include <sys/sysctl.h> 524568Sgibbs#include <sys/time.h> 534568Sgibbs#include <sys/ttycom.h> 544568Sgibbs#include <sys/wait.h> 554568Sgibbs#include <sys/mman.h> 564568Sgibbs#include <dirent.h> 574568Sgibbs#include <errno.h> 584568Sgibbs#include <fcntl.h> 594568Sgibbs#include <paths.h> 604568Sgibbs#include <pthread.h> 618104Sgibbs#include <pthread_np.h> 624568Sgibbs#include <signal.h> 638104Sgibbs#include <stdio.h> 648104Sgibbs#include <stdlib.h> 654568Sgibbs#include <string.h> 664568Sgibbs#include <unistd.h> 679928Sgibbs#include "un-namespace.h" 684568Sgibbs 694568Sgibbs#include "libc_private.h" 704568Sgibbs#include "thr_private.h" 714568Sgibbs 724568Sgibbsint __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); 734568Sgibbsint __pthread_mutex_lock(pthread_mutex_t *); 744568Sgibbsint __pthread_mutex_trylock(pthread_mutex_t *); 754568Sgibbsvoid _thread_init_hack(void); 764568Sgibbsextern int _thread_state_running; 774568Sgibbs 784568Sgibbsstatic void init_private(void); 794568Sgibbsstatic void init_main_thread(struct pthread *thread); 804568Sgibbs 814568Sgibbs/* 824568Sgibbs * All weak references used within libc should be in this table. 837532Sgibbs * This is so that static libraries will work. 847532Sgibbs */ 857532Sgibbsstatic void *references[] = { 864568Sgibbs &_accept, 874568Sgibbs &_bind, 884568Sgibbs &_close, 894568Sgibbs &_connect, 904568Sgibbs &_dup, 914568Sgibbs &_dup2, 924568Sgibbs &_execve, 934568Sgibbs &_fcntl, 944568Sgibbs &_flock, 954568Sgibbs &_flockfile, 964568Sgibbs &_fstat, 974568Sgibbs &_fstatfs, 984568Sgibbs &_fsync, 995326Sgibbs &_funlockfile, 1005326Sgibbs &_getdirentries, 1014568Sgibbs &_getlogin, 1024568Sgibbs &_getpeername, 1039928Sgibbs &_getsockname, 1049928Sgibbs &_getsockopt, 1059928Sgibbs &_ioctl, 1069928Sgibbs &_kevent, 1079928Sgibbs &_listen, 1084568Sgibbs &_nanosleep, 1094568Sgibbs &_open, 1105647Sgibbs &_pthread_getspecific, 1115647Sgibbs &_pthread_key_create, 1125647Sgibbs &_pthread_key_delete, 1139928Sgibbs &_pthread_mutex_destroy, 1146608Sgibbs &_pthread_mutex_init, 1159928Sgibbs &_pthread_mutex_lock, 1165647Sgibbs &_pthread_mutex_trylock, 1175647Sgibbs &_pthread_mutex_unlock, 1184568Sgibbs &_pthread_mutexattr_init, 1194568Sgibbs &_pthread_mutexattr_destroy, 1204568Sgibbs &_pthread_mutexattr_settype, 1215647Sgibbs &_pthread_once, 1225647Sgibbs &_pthread_setspecific, 1235647Sgibbs &_read, 1244568Sgibbs &_readv, 1255647Sgibbs &_recvfrom, 1265647Sgibbs &_recvmsg, 1275647Sgibbs &_select, 1284568Sgibbs &_sendmsg, 1295647Sgibbs &_sendto, 1305647Sgibbs &_setsockopt, 1314568Sgibbs &_sigaction, 1324568Sgibbs &_sigprocmask, 1334568Sgibbs &_sigsuspend, 1344568Sgibbs &_socket, 1354568Sgibbs &_socketpair, 1364568Sgibbs &_thread_init_hack, 1374568Sgibbs &_wait4, 1384568Sgibbs &_write, 1394568Sgibbs &_writev 1404568Sgibbs}; 1414568Sgibbs 1424568Sgibbs/* 1435647Sgibbs * These are needed when linking statically. All references within 1447532Sgibbs * libgcc (and in the future libc) to these routines are weak, but 1457532Sgibbs * if they are not (strongly) referenced by the application or other 1467532Sgibbs * libraries, then the actual functions will not be loaded. 1478104Sgibbs */ 1484568Sgibbsstatic void *libgcc_references[] = { 1495647Sgibbs &_pthread_once, 1508104Sgibbs &_pthread_key_create, 1515647Sgibbs &_pthread_key_delete, 1525647Sgibbs &_pthread_getspecific, 1535647Sgibbs &_pthread_setspecific, 1545647Sgibbs &_pthread_mutex_init, 1555647Sgibbs &_pthread_mutex_destroy, 1565647Sgibbs &_pthread_mutex_lock, 1575647Sgibbs &_pthread_mutex_trylock, 1587532Sgibbs &_pthread_mutex_unlock 1597562Sgibbs}; 1608567Sdg 1618567Sdg#define DUAL_ENTRY(entry) \ 1628567Sdg (pthread_func_t)entry, (pthread_func_t)entry 1638567Sdg 1648567Sdgstatic pthread_func_t jmp_table[][2] = { 1659810Sgibbs {DUAL_ENTRY(_pthread_cond_broadcast)}, /* PJT_COND_BROADCAST */ 1664568Sgibbs {DUAL_ENTRY(_pthread_cond_destroy)}, /* PJT_COND_DESTROY */ 1678567Sdg {DUAL_ENTRY(_pthread_cond_init)}, /* PJT_COND_INIT */ 1684568Sgibbs {DUAL_ENTRY(_pthread_cond_signal)}, /* PJT_COND_SIGNAL */ 1695326Sgibbs {(pthread_func_t)__pthread_cond_wait, 1705326Sgibbs (pthread_func_t)_pthread_cond_wait}, /* PJT_COND_WAIT */ 1714568Sgibbs {DUAL_ENTRY(_pthread_getspecific)}, /* PJT_GETSPECIFIC */ 1724568Sgibbs {DUAL_ENTRY(_pthread_key_create)}, /* PJT_KEY_CREATE */ 1735326Sgibbs {DUAL_ENTRY(_pthread_key_delete)}, /* PJT_KEY_DELETE*/ 1745326Sgibbs {DUAL_ENTRY(_pthread_main_np)}, /* PJT_MAIN_NP */ 1759928Sgibbs {DUAL_ENTRY(_pthread_mutex_destroy)}, /* PJT_MUTEX_DESTROY */ 1769928Sgibbs {DUAL_ENTRY(_pthread_mutex_init)}, /* PJT_MUTEX_INIT */ 1779928Sgibbs {(pthread_func_t)__pthread_mutex_lock, 1789928Sgibbs (pthread_func_t)_pthread_mutex_lock}, /* PJT_MUTEX_LOCK */ 1799928Sgibbs {(pthread_func_t)__pthread_mutex_trylock, 1804568Sgibbs (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */ 1818104Sgibbs {DUAL_ENTRY(_pthread_mutex_unlock)}, /* PJT_MUTEX_UNLOCK */ 1828104Sgibbs {DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */ 1834568Sgibbs {DUAL_ENTRY(_pthread_mutexattr_init)}, /* PJT_MUTEXATTR_INIT */ 1845562Sgibbs {DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */ 1854568Sgibbs {DUAL_ENTRY(_pthread_once)}, /* PJT_ONCE */ 1864568Sgibbs {DUAL_ENTRY(_pthread_rwlock_destroy)}, /* PJT_RWLOCK_DESTROY */ 1874568Sgibbs {DUAL_ENTRY(_pthread_rwlock_init)}, /* PJT_RWLOCK_INIT */ 1884568Sgibbs {DUAL_ENTRY(_pthread_rwlock_rdlock)}, /* PJT_RWLOCK_RDLOCK */ 1898104Sgibbs {DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */ 1909928Sgibbs {DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */ 1919928Sgibbs {DUAL_ENTRY(_pthread_rwlock_unlock)}, /* PJT_RWLOCK_UNLOCK */ 1929928Sgibbs {DUAL_ENTRY(_pthread_rwlock_wrlock)}, /* PJT_RWLOCK_WRLOCK */ 1934568Sgibbs {DUAL_ENTRY(_pthread_self)}, /* PJT_SELF */ 1944568Sgibbs {DUAL_ENTRY(_pthread_setspecific)}, /* PJT_SETSPECIFIC */ 1954568Sgibbs {DUAL_ENTRY(_pthread_sigmask)} /* PJT_SIGMASK */ 1964568Sgibbs}; 1974568Sgibbs 1984568Sgibbsstatic int init_once = 0; 1995326Sgibbs 2005326Sgibbs/* 2014568Sgibbs * Threaded process initialization. 2026608Sgibbs * 2036608Sgibbs * This is only called under two conditions: 2046608Sgibbs * 2056608Sgibbs * 1) Some thread routines have detected that the library hasn't yet 2066608Sgibbs * been initialized (_thr_initial == NULL && curthread == NULL), or 2076608Sgibbs * 2086608Sgibbs * 2) An explicit call to reinitialize after a fork (indicated 2097562Sgibbs * by curthread != NULL) 2104568Sgibbs */ 2116608Sgibbsvoid 2125647Sgibbs_libpthread_init(struct pthread *curthread) 2136608Sgibbs{ 2144568Sgibbs int fd; 2156608Sgibbs 2164568Sgibbs /* Check if this function has already been called: */ 2175647Sgibbs if ((_thr_initial != NULL) && (curthread == NULL)) 2185647Sgibbs /* Only initialize the threaded application once. */ 2195647Sgibbs return; 2209928Sgibbs 2215647Sgibbs /* 2229928Sgibbs * Make gcc quiescent about {,libgcc_}references not being 2236608Sgibbs * referenced: 2246608Sgibbs */ 2256608Sgibbs if ((references[0] == NULL) || (libgcc_references[0] == NULL)) 2266608Sgibbs PANIC("Failed loading mandatory references in _thread_init"); 2276608Sgibbs 2286608Sgibbs /* Pull debug symbols in for static binary */ 2294568Sgibbs _thread_state_running = PS_RUNNING; 2306608Sgibbs 2316608Sgibbs /* 2325326Sgibbs * Check the size of the jump table to make sure it is preset 2335326Sgibbs * with the correct number of entries. 2349928Sgibbs */ 2358567Sdg if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2)) 2365562Sgibbs PANIC("Thread jump table not properly initialized"); 2375562Sgibbs memcpy(__thr_jtable, jmp_table, sizeof(jmp_table)); 2385562Sgibbs 2394568Sgibbs /* 2408567Sdg * Check for the special case of this process running as 2418567Sdg * or in place of init as pid = 1: 2428567Sdg */ 2436608Sgibbs if ((_thr_pid = getpid()) == 1) { 2446608Sgibbs /* 2458104Sgibbs * Setup a new session for this process which is 2468104Sgibbs * assumed to be running as root. 2478104Sgibbs */ 2488104Sgibbs if (setsid() == -1) 2498104Sgibbs PANIC("Can't set session ID"); 2508104Sgibbs if (revoke(_PATH_CONSOLE) != 0) 2518104Sgibbs PANIC("Can't revoke console"); 2528104Sgibbs if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) 2538104Sgibbs PANIC("Can't open console"); 2548104Sgibbs if (setlogin("root") == -1) 2558104Sgibbs PANIC("Can't set login to root"); 2568104Sgibbs if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1) 2578104Sgibbs PANIC("Can't set controlling terminal"); 2589395Sgibbs } 2599395Sgibbs 2608104Sgibbs /* Initialize pthread private data. */ 2618104Sgibbs init_private(); 2628104Sgibbs _kse_init(); 2638104Sgibbs 2648104Sgibbs /* Initialize the initial kse and kseg. */ 2658104Sgibbs _kse_initial = _kse_alloc(NULL, _thread_scope_system > 0); 2668104Sgibbs if (_kse_initial == NULL) 2679395Sgibbs PANIC("Can't allocate initial kse."); 2688104Sgibbs _kse_initial->k_kseg = _kseg_alloc(NULL); 2698104Sgibbs if (_kse_initial->k_kseg == NULL) 2704866Sgibbs PANIC("Can't allocate initial kseg."); 2714568Sgibbs _kse_initial->k_kseg->kg_flags |= KGF_SINGLE_THREAD; 2724568Sgibbs _kse_initial->k_schedq = &_kse_initial->k_kseg->kg_schedq; 2738104Sgibbs 2745326Sgibbs TAILQ_INSERT_TAIL(&_kse_initial->k_kseg->kg_kseq, _kse_initial, k_kgqe); 2755326Sgibbs _kse_initial->k_kseg->kg_ksecount = 1; 2765326Sgibbs 2775326Sgibbs /* Set the initial thread. */ 2788104Sgibbs if (curthread == NULL) { 2795326Sgibbs /* Create and initialize the initial thread. */ 2805326Sgibbs curthread = _thr_alloc(NULL); 2818104Sgibbs if (curthread == NULL) 2829395Sgibbs PANIC("Can't allocate initial thread"); 2838104Sgibbs _thr_initial = curthread; 2844568Sgibbs init_main_thread(curthread); 2858104Sgibbs } else { 2868104Sgibbs /* 2878104Sgibbs * The initial thread is the current thread. It is 2888104Sgibbs * assumed that the current thread is already initialized 2898104Sgibbs * because it is left over from a fork(). 2904568Sgibbs */ 2914568Sgibbs _thr_initial = curthread; 2924568Sgibbs } 2935647Sgibbs _kse_initial->k_kseg->kg_threadcount = 0; 2945647Sgibbs _thr_initial->kse = _kse_initial; 2955647Sgibbs _thr_initial->kseg = _kse_initial->k_kseg; 2968104Sgibbs _thr_initial->active = 1; 2975647Sgibbs 2985647Sgibbs /* 2995647Sgibbs * Add the thread to the thread list and to the KSEG's thread 3005647Sgibbs * queue. 3018104Sgibbs */ 3028104Sgibbs THR_LIST_ADD(_thr_initial); 3038104Sgibbs KSEG_THRQ_ADD(_kse_initial->k_kseg, _thr_initial); 3048104Sgibbs 3055647Sgibbs /* Setup the KSE/thread specific data for the current KSE/thread. */ 3065647Sgibbs _thr_initial->kse->k_curthread = _thr_initial; 3075647Sgibbs _kcb_set(_thr_initial->kse->k_kcb); 3085647Sgibbs _tcb_set(_thr_initial->kse->k_kcb, _thr_initial->tcb); 3097532Sgibbs _thr_initial->kse->k_flags |= KF_INITIALIZED; 3105647Sgibbs 3115647Sgibbs _thr_signal_init(); 3125647Sgibbs _kse_critical_leave(&_thr_initial->tcb->tcb_tmbx); 3137532Sgibbs /* 3149928Sgibbs * activate threaded mode as soon as possible if we are 3159928Sgibbs * being debugged 3169928Sgibbs */ 3179928Sgibbs if (_libkse_debug) 3188104Sgibbs _kse_setthreaded(1); 3194568Sgibbs} 3205326Sgibbs 3215326Sgibbs/* 3225326Sgibbs * This function and pthread_create() do a lot of the same things. 3235326Sgibbs * It'd be nice to consolidate the common stuff in one place. 3245326Sgibbs */ 3255326Sgibbsstatic void 3265326Sgibbsinit_main_thread(struct pthread *thread) 3274568Sgibbs{ 3285647Sgibbs /* Setup the thread attributes. */ 3294568Sgibbs thread->attr = _pthread_attr_default; 3304568Sgibbs thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; 3315326Sgibbs /* 3325326Sgibbs * Set up the thread stack. 3335326Sgibbs * 3349928Sgibbs * Create a red zone below the main stack. All other stacks 3355326Sgibbs * are constrained to a maximum size by the parameters 3365326Sgibbs * passed to mmap(), but this stack is only limited by 3375326Sgibbs * resource limits, so this stack needs an explicitly mapped 3384568Sgibbs * red zone to protect the thread stack that is just beyond. 3395326Sgibbs */ 3404568Sgibbs if (mmap((void *)_usrstack - THR_STACK_INITIAL - 3418104Sgibbs _thr_guard_default, _thr_guard_default, 0, MAP_ANON, 3424568Sgibbs -1, 0) == MAP_FAILED) 3438104Sgibbs PANIC("Cannot allocate red zone for initial thread"); 3448104Sgibbs 3458104Sgibbs /* 3468104Sgibbs * Mark the stack as an application supplied stack so that it 3478104Sgibbs * isn't deallocated. 3485326Sgibbs * 3495326Sgibbs * XXX - I'm not sure it would hurt anything to deallocate 3509928Sgibbs * the main thread stack because deallocation doesn't 3515326Sgibbs * actually free() it; it just puts it in the free 3525326Sgibbs * stack queue for later reuse. 3535326Sgibbs */ 3546940Sgibbs thread->attr.stackaddr_attr = (void *)_usrstack - THR_STACK_INITIAL; 3556940Sgibbs thread->attr.stacksize_attr = THR_STACK_INITIAL; 3566940Sgibbs thread->attr.guardsize_attr = _thr_guard_default; 3576940Sgibbs thread->attr.flags |= THR_STACK_USER; 3588104Sgibbs 3598104Sgibbs /* 3608104Sgibbs * Write a magic value to the thread structure 3618104Sgibbs * to help identify valid ones: 3628104Sgibbs */ 3638104Sgibbs thread->magic = THR_MAGIC; 3648104Sgibbs 3658104Sgibbs thread->slice_usec = -1; 3668104Sgibbs thread->cancelflags = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; 3678104Sgibbs thread->name = strdup("initial thread"); 3689928Sgibbs 3694568Sgibbs /* Initialize the thread for signals: */ 3704568Sgibbs SIGEMPTYSET(thread->sigmask); 3714568Sgibbs 3724568Sgibbs /* 3734568Sgibbs * Set up the thread mailbox. The threads saved context 3744866Sgibbs * is also in the mailbox. 3754568Sgibbs */ 3764568Sgibbs thread->tcb->tcb_tmbx.tm_udata = thread; 3774568Sgibbs thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_size = 3784568Sgibbs thread->attr.stacksize_attr; 3798567Sdg thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_sp = 3808567Sdg thread->attr.stackaddr_attr; 3818567Sdg 3828567Sdg /* Default the priority of the initial thread: */ 3838567Sdg thread->base_priority = THR_DEFAULT_PRIORITY; 3848567Sdg thread->active_priority = THR_DEFAULT_PRIORITY; 3858567Sdg thread->inherited_priority = 0; 3868567Sdg 3879917Sgibbs /* Initialize the mutex queue: */ 3888567Sdg TAILQ_INIT(&thread->mutexq); 3898567Sdg 3909928Sgibbs /* Initialize hooks in the thread structure: */ 3914568Sgibbs thread->specific = NULL; 3924568Sgibbs thread->cleanup = NULL; 3939928Sgibbs thread->flags = 0; 3944568Sgibbs thread->sigbackout = NULL; 3954568Sgibbs thread->continuation = NULL; 3964568Sgibbs 3979928Sgibbs thread->state = PS_RUNNING; 3984568Sgibbs thread->uniqueid = 0; 3994568Sgibbs} 4006608Sgibbs 4016608Sgibbsstatic void 4026608Sgibbsinit_private(void) 4036608Sgibbs{ 4046608Sgibbs struct clockinfo clockinfo; 4056608Sgibbs size_t len; 4066608Sgibbs int mib[2]; 4076608Sgibbs 4086608Sgibbs /* 4096608Sgibbs * Avoid reinitializing some things if they don't need to be, 4106608Sgibbs * e.g. after a fork(). 4116608Sgibbs */ 4126608Sgibbs if (init_once == 0) { 4136608Sgibbs /* Find the stack top */ 4146608Sgibbs mib[0] = CTL_KERN; 4156608Sgibbs mib[1] = KERN_USRSTACK; 4164568Sgibbs len = sizeof (_usrstack); 4179917Sgibbs if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1) 4189917Sgibbs PANIC("Cannot get kern.usrstack from sysctl"); 4199917Sgibbs /* Get the kernel clockrate: */ 4209917Sgibbs mib[0] = CTL_KERN; 4214568Sgibbs mib[1] = KERN_CLOCKRATE; 4228104Sgibbs len = sizeof (struct clockinfo); 4234568Sgibbs if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0) 4244568Sgibbs _clock_res_usec = clockinfo.tick; 4254568Sgibbs else 4264568Sgibbs _clock_res_usec = CLOCK_RES_USEC; 4278104Sgibbs 4285562Sgibbs _thr_page_size = getpagesize(); 4298104Sgibbs _thr_guard_default = _thr_page_size; 4304568Sgibbs init_once = 1; /* Don't do this again. */ 4318104Sgibbs } else { 4328104Sgibbs /* 4338104Sgibbs * Destroy the locks before creating them. We don't 4348104Sgibbs * know what state they are in so it is better to just 4354568Sgibbs * recreate them. 4368104Sgibbs */ 4378104Sgibbs _lock_destroy(&_thread_signal_lock); 4388104Sgibbs _lock_destroy(&_mutex_static_lock); 4398104Sgibbs _lock_destroy(&_rwlock_static_lock); 4408104Sgibbs _lock_destroy(&_keytable_lock); 4418104Sgibbs } 4428104Sgibbs 4438104Sgibbs /* Initialize everything else. */ 4444568Sgibbs TAILQ_INIT(&_thread_list); 4454568Sgibbs TAILQ_INIT(&_thread_gc_list); 4464568Sgibbs TAILQ_INIT(&_thr_atfork_list); 4474568Sgibbs _pthread_mutex_init(&_thr_atfork_mutex, NULL); 4484568Sgibbs 4494568Sgibbs /* 4504568Sgibbs * Initialize the lock for temporary installation of signal 4514568Sgibbs * handlers (to support sigwait() semantics) and for the 4524568Sgibbs * process signal mask and pending signal sets. 4534568Sgibbs */ 4544568Sgibbs if (_lock_init(&_thread_signal_lock, LCK_ADAPTIVE, 4554568Sgibbs _kse_lock_wait, _kse_lock_wakeup) != 0) 4564568Sgibbs PANIC("Cannot initialize _thread_signal_lock"); 4574568Sgibbs if (_lock_init(&_mutex_static_lock, LCK_ADAPTIVE, 4584568Sgibbs _thr_lock_wait, _thr_lock_wakeup) != 0) 4594568Sgibbs PANIC("Cannot initialize mutex static init lock"); 4604568Sgibbs if (_lock_init(&_rwlock_static_lock, LCK_ADAPTIVE, 4614568Sgibbs _thr_lock_wait, _thr_lock_wakeup) != 0) 4624568Sgibbs PANIC("Cannot initialize rwlock static init lock"); 4634568Sgibbs if (_lock_init(&_keytable_lock, LCK_ADAPTIVE, 4644568Sgibbs _thr_lock_wait, _thr_lock_wakeup) != 0) 4654568Sgibbs PANIC("Cannot initialize thread specific keytable lock"); 4664568Sgibbs _thr_spinlock_init(); 4674568Sgibbs 4684568Sgibbs /* Clear pending signals and get the process signal mask. */ 4695647Sgibbs SIGEMPTYSET(_thr_proc_sigpending); 4704568Sgibbs 4714568Sgibbs /* Are we in M:N mode (default) or 1:1 mode? */ 4724568Sgibbs#ifdef SYSTEM_SCOPE_ONLY 4739928Sgibbs _thread_scope_system = 1; 4749928Sgibbs#else 4759928Sgibbs if (getenv("LIBPTHREAD_SYSTEM_SCOPE") != NULL) 4764568Sgibbs _thread_scope_system = 1; 4779928Sgibbs else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL) 4789928Sgibbs _thread_scope_system = -1; 4799928Sgibbs#endif 4809928Sgibbs 4819928Sgibbs /* 4829928Sgibbs * _thread_list_lock and _kse_count are initialized 4834568Sgibbs * by _kse_init() 4849928Sgibbs */ 4859928Sgibbs} 4869928Sgibbs