Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_kthread.c
Show First 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | kproc_create(void (*func)(void *), void *arg, | ||||
struct thread *td; | struct thread *td; | ||||
struct proc *p2; | struct proc *p2; | ||||
if (!proc0.p_stats) | if (!proc0.p_stats) | ||||
panic("kproc_create called too soon"); | panic("kproc_create called too soon"); | ||||
bzero(&fr, sizeof(fr)); | bzero(&fr, sizeof(fr)); | ||||
fr.fr_flags = RFMEM | RFFDG | RFPROC | RFSTOPPED | flags; | fr.fr_flags = RFMEM | RFFDG | RFPROC | RFSTOPPED | flags; | ||||
fr.fr_flags2 = FR2_KPROC; | |||||
fr.fr_pages = pages; | fr.fr_pages = pages; | ||||
fr.fr_procp = &p2; | fr.fr_procp = &p2; | ||||
error = fork1(&thread0, &fr); | error = fork1(&thread0, &fr); | ||||
if (error) | if (error) | ||||
return error; | return error; | ||||
/* save a global descriptor, if desired */ | /* save a global descriptor, if desired */ | ||||
if (newpp != NULL) | if (newpp != NULL) | ||||
*newpp = p2; | *newpp = p2; | ||||
/* this is a non-swapped system process */ | |||||
PROC_LOCK(p2); | |||||
td = FIRST_THREAD_IN_PROC(p2); | |||||
p2->p_flag |= P_SYSTEM | P_KPROC; | |||||
td->td_pflags |= TDP_KTHREAD; | |||||
mtx_lock(&p2->p_sigacts->ps_mtx); | |||||
p2->p_sigacts->ps_flag |= PS_NOCLDWAIT; | |||||
mtx_unlock(&p2->p_sigacts->ps_mtx); | |||||
PROC_UNLOCK(p2); | |||||
/* set up arg0 for 'ps', et al */ | /* set up arg0 for 'ps', et al */ | ||||
va_start(ap, fmt); | va_start(ap, fmt); | ||||
vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap); | vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap); | ||||
va_end(ap); | va_end(ap); | ||||
/* set up arg0 for 'ps', et al */ | td = FIRST_THREAD_IN_PROC(p2); | ||||
va_start(ap, fmt); | va_start(ap, fmt); | ||||
vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap); | vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap); | ||||
va_end(ap); | va_end(ap); | ||||
#ifdef KTR | #ifdef KTR | ||||
sched_clear_tdname(td); | sched_clear_tdname(td); | ||||
#endif | #endif | ||||
TSTHREAD(td, td->td_name); | TSTHREAD(td, td->td_name); | ||||
#ifdef HWPMC_HOOKS | #ifdef HWPMC_HOOKS | ||||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | kthread_add(void (*func)(void *), void *arg, struct proc *p, | ||||
/* set up arg0 for 'ps', et al */ | /* set up arg0 for 'ps', et al */ | ||||
va_start(ap, fmt); | va_start(ap, fmt); | ||||
vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap); | vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap); | ||||
va_end(ap); | va_end(ap); | ||||
TSTHREAD(newtd, newtd->td_name); | TSTHREAD(newtd, newtd->td_name); | ||||
newtd->td_proc = p; /* needed for cpu_copy_thread */ | newtd->td_proc = p; /* needed for cpu_copy_thread */ | ||||
newtd->td_pflags |= TDP_KTHREAD; | |||||
/* might be further optimized for kthread */ | /* might be further optimized for kthread */ | ||||
cpu_copy_thread(newtd, oldtd); | cpu_copy_thread(newtd, oldtd); | ||||
/* put the designated function(arg) as the resume context */ | /* put the designated function(arg) as the resume context */ | ||||
cpu_fork_kthread_handler(newtd, func, arg); | cpu_fork_kthread_handler(newtd, func, arg); | ||||
newtd->td_pflags |= TDP_KTHREAD; | |||||
thread_cow_get_proc(newtd, p); | thread_cow_get_proc(newtd, p); | ||||
/* this code almost the same as create_thread() in kern_thr.c */ | /* this code almost the same as create_thread() in kern_thr.c */ | ||||
p->p_flag |= P_HADTHREADS; | p->p_flag |= P_HADTHREADS; | ||||
thread_link(newtd, p); | thread_link(newtd, p); | ||||
thread_lock(oldtd); | thread_lock(oldtd); | ||||
/* let the scheduler know about these things. */ | /* let the scheduler know about these things. */ | ||||
sched_fork_thread(oldtd, newtd); | sched_fork_thread(oldtd, newtd); | ||||
▲ Show 20 Lines • Show All 182 Lines • Show Last 20 Lines |