* Create a kernel process/thread/whatever. It shares its address space * with proc0 - ie: kernel only. * * func is the function to start. * arg is the parameter to pass to function on first startup. * newpp is the return value pointing to the thread's struct proc. * flags are flags to fork1 (in unistd.h) * fmt and following will be *printf'd into (*newpp)->p_comm (for ps, etc.). */
| 81 | * fmt and following will be *printf'd into (*newpp)->p_comm (for ps, etc.). |
| 82 | */ |
| 83 | int |
| 84 | kproc_create(void (*func)(void *), void *arg, |
| 85 | struct proc **newpp, int flags, int pages, const char *fmt, ...) |
| 86 | { |
| 87 | struct fork_req fr; |
| 88 | int error; |
| 89 | va_list ap; |
| 90 | struct thread *td; |
| 91 | struct proc *p2; |
| 92 | |
| 93 | if (!proc0.p_stats) |
| 94 | panic("kproc_create called too soon"); |
| 95 | |
| 96 | bzero(&fr, sizeof(fr)); |
| 97 | fr.fr_flags = RFMEM | RFFDG | RFPROC | RFSTOPPED | flags; |
| 98 | fr.fr_pages = pages; |
| 99 | fr.fr_procp = &p2; |
| 100 | error = fork1(&thread0, &fr); |
| 101 | if (error) |
| 102 | return error; |
| 103 | |
| 104 | /* save a global descriptor, if desired */ |
| 105 | if (newpp != NULL) |
| 106 | *newpp = p2; |
| 107 | |
| 108 | /* this is a non-swapped system process */ |
| 109 | PROC_LOCK(p2); |
| 110 | td = FIRST_THREAD_IN_PROC(p2); |
| 111 | p2->p_flag |= P_SYSTEM | P_KPROC; |
| 112 | td->td_pflags |= TDP_KTHREAD; |
| 113 | mtx_lock(&p2->p_sigacts->ps_mtx); |
| 114 | p2->p_sigacts->ps_flag |= PS_NOCLDWAIT; |
| 115 | mtx_unlock(&p2->p_sigacts->ps_mtx); |
| 116 | PROC_UNLOCK(p2); |
| 117 | |
| 118 | /* set up arg0 for 'ps', et al */ |
| 119 | va_start(ap, fmt); |
| 120 | vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap); |
| 121 | va_end(ap); |
| 122 | /* set up arg0 for 'ps', et al */ |
| 123 | va_start(ap, fmt); |
| 124 | vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap); |
| 125 | va_end(ap); |
| 126 | #ifdef KTR |
| 127 | sched_clear_tdname(td); |
| 128 | #endif |
| 129 | TSTHREAD(td, td->td_name); |
| 130 | #ifdef HWPMC_HOOKS |
| 131 | if (PMC_SYSTEM_SAMPLING_ACTIVE()) { |
| 132 | PMC_CALL_HOOK_UNLOCKED(td, PMC_FN_PROC_CREATE_LOG, p2); |
| 133 | PMC_CALL_HOOK_UNLOCKED(td, PMC_FN_THR_CREATE_LOG, NULL); |
| 134 | } |
| 135 | #endif |
| 136 | |
| 137 | /* call the processes' main()... */ |
| 138 | cpu_fork_kthread_handler(td, func, arg); |
| 139 | |
| 140 | /* Avoid inheriting affinity from a random parent. */ |
no test coverage detected