#ifndef _SYS_PROC_H
#define _SYS_PROC_H
#include <sys/time.h>
#include <sys/thread.h>
#include <sys/cred.h>
#include <sys/user.h>
#include <sys/watchpoint.h>
#include <sys/timer.h>
#if defined(__x86)
#include <sys/tss.h>
#include <sys/segments.h>
#endif
#include <sys/utrap.h>
#include <sys/model.h>
#include <sys/refstr.h>
#include <sys/avl.h>
#include <sys/rctl.h>
#include <sys/list.h>
#include <sys/avl.h>
#include <sys/door_impl.h>
#include <sys/signalfd.h>
#include <sys/secflags.h>
#ifdef __cplusplus
extern "C" {
#endif
struct prof {
void *pr_base;
uintptr_t pr_off;
size_t pr_size;
uint32_t pr_scale;
long pr_samples;
};
typedef struct lwpent {
kthread_t *le_thread;
id_t le_lwpid;
uint16_t le_waiters;
uint16_t le_dwaiters;
clock_t le_start;
struct vnode *le_trace;
} lwpent_t;
typedef struct pctxop {
void (*save_op)(void *);
void (*restore_op)(void *);
void (*fork_op)(void *, void *);
void (*exit_op)(void *);
void (*free_op)(void *, int);
void *arg;
struct pctxop *next;
} pctxop_t;
typedef struct lwpdir {
struct lwpdir *ld_next;
struct lwpent *ld_entry;
} lwpdir_t;
typedef struct tidhash {
kmutex_t th_lock;
lwpdir_t *th_list;
} tidhash_t;
typedef struct ret_tidhash {
struct ret_tidhash *rth_next;
tidhash_t *rth_tidhash;
uint_t rth_tidhash_sz;
} ret_tidhash_t;
struct pool;
struct task;
struct zone;
struct brand;
struct corectl_path;
struct corectl_content;
typedef struct proc {
struct vnode *p_exec;
struct as *p_as;
struct plock *p_lockp;
kmutex_t p_crlock;
struct cred *p_cred;
int p_swapcnt;
char p_stat;
char p_wcode;
ushort_t p_pidflag;
int p_wdata;
pid_t p_ppid;
struct proc *p_link;
struct proc *p_parent;
struct proc *p_child;
struct proc *p_sibling;
struct proc *p_psibling;
struct proc *p_sibling_ns;
struct proc *p_child_ns;
struct proc *p_next;
struct proc *p_prev;
struct proc *p_nextofkin;
struct proc *p_orphan;
struct proc *p_nextorph;
struct proc *p_pglink;
struct proc *p_ppglink;
struct sess *p_sessp;
struct pid *p_pidp;
struct pid *p_pgidp;
kcondvar_t p_cv;
kcondvar_t p_flag_cv;
kcondvar_t p_lwpexit;
kcondvar_t p_holdlwps;
uint_t p_proc_flag;
uint_t p_flag;
clock_t p_utime;
clock_t p_stime;
clock_t p_cutime;
clock_t p_cstime;
avl_tree_t *p_segacct;
avl_tree_t *p_semacct;
caddr_t p_bssbase;
caddr_t p_brkbase;
size_t p_brksize;
uint_t p_brkpageszc;
k_sigset_t p_sig;
k_sigset_t p_extsig;
k_sigset_t p_ignore;
k_sigset_t p_siginfo;
void *p_sigfd;
struct sigqueue *p_sigqueue;
struct sigqhdr *p_sigqhdr;
struct sigqhdr *p_signhdr;
uchar_t p_stopsig;
char p_fixalignment;
id_t p_lwpid;
int p_lwpcnt;
int p_lwprcnt;
int p_lwpdaemon;
int p_lwpwait;
int p_lwpdwait;
int p_zombcnt;
kthread_t *p_tlist;
lwpdir_t *p_lwpdir;
lwpdir_t *p_lwpfree;
tidhash_t *p_tidhash;
uint_t p_lwpdir_sz;
uint_t p_tidhash_sz;
ret_tidhash_t *p_ret_tidhash;
uint64_t p_lgrpset;
volatile lgrp_id_t p_t1_lgrpid;
volatile lgrp_id_t p_tr_lgrpid;
#if defined(_LP64)
uintptr_t p_lgrpres2;
#endif
k_sigset_t p_sigmask;
k_fltset_t p_fltmask;
struct vnode *p_trace;
struct vnode *p_plist;
kthread_t *p_agenttp;
avl_tree_t p_warea;
avl_tree_t p_wpage;
watched_page_t *p_wprot;
int p_mapcnt;
kmutex_t p_maplock;
struct proc *p_rlink;
kcondvar_t p_srwchan_cv;
size_t p_stksize;
uint_t p_stkpageszc;
uintptr_t p_stkg_start;
uintptr_t p_stkg_end;
hrtime_t p_mstart;
hrtime_t p_mterm;
hrtime_t p_mlreal;
hrtime_t p_acct[NMSTATES];
hrtime_t p_cacct[NMSTATES];
struct lrusage p_ru;
struct lrusage p_cru;
struct itimerval p_rprof_timer;
uintptr_t p_rprof_cyclic;
uint_t p_defunct;
kmutex_t p_pflock;
struct prof p_prof;
door_pool_t p_server_threads;
struct door_node *p_door_list;
struct door_node *p_unref_list;
kcondvar_t p_unref_cv;
char p_unref_thread;
struct p_audit_data *p_audit_data;
pctxop_t *p_pctx;
#if defined(__x86)
kmutex_t p_ldtlock;
user_desc_t *p_ldt;
uint64_t p_unused1;
uint64_t p_unused2;
ushort_t p_ldtlimit;
#endif
size_t p_swrss;
struct aio *p_aio;
struct itimer **p_itimer;
uint_t p_itimer_sz;
timeout_id_t p_alarmid;
caddr_t p_usrstack;
uint_t p_stkprot;
uint_t p_datprot;
model_t p_model;
struct lwpchan_data *p_lcp;
kmutex_t p_lcp_lock;
utrap_handler_t *p_utraps;
struct corectl_path *p_corefile;
struct task *p_task;
struct proc *p_taskprev;
struct proc *p_tasknext;
kmutex_t p_sc_lock;
struct sc_page_ctl *p_pagep;
struct rctl_set *p_rctls;
rlim64_t p_stk_ctl;
rlim64_t p_fsz_ctl;
rlim64_t p_vmem_ctl;
rlim64_t p_fno_ctl;
pid_t p_ancpid;
struct itimerval p_realitimer;
timeout_id_t p_itimerid;
struct corectl_content *p_content;
avl_tree_t p_ct_held;
struct ct_equeue **p_ct_equeue;
struct cont_process *p_ct_process;
list_node_t p_ct_member;
sigqueue_t *p_killsqp;
int p_dtrace_probes;
uint64_t p_dtrace_count;
void *p_dtrace_helpers;
struct pool *p_pool;
kcondvar_t p_poolcv;
uint_t p_poolcnt;
uint_t p_poolflag;
uint_t p_upanicflag;
void *p_upanic;
uintptr_t p_portcnt;
struct zone *p_zone;
struct vnode *p_execdir;
struct brand *p_brand;
void *p_brand_data;
psecflags_t p_secflags;
kmutex_t p_splock;
rctl_qty_t p_locked_mem;
rctl_qty_t p_crypto_mem;
clock_t p_ttime;
struct user p_user;
} proc_t;
#define PROC_T
#ifdef _KERNEL
extern proc_t *practive;
extern proc_t *proc_sched;
extern proc_t *proc_init;
extern proc_t *proc_pageout;
extern proc_t *proc_fsflush;
#endif
struct upcount {
struct upcount *up_next;
uid_t up_uid;
zoneid_t up_zoneid;
uint_t up_count;
};
struct pid {
unsigned int pid_prinactive :1;
unsigned int pid_pgorphaned :1;
unsigned int pid_padding :6;
unsigned int pid_prslot :24;
pid_t pid_id;
struct proc *pid_pglink;
struct proc *pid_pgtail;
struct pid *pid_link;
uint_t pid_ref;
};
#define p_pgrp p_pgidp->pid_id
#define p_pid p_pidp->pid_id
#define p_slot p_pidp->pid_prslot
#define p_detached p_pgidp->pid_pgorphaned
#define PID_HOLD(pidp) ASSERT(MUTEX_HELD(&pidlock)); \
++(pidp)->pid_ref;
#define PID_RELE(pidp) ASSERT(MUTEX_HELD(&pidlock)); \
(pidp)->pid_ref > 1 ? \
--(pidp)->pid_ref : pid_rele(pidp);
struct plock {
kmutex_t pl_lock;
};
#define p_lock p_lockp->pl_lock
#ifdef _KERNEL
extern proc_t p0;
extern struct plock p0lock;
extern struct pid pid0;
#define PID_ALLOC_PROC 0x0001
#endif
#define SSLEEP 1
#define SRUN 2
#define SZOMB 3
#define SSTOP 4
#define SIDL 5
#define SONPROC 6
#define SWAIT 7
#define CLDPEND 0x0001
#define CLDCONT 0x0002
#define CLDNOSIGCHLD 0x0004
#define CLDWAITPID 0x0008
#define P_PR_TRACE 0x0001
#define P_PR_PTRACE 0x0002
#define P_PR_FORK 0x0004
#define P_PR_LOCK 0x0008
#define P_PR_ASYNC 0x0010
#define P_PR_EXEC 0x0020
#define P_PR_BPTADJ 0x0040
#define P_PR_RUNLCL 0x0080
#define P_PR_KILLCL 0x0100
#define SSYS 0x00000001
#define SEXITING 0x00000002
#define SITBUSY 0x00000004
#define SFORKING 0x00000008
#define SWATCHOK 0x00000010
#define SKILLED 0x00000100
#define SSCONT 0x00000200
#define SZONETOP 0x00000400
#define SEXTKILLED 0x00000800
#define SUGID 0x00002000
#define SEXECED 0x00004000
#define SJCTL 0x00010000
#define SNOWAIT 0x00020000
#define SVFORK 0x00040000
#define SVFWAIT 0x00080000
#define SEXITLWPS 0x00100000
#define SHOLDFORK 0x00200000
#define SHOLDFORK1 0x00800000
#define SCOREDUMP 0x01000000
#define SMSACCT 0x02000000
#define SLWPWRAP 0x04000000
#define SAUTOLPG 0x08000000
#define SNOCD 0x10000000
#define SHOLDWATCH 0x20000000
#define SMSFORK 0x40000000
#define SDOCORE 0x80000000
#define PBWAIT 0x0001
#define PEXITED 0x0002
#define P_UPF_PANICKED 0x0001
#define P_UPF_HAVEMSG 0x0002
#define P_UPF_TRUNCMSG 0x0004
#define P_UPF_INVALMSG 0x0008
#define PTOU(p) (&(p)->p_user)
#define tracing(p, sig) (sigismember(&(p)->p_sigmask, sig))
#define ISSIG(t, why) ISSIG_FAST(t, ttolwp(t), ttoproc(t), why)
#define ISSIG_FAST(t, lwp, p, why) \
(ISSIG_PENDING(t, lwp, p) && issig(why))
#define ISSIG_PENDING(t, lwp, p) \
((lwp)->lwp_cursig | \
sigcheck((p), (t)) | \
(p)->p_stopsig | \
(t)->t_dtrace_stop | \
(t)->t_dtrace_sig | \
((t)->t_proc_flag & (TP_PRSTOP|TP_HOLDLWP|TP_CHKPT|TP_PAUSE)) | \
((p)->p_flag & (SEXITLWPS|SKILLED|SHOLDFORK1|SHOLDWATCH)))
#define ISSTOP(sig) (u.u_signal[sig-1] == SIG_DFL && \
sigismember(&stopdefault, sig))
#define ISHOLD(p) ((p)->p_flag & SHOLDFORK)
#define MUSTRETURN(p, t) (ISHOLD(p) | (t)->t_activefd.a_stale)
#define pr_watch_active(p) (avl_numnodes(&(p)->p_warea) != 0)
#define FORREAL 0
#define JUSTLOOKING 1
#define SUSPEND_NORMAL 0
#define SUSPEND_PAUSE 1
#define NOCLASS (-1)
#define CLASS_UNUSED (-2)
typedef enum {
LWP_STAT_INBLK,
LWP_STAT_OUBLK,
LWP_STAT_MSGRCV,
LWP_STAT_MSGSND
} lwp_stat_id_t;
typedef struct prkillinfo {
int32_t prk_error;
int32_t prk_pad;
siginfo_t prk_info;
} prkillinfo_t;
#ifdef _KERNEL
extern void profil_tick(uintptr_t);
extern int newproc(void (*)(), caddr_t, id_t, int, struct contract **, pid_t);
extern void vfwait(pid_t);
extern void proc_detach(proc_t *);
extern void freeproc(proc_t *);
extern void setrun(kthread_t *);
extern void setrun_locked(kthread_t *);
extern void exit(int, int);
extern int proc_exit(int, int);
extern void proc_is_exiting(proc_t *);
extern void relvm(void);
extern void add_ns(proc_t *, proc_t *);
extern void delete_ns(proc_t *, proc_t *);
extern void upcount_inc(uid_t, zoneid_t);
extern void upcount_dec(uid_t, zoneid_t);
extern int upcount_get(uid_t, zoneid_t);
#if defined(__x86)
extern selector_t setup_thrptr(proc_t *, uintptr_t);
extern void deferred_singlestep_trap(caddr_t);
#endif
extern void sigcld(proc_t *, sigqueue_t *);
extern void sigcld_delete(k_siginfo_t *);
extern void sigcld_repost(void);
extern int fsig(k_sigset_t *, kthread_t *);
extern void psig(void);
extern void stop(int, int);
extern int stop_on_fault(uint_t, k_siginfo_t *);
extern int issig(int);
extern int jobstopped(proc_t *);
extern void psignal(proc_t *, int);
extern void tsignal(kthread_t *, int);
extern void sigtoproc(proc_t *, kthread_t *, int);
extern void trapsig(k_siginfo_t *, int);
extern void realsigprof(int, int, int);
extern int eat_signal(kthread_t *, int);
extern int signal_is_blocked(kthread_t *, int);
extern int sigcheck(proc_t *, kthread_t *);
extern void sigdefault(proc_t *);
extern void pid_setmin(void);
extern pid_t pid_allocate(proc_t *, pid_t, int);
extern int pid_rele(struct pid *);
extern void pid_exit(proc_t *, struct task *);
extern void proc_entry_free(struct pid *);
extern proc_t *prfind(pid_t);
extern proc_t *prfind_zone(pid_t, zoneid_t);
extern proc_t *pgfind(pid_t);
extern proc_t *pgfind_zone(pid_t, zoneid_t);
extern proc_t *sprlock(pid_t);
extern proc_t *sprlock_zone(pid_t, zoneid_t);
extern int sprtrylock_proc(proc_t *);
extern void sprwaitlock_proc(proc_t *);
extern void sprlock_proc(proc_t *);
extern void sprunlock(proc_t *);
extern void pid_init(void);
extern proc_t *pid_entry(int);
extern int pid_slot(proc_t *);
extern void signal(pid_t, int);
extern void prsignal(struct pid *, int);
extern int uread(proc_t *, void *, size_t, uintptr_t);
extern int uwrite(proc_t *, void *, size_t, uintptr_t);
extern void pgsignal(struct pid *, int);
extern void pgjoin(proc_t *, struct pid *);
extern void pgcreate(proc_t *);
extern void pgexit(proc_t *);
extern void pgdetach(proc_t *);
extern int pgmembers(pid_t);
extern void init_mstate(kthread_t *, int);
extern int new_mstate(kthread_t *, int);
extern void restore_mstate(kthread_t *);
extern void term_mstate(kthread_t *);
extern void estimate_msacct(kthread_t *, hrtime_t);
extern void disable_msacct(proc_t *);
extern hrtime_t mstate_aggr_state(proc_t *, int);
extern hrtime_t mstate_thread_onproc_time(kthread_t *);
extern void mstate_systhread_times(kthread_t *, hrtime_t *, hrtime_t *);
extern void syscall_mstate(int, int);
extern uint_t cpu_update_pct(kthread_t *, hrtime_t);
extern void set_proc_pre_sys(proc_t *p);
extern void set_proc_post_sys(proc_t *p);
extern void set_proc_sys(proc_t *p);
extern void set_proc_ast(proc_t *p);
extern void set_all_proc_sys(void);
extern void set_all_zone_usr_proc_sys(zoneid_t);
extern kthread_t *thread_create(
caddr_t stk,
size_t stksize,
void (*proc)(),
void *arg,
size_t len,
proc_t *pp,
int state,
pri_t pri);
extern void thread_exit(void) __NORETURN;
extern void thread_free(kthread_t *);
extern void thread_rele(kthread_t *);
extern void thread_join(kt_did_t);
extern int reaper(void);
#define CTXOP_TPL_REV 1
struct ctxop_template {
uint32_t ct_rev;
uint32_t ct_pad;
void (*ct_save)(void *);
void (*ct_restore)(void *);
void (*ct_fork)(void *, void *);
void (*ct_lwp_create)(void *, void *);
void (*ct_exit)(void *);
void (*ct_free)(void *, int);
};
extern struct ctxop *ctxop_allocate(const struct ctxop_template *, void *);
extern void ctxop_free(struct ctxop *);
extern void ctxop_attach(kthread_t *, struct ctxop *);
extern void ctxop_detach(kthread_t *, struct ctxop *);
extern void ctxop_install(kthread_t *, const struct ctxop_template *, void *);
extern int ctxop_remove(kthread_t *, const struct ctxop_template *, void *);
extern void savectx(kthread_t *);
extern void restorectx(kthread_t *);
extern void forkctx(kthread_t *, kthread_t *);
extern void lwp_createctx(kthread_t *, kthread_t *);
extern void exitctx(kthread_t *);
extern void freectx(kthread_t *, int);
extern void installpctx(proc_t *, void *, void (*)(), void (*)(),
void (*)(), void (*)(), void (*)());
extern int removepctx(proc_t *, void *, void (*)(), void (*)(),
void (*)(), void (*)(), void (*)());
extern void savepctx(proc_t *);
extern void restorepctx(proc_t *);
extern void forkpctx(proc_t *, proc_t *);
extern void exitpctx(proc_t *);
extern void freepctx(proc_t *, int);
extern kthread_t *thread_unpin(void);
extern void thread_init(void);
extern void thread_load(kthread_t *, void (*)(), caddr_t, size_t);
extern void tsd_create(uint_t *, void (*)(void *));
extern void tsd_destroy(uint_t *);
extern void *tsd_getcreate(uint_t *, void (*)(void *), void *(*)(void));
extern void *tsd_get(uint_t);
extern int tsd_set(uint_t, void *);
extern void tsd_exit(void);
extern void *tsd_agent_get(kthread_t *, uint_t);
extern int tsd_agent_set(kthread_t *, uint_t, void *);
extern kthread_t *lwp_kernel_create(proc_t *, void (*)(), void *, int, pri_t);
extern klwp_t *lwp_create(
void (*proc)(),
caddr_t arg,
size_t len,
proc_t *p,
int state,
int pri,
const k_sigset_t *smask,
int cid,
id_t lwpid);
extern kthread_t *idtot(proc_t *, id_t);
extern void lwp_hash_in(proc_t *, lwpent_t *, tidhash_t *, uint_t, int);
extern void lwp_hash_out(proc_t *, id_t);
extern lwpdir_t *lwp_hash_lookup(proc_t *, id_t);
extern lwpdir_t *lwp_hash_lookup_and_lock(proc_t *, id_t, kmutex_t **);
extern void lwp_create_done(kthread_t *);
extern void lwp_exit(void);
extern void lwp_pcb_exit(void);
extern void lwp_cleanup(void);
extern int lwp_suspend(kthread_t *);
extern void lwp_continue(kthread_t *);
extern void holdlwp(void);
extern void stoplwp(void);
extern int holdlwps(int);
extern int holdwatch(void);
extern void pokelwps(proc_t *);
extern void runlwps(proc_t *, ushort_t);
extern void continuelwps(proc_t *);
extern int exitlwps(int);
extern void lwp_ctmpl_copy(klwp_t *, klwp_t *);
extern void lwp_ctmpl_clear(klwp_t *);
extern klwp_t *forklwp(klwp_t *, proc_t *, id_t);
extern void lwp_load(klwp_t *, gregset_t, uintptr_t);
extern void lwp_setrval(klwp_t *, int, int);
extern void lwp_forkregs(klwp_t *, klwp_t *);
extern void lwp_freeregs(klwp_t *, int);
extern caddr_t lwp_stk_init(klwp_t *, caddr_t);
extern void lwp_stk_cache_init(void);
extern void lwp_stk_fini(klwp_t *);
extern void lwp_fp_init(klwp_t *);
extern void lwp_installctx(klwp_t *);
extern void lwp_rtt(void);
extern void lwp_rtt_initial(void);
extern int lwp_setprivate(klwp_t *, int, uintptr_t);
extern void lwp_stat_update(lwp_stat_id_t, long);
extern void lwp_attach_brand_hdlrs(klwp_t *);
extern void lwp_detach_brand_hdlrs(klwp_t *);
#if defined(__sparcv9)
extern void lwp_mmodel_newlwp(void);
extern void lwp_mmodel_shared_as(caddr_t, size_t);
#define LWP_MMODEL_NEWLWP() lwp_mmodel_newlwp()
#define LWP_MMODEL_SHARED_AS(addr, sz) lwp_mmodel_shared_as((addr), (sz))
#else
#define LWP_MMODEL_NEWLWP()
#define LWP_MMODEL_SHARED_AS(addr, sz)
#endif
extern void sigqfree(proc_t *);
extern void siginfofree(sigqueue_t *);
extern void sigdeq(proc_t *, kthread_t *, int, sigqueue_t **);
extern void sigdelq(proc_t *, kthread_t *, int);
extern void sigaddq(proc_t *, kthread_t *, k_siginfo_t *, int);
extern void sigaddqa(proc_t *, kthread_t *, sigqueue_t *);
extern void sigqsend(int, proc_t *, kthread_t *, sigqueue_t *);
extern void sigdupq(proc_t *, proc_t *);
extern int sigwillqueue(int, int);
extern sigqhdr_t *sigqhdralloc(size_t, uint_t);
extern sigqueue_t *sigqalloc(sigqhdr_t *);
extern void sigqhdrfree(sigqhdr_t *);
extern sigqueue_t *sigappend(k_sigset_t *, sigqueue_t *,
k_sigset_t *, sigqueue_t *);
extern sigqueue_t *sigprepend(k_sigset_t *, sigqueue_t *,
k_sigset_t *, sigqueue_t *);
extern void winfo(proc_t *, k_siginfo_t *, int);
extern int wstat(int, int);
extern int sendsig(int, k_siginfo_t *, void (*)());
#if defined(_SYSCALL32_IMPL)
extern int sendsig32(int, k_siginfo_t *, void (*)());
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif