#ifndef _SYS_PROC_H_
#define _SYS_PROC_H_
#if !defined(_KERNEL) && !defined(_KERNEL_STRUCTURES)
#error "Userland must include sys/user.h instead of sys/proc.h"
#else
#include <sys/callout.h>
#include <sys/cpumask.h>
#include <sys/filedesc.h>
#include <sys/queue.h>
#include <sys/tree.h>
#include <sys/rtprio.h>
#include <sys/signal.h>
#include <sys/lock.h>
#include <sys/upmap.h>
#ifndef _KERNEL
#include <sys/time.h>
#endif
#include <sys/ucred.h>
#include <sys/event.h>
#include <sys/eventvar.h>
#include <sys/proc_common.h>
#include <sys/sysent.h>
#include <sys/thread.h>
#include <sys/varsym.h>
#include <sys/resourcevar.h>
#ifdef _KERNEL
#include <sys/procctl.h>
#include <sys/globaldata.h>
#endif
#include <sys/systimer.h>
#include <sys/iosched.h>
#include <sys/usched.h>
#include <machine/proc.h>
#include <machine/atomic.h>
#include <sys/signalvar.h>
struct proc;
struct pgrp;
struct session;
struct lwp;
struct uidcount;
struct procglob;
struct vm_map_backing;
LIST_HEAD(proclist, proc);
LIST_HEAD(pgrplist, pgrp);
LIST_HEAD(sesslist, session);
LIST_HEAD(lwplist, lwp);
struct lwp_rb_tree;
RB_HEAD(lwp_rb_tree, lwp);
RB_PROTOTYPE2(lwp_rb_tree, lwp, u.lwp_rbnode, rb_lwp_compare, lwpid_t);
struct session {
LIST_ENTRY(session) s_list;
int s_count;
struct procglob *s_prg;
struct proc *s_leader;
struct vnode *s_ttyvp;
struct tty *s_ttyp;
pid_t s_sid;
char s_login[roundup(MAXLOGNAME, sizeof(long))];
};
struct pgrp {
LIST_ENTRY(pgrp) pg_list;
struct proclist pg_members;
struct session *pg_session;
struct sigiolst pg_sigiolst;
pid_t pg_id;
int pg_jobc;
u_int pg_refs;
struct lwkt_token pg_token;
struct lock pg_lock;
};
#define PS_NOCLDWAIT 0x0001
#define PS_NOCLDSTOP 0x0002
#define PS_CLDSIGIGN 0x0004
struct pargs {
u_int ar_ref;
u_int ar_length;
u_char ar_args[0];
};
struct jail;
struct vkernel_proc;
struct vkernel_lwp;
struct vmspace_entry;
struct ktrace_node;
struct sem_undo;
struct lwp {
TAILQ_ENTRY(lwp) lwp_procq;
union {
RB_ENTRY(lwp) lwp_rbnode;
LIST_ENTRY(lwp) lwp_reap_entry;
} u;
struct proc *lwp_proc;
struct vmspace *lwp_vmspace;
struct vkernel_lwp *lwp_vkernel;
lwpid_t lwp_tid;
u_int lwp_flags;
u_int lwp_mpflags;
enum lwpstat lwp_stat;
int lwp_lock;
int lwp_unused01;
int lwp_sig;
u_long lwp_code;
sysclock_t lwp_cpticks;
fixpt_t lwp_pctcpu;
u_int lwp_slptime;
u_int lwp_rebal_ticks;
int lwp_traceflag;
struct rusage lwp_ru;
union usched_data lwp_usdata;
#define lwp_startcopy lwp_cpumask
cpumask_t lwp_cpumask;
sigset_t lwp_siglist;
sigset_t lwp_oldsigmask;
sigset_t lwp_sigmask;
stack_t lwp_sigstk;
struct rtprio lwp_rtprio;
struct mdproc lwp_md;
#define lwp_endcopy lwp_md
struct thread *lwp_thread;
struct sys_lpmap *lwp_lpmap;
struct kqueue lwp_kqueue;
uint64_t lwp_kqueue_serial;
struct lwkt_token lwp_token;
struct spinlock lwp_spin;
TAILQ_HEAD(, vm_map_backing) lwp_lpmap_backing_list;
sysclock_t lwp_cpbase;
};
struct proc {
LIST_ENTRY(proc) p_list;
struct ucred *p_ucred;
struct filedesc *p_fd;
struct filedesc_to_leader *p_fdtol;
struct plimit *p_limit;
#define p_rlimit p_limit->pl_rlimit
struct pstats *p_stats;
u_int p_mqueue_cnt;
long p_waitgen;
struct sigacts *p_sigacts;
#define p_sigignore p_sigacts->ps_sigignore
#define p_sigcatch p_sigacts->ps_sigcatch
int p_flags;
enum procstat p_stat;
char p_advlock_flag;
char p_pad1[2];
pid_t p_pid;
pid_t p_ppid;
LIST_ENTRY(proc) p_pglist;
struct proc *p_pptr;
LIST_ENTRY(proc) p_sibling;
struct proclist p_children;
struct callout p_ithandle;
struct varsymset p_varsymset;
struct iosched_data p_iosdata;
pid_t p_oppid;
struct vmspace *p_vmspace;
unsigned int p_swtime;
struct itimerval p_realtimer;
struct itimerval p_timer[3];
int p_traceflag;
struct ktrace_node *p_tracenode;
sigset_t p_siglist;
struct vnode *p_textvp;
struct nchandle p_textnch;
unsigned int p_stops;
unsigned int p_stype;
char p_step;
unsigned char p_pfsflags;
char p_pad2[2];
struct sigiolst p_sigiolst;
int p_sigparent;
struct klist p_klist;
struct timeval p_start;
struct rusage p_ru;
struct rusage p_cru;
void *p_linux_mm;
#define p_startcopy p_comm
char p_comm[MAXCOMLEN+1];
char p_pad3;
char p_nice;
char p_pad4;
int p_osrel;
struct pgrp *p_pgrp;
struct sysentvec *p_sysent;
struct uprof p_prof;
struct rtprio p_rtprio;
struct pargs *p_args;
u_short p_xstat;
u_short p_depth;
int p_ionice;
void *p_unused01;
#define p_endcopy p_unused01
u_short p_acflag;
int p_lock;
int p_nthreads;
int p_nstopped;
int p_lasttid;
struct lwp_rb_tree p_lwp_tree;
void *p_aioinfo;
int p_wakeup;
struct proc *p_peers;
struct proc *p_leader;
void *p_emuldata;
struct usched *p_usched;
struct vkernel_proc *p_vkernel;
struct uidcount *p_uidpcpu;
void (*p_userret)(void);
struct spinlock p_spin;
struct lwkt_token p_token;
struct sem_undo *p_sem_undo;
void *p_drv_priv;
uint32_t p_sigirefs;
char p_unused02[40];
struct sys_upmap *p_upmap;
forkid_t p_forkid;
struct sysreaper *p_reaper;
int p_deathsig;
unsigned int p_reaptid;
void *p_reserveds[2];
};
#define lwp_wchan lwp_thread->td_wchan
#define lwp_wmesg lwp_thread->td_wmesg
#define p_session p_pgrp->pg_session
#define p_pgid p_pgrp->pg_id
#define P_UNUSED00 0x00001
#define P_CONTROLT 0x00002
#define P_SWAPPEDOUT 0x00004
#define P_SYSVSEM 0x00008
#define P_PPWAIT 0x00010
#define P_PROFIL 0x00020
#define P_POSTEXIT 0x00040
#define P_SCMOUSE 0x00080
#define P_SUGID 0x00100
#define P_SYSTEM 0x00200
#define P_MAYBETHREADED 0x00400
#define P_TRACED 0x00800
#define P_WAITED 0x01000
#define P_WEXIT 0x02000
#define P_EXEC 0x04000
#define P_CONTINUED 0x08000
#define P_LOWMEMKILL 0x00010000
#define P_MUSTKILL 0x00020000
#define P_UNUSED18 0x00040000
#define P_UNUSED19 0x00080000
#define P_UNUSED20 0x00100000
#define P_UNUSED21 0x00200000
#define P_IDLESWAP 0x00400000
#define P_JAILED 0x01000000
#define P_SIGVTALRM 0x02000000
#define P_SIGPROF 0x04000000
#define P_INEXEC 0x08000000
#define P_DIDCHROOT 0x10000000
#define P_UNUSED29 0x20000000
#define P_XCPU 0x40000000
#define LWP_ALTSTACK 0x0000001
#define LWP_OLDMASK 0x0000002
#define LWP_SINTR 0x0000008
#define LWP_SELECT 0x0000010
#define LWP_UNUSED20 0x0000020
#define LWP_UNUSED40 0x0000040
#define LWP_UNUSED80 0x0000080
#define LWP_PASSIVE_ACQ 0x0000100
#define LWP_PAGING 0x0000200
#define LWP_MP_ONRUNQ 0x0000001
#define LWP_MP_WEXIT 0x0000002
#define LWP_MP_WSTOP 0x0000004
#define LWP_MP_ULOAD 0x0000008
#define LWP_MP_RRFORCE 0x0000010
#define LWP_MP_VNLRU 0x0000020
#define LWP_MP_URETMASK (LWP_MP_WEXIT | LWP_MP_VNLRU)
#define FIRST_LWP_IN_PROC(p) RB_FIRST(lwp_rb_tree, &(p)->p_lwp_tree)
#define FOREACH_LWP_IN_PROC(lp, p) \
RB_FOREACH(lp, lwp_rb_tree, &(p)->p_lwp_tree)
#define ONLY_LWP_IN_PROC(p) _only_lwp_in_proc(p, __func__)
struct procglob {
struct lwkt_token proc_token;
struct proclist allproc;
struct pgrplist allpgrp;
struct sesslist allsess;
void *pad01;
} __cachealign;
#ifdef _KERNEL
static inline struct lwp *
_only_lwp_in_proc(struct proc *p, const char *caller)
{
if (p->p_nthreads != 1) {
panic("%s: proc %p (pid %d cmd %s) has more than one thread",
caller, p, p->p_pid, p->p_comm);
}
return RB_ROOT(&p->p_lwp_tree);
}
#endif
#define PID_MAX 999999
#define NO_PID 0x7FFFFFFF
#define SESS_LEADER(p) ((p)->p_session->s_leader == (p))
#ifdef _KERNEL
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_SESSION);
MALLOC_DECLARE(M_PROC);
MALLOC_DECLARE(M_LWP);
MALLOC_DECLARE(M_SUBPROC);
MALLOC_DECLARE(M_PARGS);
#endif
#define PRISON_CHECK(cr1, cr2) \
((!(cr1)->cr_prison) || (cr1)->cr_prison == (cr2)->cr_prison)
void stopevent(struct proc *, unsigned int, unsigned int);
#define STOPEVENT(p,e,v) \
do { \
if (__predict_false((p)->p_stops & (e))) { \
stopevent(p,e,v); \
} \
} while (0)
#define PHOLD(p) phold((p))
#define PRELE(p) prele((p))
#define PHOLDZOMB(p) pholdzomb((p))
#define PRELEZOMB(p) prelezomb((p))
#define PWAITRES_PENDING(p) pwaitres_pending((p))
#define PWAITRES_SET(p) pwaitres_set((p))
#define PSTALL(p, msg, n) \
do { if ((p)->p_lock > (n)) pstall((p), (msg), (n)); } while (0)
#define STOPLWP(p, lp) \
(((p)->p_stat == SSTOP || (p)->p_stat == SCORE) && \
((lp)->lwp_mpflags & LWP_MP_WEXIT) == 0)
#define LWPHOLD(lp) atomic_add_int(&(lp)->lwp_lock, 1)
#define LWPRELE(lp) atomic_add_int(&(lp)->lwp_lock, -1)
extern struct proc proc0;
extern struct lwp lwp0;
extern struct thread thread0;
extern int nprocs, maxproc;
extern int maxprocperuid;
extern struct proc *initproc;
extern struct thread *pagethread;
extern struct thread *emergpager;
extern struct thread *updatethread;
#define ESTCPUFREQ 50
extern u_long ps_arg_cache_limit;
extern int ps_argsopen;
extern int ps_showallprocs;
struct lwp *lwpfind (struct proc *, lwpid_t);
struct proc *pfind (pid_t);
struct proc *pfindn (pid_t);
struct pgrp *pgfind (pid_t);
struct proc *zpfind (pid_t);
void pgref (struct pgrp *);
void pgrel (struct pgrp *);
struct globaldata;
struct lwp_params;
int enterpgrp (struct proc *p, pid_t pgid, int mksess);
void proc_add_allproc(struct proc *p);
void proc_move_allproc_zombie(struct proc *);
void proc_remove_zombie(struct proc *);
void allproc_scan(int (*callback)(struct proc *, void *), void *data,
int segmented);
void alllwp_scan(int (*callback)(struct lwp *, void *), void *data,
int segmented);
void zombproc_scan(int (*callback)(struct proc *, void *), void *data);
void fixjobc (struct proc *p, struct pgrp *pgrp, int entering);
void updatepcpu(struct lwp *, int, int);
int inferior (struct proc *p);
int leavepgrp (struct proc *p);
void sess_hold(struct session *sp);
void sess_rele(struct session *sp);
void procinit (void);
void procinsertinit(struct proc *p);
void sessinsertinit(struct session *sess);
void pgrpinsertinit(struct pgrp *pg);
void relscurproc(struct proc *curp);
int p_trespass (struct ucred *cr1, struct ucred *cr2);
void setrunnable (struct lwp *);
void proc_stop (struct proc *, int);
void proc_unstop (struct proc *, int);
void sleep_early_gdinit (struct globaldata *);
void sleep_gdinit (struct globaldata *);
thread_t cpu_heavy_switch (struct thread *);
thread_t cpu_lwkt_switch (struct thread *);
int cpu_interrupt_running(struct thread *);
void cpu_lwp_exit (void) __dead2;
void cpu_thread_exit (void) __dead2;
void lwp_exit (int masterexit, void *waddr) __dead2;
void lwp_dispose (struct lwp *);
int killalllwps (int);
void exit1 (int) __dead2;
void cpu_fork (struct lwp *, struct lwp *, int);
int cpu_prepare_lwp(struct lwp *, struct lwp_params *);
void cpu_set_fork_handler (struct lwp *, void (*)(void *, struct trapframe *), void *);
void cpu_set_thread_handler(struct thread *td, void (*retfunc)(void), void *func, void *arg);
int fork1 (struct lwp *, int, struct proc **);
void start_forked_proc (struct lwp *, struct proc *);
int trace_req (struct proc *);
void cpu_thread_wait (struct thread *);
void setsugid (void);
void faultin (struct proc *p);
void phold (struct proc *);
void prele (struct proc *);
int pwaitres_pending (struct proc *);
void pwaitres_set (struct proc *);
int pholdzomb (struct proc *);
void prelezomb (struct proc *);
void pstall (struct proc *, const char *, int);
void lwpuserret(struct lwp *);
void lwpkthreaddeferred(void);
void lwp_usermap(struct lwp *lp, int invfork);
void lwp_userunmap(struct lwp *lp);
void proc_usermap(struct proc *p, int invfork);
void proc_userunmap(struct proc *p);
void reaper_hold(struct sysreaper *reap);
void reaper_drop(struct sysreaper *reap);
int reaper_sigtest(struct proc *sender, struct proc *target, int reaper_ok);
struct sysreaper *reaper_exit(struct proc *p);
void reaper_init(struct proc *p, struct sysreaper *reap);
struct proc *reaper_get(struct sysreaper *reap);
int reaper_kill(struct sysreaper *reap, struct reaper_kill *rk);
u_int32_t procrunnable (void);
#endif
#endif
#endif