167754Smsmith/*
267754Smsmith * Copyright (c) 2003 Daniel M. Eischen <deischen@freebsd.org>
367754Smsmith * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
477424Smsmith * All rights reserved.
577424Smsmith *
677424Smsmith * Redistribution and use in source and binary forms, with or without
767754Smsmith * modification, are permitted provided that the following conditions
867754Smsmith * are met:
967754Smsmith * 1. Redistributions of source code must retain the above copyright
1067754Smsmith *    notice, this list of conditions and the following disclaimer.
1167754Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1267754Smsmith *    notice, this list of conditions and the following disclaimer in the
1367754Smsmith *    documentation and/or other materials provided with the distribution.
1467754Smsmith * 3. Neither the name of the author nor the names of any co-contributors
15202771Sjkim *    may be used to endorse or promote products derived from this software
1670243Smsmith *    without specific prior written permission.
1767754Smsmith *
1867754Smsmith * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
1967754Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2067754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2167754Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2267754Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2367754Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2467754Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2567754Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2667754Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2767754Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2867754Smsmith * SUCH DAMAGE.
2967754Smsmith *
3067754Smsmith * $FreeBSD$
3167754Smsmith */
3267754Smsmith
3367754Smsmith/* Allocate space for global thread variables here: */
3467754Smsmith#define GLOBAL_PTHREAD_PRIVATE
3567754Smsmith
3685756Smsmith#include "namespace.h"
3785756Smsmith#include <sys/param.h>
3867754Smsmith#include <sys/types.h>
3967754Smsmith#include <sys/signalvar.h>
4067754Smsmith#include <machine/reg.h>
4167754Smsmith
4267754Smsmith#include <sys/ioctl.h>
4367754Smsmith#include <sys/mount.h>
4467754Smsmith#include <sys/uio.h>
4567754Smsmith#include <sys/socket.h>
4667754Smsmith#include <sys/event.h>
4767754Smsmith#include <sys/stat.h>
4867754Smsmith#include <sys/sysctl.h>
4967754Smsmith#include <sys/time.h>
5067754Smsmith#include <sys/ttycom.h>
5167754Smsmith#include <sys/wait.h>
5267754Smsmith#include <sys/mman.h>
5367754Smsmith#include <dirent.h>
5467754Smsmith#include <errno.h>
5567754Smsmith#include <fcntl.h>
5667754Smsmith#include <paths.h>
5767754Smsmith#include <pthread.h>
5867754Smsmith#include <pthread_np.h>
5967754Smsmith#include <signal.h>
6067754Smsmith#include <stdio.h>
6167754Smsmith#include <stdlib.h>
6267754Smsmith#include <string.h>
6367754Smsmith#include <unistd.h>
6467754Smsmith#include "un-namespace.h"
6567754Smsmith
6667754Smsmith#include "libc_private.h"
6767754Smsmith#include "thr_private.h"
6867754Smsmith
6967754Smsmithint	__pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
7067754Smsmithint	__pthread_mutex_lock(pthread_mutex_t *);
7167754Smsmithint	__pthread_mutex_trylock(pthread_mutex_t *);
7267754Smsmithvoid	_thread_init_hack(void);
7367754Smsmithextern int _thread_state_running;
7467754Smsmith
7567754Smsmithstatic void init_private(void);
7667754Smsmithstatic void init_main_thread(struct pthread *thread);
7767754Smsmith
7867754Smsmith/*
7967754Smsmith * All weak references used within libc should be in this table.
8067754Smsmith * This is so that static libraries will work.
8167754Smsmith */
8267754Smsmithstatic void *references[] = {
8367754Smsmith	&_accept,
8467754Smsmith	&_bind,
8567754Smsmith	&_close,
8667754Smsmith	&_connect,
8767754Smsmith	&_dup,
8867754Smsmith	&_dup2,
8967754Smsmith	&_execve,
9067754Smsmith	&_fcntl,
9167754Smsmith	&_flock,
9267754Smsmith	&_flockfile,
9367754Smsmith	&_fstat,
9467754Smsmith	&_fstatfs,
9567754Smsmith	&_fsync,
9667754Smsmith	&_funlockfile,
9767754Smsmith	&_getdirentries,
9867754Smsmith	&_getlogin,
9967754Smsmith	&_getpeername,
10067754Smsmith	&_getsockname,
10167754Smsmith	&_getsockopt,
10267754Smsmith	&_ioctl,
10367754Smsmith	&_kevent,
10467754Smsmith	&_listen,
10567754Smsmith	&_nanosleep,
10667754Smsmith	&_open,
10767754Smsmith	&_pthread_getspecific,
10867754Smsmith	&_pthread_key_create,
10967754Smsmith	&_pthread_key_delete,
11067754Smsmith	&_pthread_mutex_destroy,
11167754Smsmith	&_pthread_mutex_init,
11267754Smsmith	&_pthread_mutex_lock,
11367754Smsmith	&_pthread_mutex_trylock,
11467754Smsmith	&_pthread_mutex_unlock,
11567754Smsmith	&_pthread_mutexattr_init,
11667754Smsmith	&_pthread_mutexattr_destroy,
11767754Smsmith	&_pthread_mutexattr_settype,
11867754Smsmith	&_pthread_once,
11967754Smsmith	&_pthread_setspecific,
12067754Smsmith	&_read,
12177424Smsmith	&_readv,
12277424Smsmith	&_recvfrom,
12367754Smsmith	&_recvmsg,
124193341Sjkim	&_select,
125193341Sjkim	&_sendmsg,
12667754Smsmith	&_sendto,
12767754Smsmith	&_setsockopt,
128167802Sjkim	&_sigaction,
12967754Smsmith	&_sigprocmask,
130167802Sjkim	&_sigsuspend,
131167802Sjkim	&_socket,
132167802Sjkim	&_socketpair,
133167802Sjkim	&_thread_init_hack,
134167802Sjkim	&_wait4,
135167802Sjkim	&_write,
136167802Sjkim	&_writev
137167802Sjkim};
13867754Smsmith
139167802Sjkim/*
140167802Sjkim * These are needed when linking statically.  All references within
14177424Smsmith * libgcc (and in the future libc) to these routines are weak, but
14277424Smsmith * if they are not (strongly) referenced by the application or other
14367754Smsmith * libraries, then the actual functions will not be loaded.
14467754Smsmith */
14580062Smsmithstatic void *libgcc_references[] = {
14680062Smsmith	&_pthread_once,
14780062Smsmith	&_pthread_key_create,
14880062Smsmith	&_pthread_key_delete,
14980062Smsmith	&_pthread_getspecific,
150114237Snjl	&_pthread_setspecific,
15180062Smsmith	&_pthread_mutex_init,
15280062Smsmith	&_pthread_mutex_destroy,
15380062Smsmith	&_pthread_mutex_lock,
15480062Smsmith	&_pthread_mutex_trylock,
15580062Smsmith	&_pthread_mutex_unlock
15680062Smsmith};
15780062Smsmith
15880062Smsmith#define	DUAL_ENTRY(entry)	\
15967754Smsmith	(pthread_func_t)entry, (pthread_func_t)entry
16077424Smsmith
16167754Smsmithstatic pthread_func_t jmp_table[][2] = {
16267754Smsmith	{DUAL_ENTRY(_pthread_atfork)},	/* PJT_ATFORK */
16367754Smsmith	{DUAL_ENTRY(_pthread_attr_destroy)},	/* PJT_ATTR_DESTROY */
16467754Smsmith	{DUAL_ENTRY(_pthread_attr_getdetachstate)},	/* PJT_ATTR_GETDETACHSTATE */
16567754Smsmith	{DUAL_ENTRY(_pthread_attr_getguardsize)},	/* PJT_ATTR_GETGUARDSIZE */
16667754Smsmith	{DUAL_ENTRY(_pthread_attr_getinheritsched)},	/* PJT_ATTR_GETINHERITSCHED */
16767754Smsmith	{DUAL_ENTRY(_pthread_attr_getschedparam)},	/* PJT_ATTR_GETSCHEDPARAM */
16867754Smsmith	{DUAL_ENTRY(_pthread_attr_getschedpolicy)},	/* PJT_ATTR_GETSCHEDPOLICY */
16967754Smsmith	{DUAL_ENTRY(_pthread_attr_getscope)},	/* PJT_ATTR_GETSCOPE */
17099146Siwasaki	{DUAL_ENTRY(_pthread_attr_getstackaddr)},	/* PJT_ATTR_GETSTACKADDR */
17199146Siwasaki	{DUAL_ENTRY(_pthread_attr_getstacksize)},	/* PJT_ATTR_GETSTACKSIZE */
17299146Siwasaki	{DUAL_ENTRY(_pthread_attr_init)},	/* PJT_ATTR_INIT */
17399146Siwasaki	{DUAL_ENTRY(_pthread_attr_setdetachstate)},	/* PJT_ATTR_SETDETACHSTATE */
174167802Sjkim	{DUAL_ENTRY(_pthread_attr_setguardsize)},	/* PJT_ATTR_SETGUARDSIZE */
17580062Smsmith	{DUAL_ENTRY(_pthread_attr_setinheritsched)},	/* PJT_ATTR_SETINHERITSCHED */
176167802Sjkim	{DUAL_ENTRY(_pthread_attr_setschedparam)},	/* PJT_ATTR_SETSCHEDPARAM */
17777424Smsmith	{DUAL_ENTRY(_pthread_attr_setschedpolicy)},	/* PJT_ATTR_SETSCHEDPOLICY */
17899146Siwasaki	{DUAL_ENTRY(_pthread_attr_setscope)},	/* PJT_ATTR_SETSCOPE */
179114237Snjl	{DUAL_ENTRY(_pthread_attr_setstackaddr)},	/* PJT_ATTR_SETSTACKADDR */
180114237Snjl	{DUAL_ENTRY(_pthread_attr_setstacksize)},	/* PJT_ATTR_SETSTACKSIZE */
181114237Snjl	{DUAL_ENTRY(_pthread_cancel)},	/* PJT_CANCEL */
182114237Snjl	{DUAL_ENTRY(_pthread_cleanup_pop)},	/* PJT_CLEANUP_POP */
183114237Snjl	{DUAL_ENTRY(_pthread_cleanup_push)},	/* PJT_CLEANUP_PUSH */
18499146Siwasaki	{DUAL_ENTRY(_pthread_cond_broadcast)},	/* PJT_COND_BROADCAST */
18599146Siwasaki	{DUAL_ENTRY(_pthread_cond_destroy)},	/* PJT_COND_DESTROY */
18699146Siwasaki	{DUAL_ENTRY(_pthread_cond_init)},	/* PJT_COND_INIT */
18780062Smsmith	{DUAL_ENTRY(_pthread_cond_signal)},	/* PJT_COND_SIGNAL */
18899146Siwasaki	{DUAL_ENTRY(_pthread_cond_timedwait)},	/* PJT_COND_TIMEDWAIT */
18967754Smsmith	{(pthread_func_t)__pthread_cond_wait,
190167802Sjkim	 (pthread_func_t)_pthread_cond_wait},	/* PJT_COND_WAIT */
19167754Smsmith	{DUAL_ENTRY(_pthread_detach)},	/* PJT_DETACH */
19267754Smsmith	{DUAL_ENTRY(_pthread_equal)},	/* PJT_EQUAL */
193167802Sjkim	{DUAL_ENTRY(_pthread_exit)},	/* PJT_EXIT */
194167802Sjkim	{DUAL_ENTRY(_pthread_getspecific)},	/* PJT_GETSPECIFIC */
195167802Sjkim	{DUAL_ENTRY(_pthread_join)},	/* PJT_JOIN */
196167802Sjkim	{DUAL_ENTRY(_pthread_key_create)},	/* PJT_KEY_CREATE */
197167802Sjkim	{DUAL_ENTRY(_pthread_key_delete)},	/* PJT_KEY_DELETE*/
198167802Sjkim	{DUAL_ENTRY(_pthread_kill)},	/* PJT_KILL */
199167802Sjkim	{DUAL_ENTRY(_pthread_main_np)},		/* PJT_MAIN_NP */
200167802Sjkim	{DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */
201167802Sjkim	{DUAL_ENTRY(_pthread_mutexattr_init)},	/* PJT_MUTEXATTR_INIT */
202167802Sjkim	{DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */
203167802Sjkim	{DUAL_ENTRY(_pthread_mutex_destroy)},	/* PJT_MUTEX_DESTROY */
204167802Sjkim	{DUAL_ENTRY(_pthread_mutex_init)},	/* PJT_MUTEX_INIT */
205167802Sjkim	{(pthread_func_t)__pthread_mutex_lock,
206167802Sjkim	 (pthread_func_t)_pthread_mutex_lock},	/* PJT_MUTEX_LOCK */
207167802Sjkim	{(pthread_func_t)__pthread_mutex_trylock,
208167802Sjkim	 (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */
209167802Sjkim	{DUAL_ENTRY(_pthread_mutex_unlock)},	/* PJT_MUTEX_UNLOCK */
210167802Sjkim	{DUAL_ENTRY(_pthread_once)},		/* PJT_ONCE */
211167802Sjkim	{DUAL_ENTRY(_pthread_rwlock_destroy)},	/* PJT_RWLOCK_DESTROY */
212167802Sjkim	{DUAL_ENTRY(_pthread_rwlock_init)},	/* PJT_RWLOCK_INIT */
213167802Sjkim	{DUAL_ENTRY(_pthread_rwlock_rdlock)},	/* PJT_RWLOCK_RDLOCK */
21467754Smsmith	{DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */
21567754Smsmith	{DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */
21667754Smsmith	{DUAL_ENTRY(_pthread_rwlock_unlock)},	/* PJT_RWLOCK_UNLOCK */
217167802Sjkim	{DUAL_ENTRY(_pthread_rwlock_wrlock)},	/* PJT_RWLOCK_WRLOCK */
21867754Smsmith	{DUAL_ENTRY(_pthread_self)},		/* PJT_SELF */
21967754Smsmith	{DUAL_ENTRY(_pthread_setcancelstate)},	/* PJT_SETCANCELSTATE */
22067754Smsmith	{DUAL_ENTRY(_pthread_setcanceltype)},	/* PJT_SETCANCELTYPE */
221167802Sjkim	{DUAL_ENTRY(_pthread_setspecific)},	/* PJT_SETSPECIFIC */
22267754Smsmith	{DUAL_ENTRY(_pthread_sigmask)},		/* PJT_SIGMASK */
22367754Smsmith	{DUAL_ENTRY(_pthread_testcancel)}	/* PJT_TESTCANCEL */
22467754Smsmith};
225167802Sjkim
22667754Smsmithstatic int	init_once = 0;
227107325Siwasaki
22867754Smsmith/*
22967754Smsmith * Threaded process initialization.
23067754Smsmith *
231167802Sjkim * This is only called under two conditions:
23267754Smsmith *
23367754Smsmith *   1) Some thread routines have detected that the library hasn't yet
234167802Sjkim *      been initialized (_thr_initial == NULL && curthread == NULL), or
235167802Sjkim *
236193267Sjkim *   2) An explicit call to reinitialize after a fork (indicated
237193267Sjkim *      by curthread != NULL)
238167802Sjkim */
239193267Sjkimvoid
240193267Sjkim_libpthread_init(struct pthread *curthread)
241117521Snjl{
242167802Sjkim	int fd;
243167802Sjkim
24477424Smsmith	/* Check if this function has already been called: */
245117521Snjl	if ((_thr_initial != NULL) && (curthread == NULL))
246167802Sjkim		/* Only initialize the threaded application once. */
247167802Sjkim		return;
248117521Snjl
249167802Sjkim	/*
250167802Sjkim	 * Make gcc quiescent about {,libgcc_}references not being
251167802Sjkim	 * referenced:
252167802Sjkim	 */
253117521Snjl	if ((references[0] == NULL) || (libgcc_references[0] == NULL))
254117521Snjl		PANIC("Failed loading mandatory references in _thread_init");
255167802Sjkim
256167802Sjkim	/* Pull debug symbols in for static binary */
257193267Sjkim	_thread_state_running = PS_RUNNING;
258117521Snjl
259117521Snjl	/*
26067754Smsmith	 * Check the size of the jump table to make sure it is preset
26167754Smsmith	 * with the correct number of entries.
26267754Smsmith	 */
26367754Smsmith	if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2))
26467754Smsmith		PANIC("Thread jump table not properly initialized");
26591116Smsmith	memcpy(__thr_jtable, jmp_table, sizeof(jmp_table));
26667754Smsmith
26767754Smsmith	/*
26867754Smsmith	 * Check for the special case of this process running as
26967754Smsmith	 * or in place of init as pid = 1:
27067754Smsmith	 */
271167802Sjkim	if ((_thr_pid = getpid()) == 1) {
27267754Smsmith		/*
273167802Sjkim		 * Setup a new session for this process which is
274193267Sjkim		 * assumed to be running as root.
27567754Smsmith		 */
27667754Smsmith		if (setsid() == -1)
27767754Smsmith			PANIC("Can't set session ID");
27867754Smsmith		if (revoke(_PATH_CONSOLE) != 0)
27991116Smsmith			PANIC("Can't revoke console");
28067754Smsmith		if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
28171867Smsmith			PANIC("Can't open console");
28271867Smsmith		if (setlogin("root") == -1)
28371867Smsmith			PANIC("Can't set login to root");
28471867Smsmith		if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1)
28567754Smsmith			PANIC("Can't set controlling terminal");
28677424Smsmith	}
28767754Smsmith
288151937Sjkim	/* Initialize pthread private data. */
28967754Smsmith	init_private();
290151937Sjkim	_kse_init();
291151937Sjkim
292151937Sjkim	/* Initialize the initial kse and kseg. */
293151937Sjkim	_kse_initial = _kse_alloc(NULL, _thread_scope_system > 0);
294151937Sjkim	if (_kse_initial == NULL)
295151937Sjkim		PANIC("Can't allocate initial kse.");
29667754Smsmith	_kse_initial->k_kseg = _kseg_alloc(NULL);
29767754Smsmith	if (_kse_initial->k_kseg == NULL)
298151937Sjkim		PANIC("Can't allocate initial kseg.");
299151937Sjkim	_kse_initial->k_kseg->kg_flags |= KGF_SINGLE_THREAD;
300151937Sjkim	_kse_initial->k_schedq = &_kse_initial->k_kseg->kg_schedq;
301151937Sjkim
302151937Sjkim	TAILQ_INSERT_TAIL(&_kse_initial->k_kseg->kg_kseq, _kse_initial, k_kgqe);
303151937Sjkim	_kse_initial->k_kseg->kg_ksecount = 1;
304151937Sjkim
305151937Sjkim	/* Set the initial thread. */
306151937Sjkim	if (curthread == NULL) {
307151937Sjkim		/* Create and initialize the initial thread. */
308151937Sjkim		curthread = _thr_alloc(NULL);
309151937Sjkim		if (curthread == NULL)
310151937Sjkim			PANIC("Can't allocate initial thread");
311151937Sjkim		_thr_initial = curthread;
312151937Sjkim		init_main_thread(curthread);
313151937Sjkim	} else {
314151937Sjkim		/*
315151937Sjkim		 * The initial thread is the current thread.  It is
316151937Sjkim		 * assumed that the current thread is already initialized
317151937Sjkim		 * because it is left over from a fork().
318151937Sjkim		 */
31967754Smsmith		_thr_initial = curthread;
32067754Smsmith	}
321138287Smarks	_kse_initial->k_kseg->kg_threadcount = 0;
32267754Smsmith	_thr_initial->kse = _kse_initial;
32367754Smsmith	_thr_initial->kseg = _kse_initial->k_kseg;
32467754Smsmith	_thr_initial->active = 1;
32567754Smsmith
32667754Smsmith	/*
327138287Smarks	 * Add the thread to the thread list and to the KSEG's thread
32867754Smsmith         * queue.
32967754Smsmith	 */
33067754Smsmith	THR_LIST_ADD(_thr_initial);
33177424Smsmith	KSEG_THRQ_ADD(_kse_initial->k_kseg, _thr_initial);
33267754Smsmith
333167802Sjkim	/* Setup the KSE/thread specific data for the current KSE/thread. */
33477424Smsmith	_thr_initial->kse->k_curthread = _thr_initial;
33577424Smsmith	_kcb_set(_thr_initial->kse->k_kcb);
33677424Smsmith	_tcb_set(_thr_initial->kse->k_kcb, _thr_initial->tcb);
33767754Smsmith	_thr_initial->kse->k_flags |= KF_INITIALIZED;
338167802Sjkim
339167802Sjkim	_thr_signal_init();
340138287Smarks	_kse_critical_leave(&_thr_initial->tcb->tcb_tmbx);
34167754Smsmith	/*
34267754Smsmith	 * activate threaded mode as soon as possible if we are
34367754Smsmith	 * being debugged
344138287Smarks	 */
345138287Smarks	if (_libkse_debug)
346138287Smarks		_kse_setthreaded(1);
347138287Smarks}
34867754Smsmith
349202771Sjkim/*
35067754Smsmith * This function and pthread_create() do a lot of the same things.
35167754Smsmith * It'd be nice to consolidate the common stuff in one place.
35280062Smsmith */
35367754Smsmithstatic void
35467754Smsmithinit_main_thread(struct pthread *thread)
35577424Smsmith{
35667754Smsmith	/* Setup the thread attributes. */
35780062Smsmith	thread->attr = _pthread_attr_default;
35867754Smsmith	thread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
35980062Smsmith	/*
36080062Smsmith	 * Set up the thread stack.
36180062Smsmith	 *
362117521Snjl	 * Create a red zone below the main stack.  All other stacks
36380062Smsmith	 * are constrained to a maximum size by the parameters
36467754Smsmith	 * passed to mmap(), but this stack is only limited by
36580062Smsmith	 * resource limits, so this stack needs an explicitly mapped
36680062Smsmith	 * red zone to protect the thread stack that is just beyond.
36780062Smsmith	 */
368117521Snjl	if (mmap((void *)((uintptr_t)_usrstack - _thr_stack_initial -
36980062Smsmith	    _thr_guard_default), _thr_guard_default, 0, MAP_ANON,
37067754Smsmith	    -1, 0) == MAP_FAILED)
37167754Smsmith		PANIC("Cannot allocate red zone for initial thread");
37267754Smsmith
37380062Smsmith	/*
37467754Smsmith	 * Mark the stack as an application supplied stack so that it
37580062Smsmith	 * isn't deallocated.
37680062Smsmith	 *
37780062Smsmith	 * XXX - I'm not sure it would hurt anything to deallocate
378117521Snjl	 *       the main thread stack because deallocation doesn't
37980062Smsmith	 *       actually free() it; it just puts it in the free
38067754Smsmith	 *       stack queue for later reuse.
38180062Smsmith	 */
38280062Smsmith	thread->attr.stackaddr_attr = (void *)((uintptr_t)_usrstack -
38380062Smsmith	     _thr_stack_initial);
384117521Snjl	thread->attr.stacksize_attr = _thr_stack_initial;
38580062Smsmith	thread->attr.guardsize_attr = _thr_guard_default;
38667754Smsmith	thread->attr.flags |= THR_STACK_USER;
38767754Smsmith
38867754Smsmith	/*
38980062Smsmith	 * Write a magic value to the thread structure
390138287Smarks	 * to help identify valid ones:
391138287Smarks	 */
39267754Smsmith	thread->magic = THR_MAGIC;
39367754Smsmith
39480062Smsmith	thread->slice_usec = -1;
39580062Smsmith	thread->cancelflags = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED;
396138287Smarks	thread->name = strdup("initial thread");
39780062Smsmith
39880062Smsmith	/* Initialize the thread for signals: */
39967754Smsmith	SIGEMPTYSET(thread->sigmask);
40067754Smsmith
40180062Smsmith	/*
40280062Smsmith	 * Set up the thread mailbox.  The threads saved context
403138287Smarks	 * is also in the mailbox.
404202771Sjkim	 */
40580062Smsmith	thread->tcb->tcb_tmbx.tm_udata = thread;
40667754Smsmith	thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_size =
407167802Sjkim	    thread->attr.stacksize_attr;
408114237Snjl	thread->tcb->tcb_tmbx.tm_context.uc_stack.ss_sp =
409114237Snjl	    thread->attr.stackaddr_attr;
410114237Snjl
411114237Snjl	/* Default the priority of the initial thread: */
412114237Snjl	thread->base_priority = THR_DEFAULT_PRIORITY;
413138287Smarks	thread->active_priority = THR_DEFAULT_PRIORITY;
414138287Smarks	thread->inherited_priority = 0;
415114237Snjl
41667754Smsmith	/* Initialize the mutex queue: */
417167802Sjkim	TAILQ_INIT(&thread->mutexq);
41867754Smsmith
41967754Smsmith	/* Initialize hooks in the thread structure: */
42067754Smsmith	thread->specific = NULL;
421167802Sjkim	thread->cleanup = NULL;
422167802Sjkim	thread->flags = 0;
423167802Sjkim	thread->sigbackout = NULL;
424167802Sjkim	thread->continuation = NULL;
42567754Smsmith
42667754Smsmith	thread->state = PS_RUNNING;
42767754Smsmith	thread->uniqueid = 0;
428117521Snjl}
42967754Smsmith
43067754Smsmithstatic void
43167754Smsmithinit_private(void)
43267754Smsmith{
433117521Snjl	struct clockinfo clockinfo;
43467754Smsmith	size_t len;
435138287Smarks	int mib[2];
43678986Smsmith
43778986Smsmith	/*
43867754Smsmith	 * Avoid reinitializing some things if they don't need to be,
43980062Smsmith	 * e.g. after a fork().
44080062Smsmith	 */
44180062Smsmith	if (init_once == 0) {
44280062Smsmith		/* Find the stack top */
44378986Smsmith		mib[0] = CTL_KERN;
444167802Sjkim		mib[1] = KERN_USRSTACK;
44567754Smsmith		len = sizeof (_usrstack);
44667754Smsmith		if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1)
44767754Smsmith			PANIC("Cannot get kern.usrstack from sysctl");
44892388Smsmith		/* Get the kernel clockrate: */
44967754Smsmith		mib[0] = CTL_KERN;
450114237Snjl		mib[1] = KERN_CLOCKRATE;
45167754Smsmith		len = sizeof (struct clockinfo);
45267754Smsmith		if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0)
45391116Smsmith			_clock_res_usec = 1000000 / clockinfo.stathz;
45467754Smsmith		else
455114237Snjl			_clock_res_usec = CLOCK_RES_USEC;
45667754Smsmith
45767754Smsmith		_thr_page_size = getpagesize();
458100966Siwasaki		_thr_guard_default = _thr_page_size;
459100966Siwasaki		if (sizeof(void *) == 8) {
460100966Siwasaki			_thr_stack_default = THR_STACK64_DEFAULT;
46177424Smsmith			_thr_stack_initial = THR_STACK64_INITIAL;
462100966Siwasaki		}
46367754Smsmith		else {
46467754Smsmith			_thr_stack_default = THR_STACK32_DEFAULT;
46567754Smsmith			_thr_stack_initial = THR_STACK32_INITIAL;
46667754Smsmith		}
46767754Smsmith		_pthread_attr_default.guardsize_attr = _thr_guard_default;
468114237Snjl		_pthread_attr_default.stacksize_attr = _thr_stack_default;
46967754Smsmith		TAILQ_INIT(&_thr_atfork_list);
47067754Smsmith		init_once = 1;	/* Don't do this again. */
47167754Smsmith	} else {
472114237Snjl		/*
473114237Snjl		 * Destroy the locks before creating them.  We don't
474114237Snjl		 * know what state they are in so it is better to just
475114237Snjl		 * recreate them.
476114237Snjl		 */
477114237Snjl		_lock_destroy(&_thread_signal_lock);
478114237Snjl		_lock_destroy(&_mutex_static_lock);
479114237Snjl		_lock_destroy(&_rwlock_static_lock);
480114237Snjl		_lock_destroy(&_keytable_lock);
481114237Snjl	}
482114237Snjl
483114237Snjl	/* Initialize everything else. */
484114237Snjl	TAILQ_INIT(&_thread_list);
485114237Snjl	TAILQ_INIT(&_thread_gc_list);
486114237Snjl	_pthread_mutex_init(&_thr_atfork_mutex, NULL);
487114237Snjl
488114237Snjl	/*
489114237Snjl	 * Initialize the lock for temporary installation of signal
490114237Snjl	 * handlers (to support sigwait() semantics) and for the
491114237Snjl	 * process signal mask and pending signal sets.
492114237Snjl	 */
493114237Snjl	if (_lock_init(&_thread_signal_lock, LCK_ADAPTIVE,
49467754Smsmith	    _kse_lock_wait, _kse_lock_wakeup, calloc) != 0)
49577424Smsmith		PANIC("Cannot initialize _thread_signal_lock");
496	if (_lock_init(&_mutex_static_lock, LCK_ADAPTIVE,
497	    _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
498		PANIC("Cannot initialize mutex static init lock");
499	if (_lock_init(&_rwlock_static_lock, LCK_ADAPTIVE,
500	    _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
501		PANIC("Cannot initialize rwlock static init lock");
502	if (_lock_init(&_keytable_lock, LCK_ADAPTIVE,
503	    _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
504		PANIC("Cannot initialize thread specific keytable lock");
505	_thr_spinlock_init();
506
507	/* Clear pending signals and get the process signal mask. */
508	SIGEMPTYSET(_thr_proc_sigpending);
509
510	/* Are we in M:N mode (default) or 1:1 mode? */
511#ifdef SYSTEM_SCOPE_ONLY
512	_thread_scope_system = 1;
513#else
514	if (getenv("LIBPTHREAD_SYSTEM_SCOPE") != NULL)
515		_thread_scope_system = 1;
516	else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL)
517		_thread_scope_system = -1;
518#endif
519	if (getenv("LIBPTHREAD_DEBUG") != NULL)
520		_thr_debug_flags |= DBG_INFO_DUMP;
521
522	/*
523	 * _thread_list_lock and _kse_count are initialized
524	 * by _kse_init()
525	 */
526}
527