FreeBSD/sys/kern/kern_fork.c
/*
 * Handle the return of a child process from fork1().  This function
 * is called from the MD fork_trampoline() entry point.
 */
Handle the return of a child process from fork1().  This function
is called from the MD fork_trampoline() entry point.
Handle the return of a child process from fork1 () . This function is called from the MD fork_trampoline () entry point .
void
fork_exit(void (*callout)(void *, struct trapframe *), void *arg,
    struct trapframe *frame)
{
	struct proc *p;
	struct thread *td;
	struct thread *dtd;
	td = curthread;
	p = td->td_proc;
	KASSERT(p->p_state == PRS_NORMAL, ("executing process is still new"));
	CTR4(KTR_PROC, "fork_exit: new thread %p (td_sched %p, pid %d, %s)",
	    td, td_get_sched(td), p->p_pid, td->td_name);
	sched_fork_exit(td);
	if ((dtd = PCPU_GET(deadthread))) {
		PCPU_SET(deadthread, NULL);
		thread_stash(dtd);
	}
	thread_unlock(td);
	KASSERT(callout != NULL, ("NULL callout in fork_exit"));
	callout(arg, frame);
	if (p->p_flag & P_KPROC) {
		printf("Kernel thread \"%s\" (pid %d) exited prematurely.\n",
		    td->td_name, p->p_pid);
		kthread_exit();
	}
	mtx_assert(&Giant, MA_NOTOWNED);
	if (p->p_sysent->sv_schedtail != NULL)
		(p->p_sysent->sv_schedtail)(td);
	td->td_pflags &= ~TDP_FORKING;
}
void fork_exit ( void ( * callout ) ( void * , struct trapframe * ) , void * arg , struct trapframe * frame ) { struct proc * p ; struct thread * td ; struct thread * dtd ; td = curthread ; p = td -> td_proc ; KASSERT ( p -> p_state == PRS_NORMAL , ( " " ) ) ; CTR4 ( KTR_PROC , " " , td , td_get_sched ( td ) , p -> p_pid , td -> td_name ) ; sched_fork_exit ( td ) ; if ( ( dtd = PCPU_GET ( deadthread ) ) ) { PCPU_SET ( deadthread , NULL ) ; thread_stash ( dtd ) ; } thread_unlock ( td ) ; KASSERT ( callout != NULL , ( " " ) ) ; callout ( arg , frame ) ; if ( p -> p_flag & P_KPROC ) { printf ( " \" \" \n " , td -> td_name , p -> p_pid ) ; kthread_exit ( ) ; } mtx_assert ( & Giant , MA_NOTOWNED ) ; if ( p -> p_sysent -> sv_schedtail != NULL ) ( p -> p_sysent -> sv_schedtail ) ( td ) ; td -> td_pflags &= ~ TDP_FORKING ; }
Handle the return of a child process from fork1().
Handle the return of a child process from fork1 () .
/*
	* Processes normally resume in mi_switch() after being
	* cpu_switch()'ed to, but when children start up they arrive here
	* instead, so we must do much the same things as mi_switch() would.
	*/ /*
	 * cpu_fork_kthread_handler intercepts this function call to
	 * have this call a non-return function to stay in kernel mode.
	 * initproc has its own fork handler, but it does return.
	 */ /*
	 * Check if a kernel thread misbehaved and returned from its main
	 * function.
	 */