/* * Threaded process initialization. * * This is only called under two conditions: * * 1) Some thread routines have detected that the library hasn't yet * been initialized (_thr_initial == NULL && curthread == NULL), or * * 2) An explicit call to reinitialize after a fork (indicated * by curthread != NULL) */ void _libpthread_init(struct pthread *curthread) { int fd; /* Check if this function has already been called: */ if ((_thr_initial != NULL) && (curthread == NULL)) /* Only initialize the threaded application once. */ return; /* * Make gcc quiescent about {,libgcc_}references not being * referenced: */ if ((references[0] == NULL) || (libgcc_references[0] == NULL)) PANIC("Failed loading mandatory references in _thread_init"); /* Pull debug symbols in for static binary */ _thread_state_running = PS_RUNNING; /* * Check the size of the jump table to make sure it is preset * with the correct number of entries. */ if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2)) PANIC("Thread jump table not properly initialized"); memcpy(__thr_jtable, jmp_table, sizeof(jmp_table)); /* * Check for the special case of this process running as * or in place of init as pid = 1: */ if ((_thr_pid = getpid()) == 1) { /* * Setup a new session for this process which is * assumed to be running as root. */ if (setsid() == -1) PANIC("Can't set session ID"); if (revoke(_PATH_CONSOLE) != 0) PANIC("Can't revoke console"); if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) PANIC("Can't open console"); if (setlogin("root") == -1) PANIC("Can't set login to root"); if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1) PANIC("Can't set controlling terminal"); } /* Initialize pthread private data. */ init_private(); _kse_init(); /* Initialize the initial kse and kseg. */ _kse_initial = _kse_alloc(NULL, _thread_scope_system > 0); if (_kse_initial == NULL) PANIC("Can't allocate initial kse."); _kse_initial->k_kseg = _kseg_alloc(NULL); if (_kse_initial->k_kseg == NULL) PANIC("Can't allocate initial kseg."); _kse_initial->k_kseg->kg_flags |= KGF_SINGLE_THREAD; _kse_initial->k_schedq = &_kse_initial->k_kseg->kg_schedq; TAILQ_INSERT_TAIL(&_kse_initial->k_kseg->kg_kseq, _kse_initial, k_kgqe); _kse_initial->k_kseg->kg_ksecount = 1; /* Set the initial thread. */ if (curthread == NULL) { /* Create and initialize the initial thread. */ curthread = _thr_alloc(NULL); if (curthread == NULL) PANIC("Can't allocate initial thread"); _thr_initial = curthread; init_main_thread(curthread); } else { /* * The initial thread is the current thread. It is * assumed that the current thread is already initialized * because it is left over from a fork(). */ _thr_initial = curthread; } _kse_initial->k_kseg->kg_threadcount = 0; _thr_initial->kse = _kse_initial; _thr_initial->kseg = _kse_initial->k_kseg; _thr_initial->active = 1; /* * Add the thread to the thread list and to the KSEG's thread * queue. */ THR_LIST_ADD(_thr_initial); KSEG_THRQ_ADD(_kse_initial->k_kseg, _thr_initial); /* Setup the KSE/thread specific data for the current KSE/thread. */ _thr_initial->kse->k_curthread = _thr_initial; _kcb_set(_thr_initial->kse->k_kcb); _tcb_set(_thr_initial->kse->k_kcb, _thr_initial->tcb); _thr_initial->kse->k_flags |= KF_INITIALIZED; _thr_signal_init(); _kse_critical_leave(&_thr_initial->tcb->tcb_tmbx); /* * activate threaded mode as soon as possible if we are * being debugged */ if (_libkse_debug) _kse_setthreaded(1); }
/* * Threaded process initialization. * * This is only called under two conditions: * * 1) Some thread routines have detected that the library hasn't yet * been initialized (_thr_initial == NULL && curthread == NULL), or * * 2) An explicit call to reinitialize after a fork (indicated * by curthread != NULL) */ void _libpthread_init(struct pthread *curthread) { int fd, first = 0; sigset_t sigset, oldset; /* Check if this function has already been called: */ if ((_thr_initial != NULL) && (curthread == NULL)) /* Only initialize the threaded application once. */ return; /* * Check for the special case of this process running as * or in place of init as pid = 1: */ if ((_thr_pid = getpid()) == 1) { /* * Setup a new session for this process which is * assumed to be running as root. */ if (setsid() == -1) PANIC("Can't set session ID"); if (revoke(_PATH_CONSOLE) != 0) PANIC("Can't revoke console"); if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) PANIC("Can't open console"); if (setlogin("root") == -1) PANIC("Can't set login to root"); if (__sys_ioctl(fd, TIOCSCTTY, NULL) == -1) PANIC("Can't set controlling terminal"); } /* Initialize pthread private data. */ init_private(); /* Set the initial thread. */ if (curthread == NULL) { first = 1; /* Create and initialize the initial thread. */ curthread = _thr_alloc(NULL); if (curthread == NULL) PANIC("Can't allocate initial thread"); init_main_thread(curthread); } /* * Add the thread to the thread list queue. */ THR_LIST_ADD(curthread); _thread_active_threads = 1; /* Setup the thread specific data */ tls_set_tcb(curthread->tcb); if (first) { SIGFILLSET(sigset); __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset); _thr_signal_init(); _thr_initial = curthread; SIGDELSET(oldset, SIGCANCEL); __sys_sigprocmask(SIG_SETMASK, &oldset, NULL); if (td_eventismember(&_thread_event_mask, TD_CREATE)) _thr_report_creation(curthread, curthread); } }