aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/proc.h
diff options
context:
space:
mode:
authorJulian Elischer <julian@FreeBSD.org>2001-09-12 08:38:13 +0000
committerJulian Elischer <julian@FreeBSD.org>2001-09-12 08:38:13 +0000
commitb40ce4165d5eb3a5de1515245055350ae3dbab8e (patch)
treeb1a19fcdf05759281fab0d89efb13f0fdf42102e /sys/sys/proc.h
parent9b36a30ee46a7766f269fe832ef3a2daa2ec04f0 (diff)
downloadsrc-b40ce4165d5eb3a5de1515245055350ae3dbab8e.tar.gz
src-b40ce4165d5eb3a5de1515245055350ae3dbab8e.zip
KSE Milestone 2
Note ALL MODULES MUST BE RECOMPILED make the kernel aware that there are smaller units of scheduling than the process. (but only allow one thread per process at this time). This is functionally equivalent to teh previousl -current except that there is a thread associated with each process. Sorry john! (your next MFC will be a doosie!) Reviewed by: peter@freebsd.org, dillon@freebsd.org X-MFC after: ha ha ha ha
Notes
Notes: svn path=/head/; revision=83366
Diffstat (limited to 'sys/sys/proc.h')
-rw-r--r--sys/sys/proc.h466
1 files changed, 328 insertions, 138 deletions
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 0a321a519872..dd532740be97 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -142,132 +142,301 @@ struct ithd;
struct nlminfo;
struct trapframe;
-struct proc {
- TAILQ_ENTRY(proc) p_procq; /* (j) Run/mutex queue. */
- TAILQ_ENTRY(proc) p_slpq; /* (j) Sleep queue. */
- LIST_ENTRY(proc) p_list; /* (d) List of all processes. */
+/*
+ * Here we define the four structures used for process information.
+ *
+ * The first is the thread. It might be though of as a "Kernel
+ * Schedulable Entity Context".
+ * This structure contains all the information as to where a thread of
+ * execution is now, or was when it was suspended, why it was suspended,
+ * and anything else that will be needed to restart it when it is
+ * rescheduled. Always associated with a KSE when running, but can be
+ * reassigned to an equivalent KSE when being restarted for
+ * load balancing. Each of these is associated with a kernel stack
+ * and a pcb.
+ *
+ * It is important to remember that a particular thread structure only
+ * exists as long as the system call or kernel entrance (e.g. by pagefault)
+ * which it is currently executing. It should threfore NEVER be referenced
+ * by pointers in long lived structures that live longer than a single
+ * request. If several threads complete their work at the same time,
+ * they will all rewind their stacks to the uer boundary, report their
+ * completion state, and all but one will be freed. That last one will
+ * be kept to provide a kernel stack and pcb for the NEXT syscall or kernel
+ * entrance. (basically to save freeing and then re-allocating it) A process
+ * might keep a cache of threads available to allow it to quickly
+ * get one when it needs a new one. There would probably also be a system
+ * cache of free threads.
+ */
+struct thread;
+
+/*
+ * The second structure is the Kernel Schedulable Entity. (KSE)
+ * As long as this is scheduled, it will continue to run any threads that
+ * are assigned to it or the KSEGRP (see later) until either it runs out
+ * of runnable threads or CPU.
+ * It runs on one CPU and is assigned a quantum of time. When a thread is
+ * blocked, The KSE continues to run and will search for another thread
+ * in a runnable state amongst those it has. It May decide to return to user
+ * mode with a new 'empty' thread if there are no runnable threads.
+ * threads are associated with a KSE for cache reasons, but a sheduled KSE with
+ * no runnable thread will try take a thread from a sibling KSE before
+ * surrendering its quantum. In some schemes it gets it's quantum from the KSEG
+ * and contributes to draining that quantum, along withthe other KSEs in
+ * the group. (undecided)
+ */
+struct kse;
- /* substructures: */
- struct ucred *p_ucred; /* (c + k) Process owner's identity. */
- struct filedesc *p_fd; /* (b) Ptr to open files structure. */
- struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */
- struct plimit *p_limit; /* (m) Process limits. */
- struct vm_object *p_upages_obj;/* (a) Upages object. */
- struct procsig *p_procsig; /* (c) Signal actions, state (CPU). */
-#define p_sigacts p_procsig->ps_sigacts
-#define p_sigignore p_procsig->ps_sigignore
-#define p_sigcatch p_procsig->ps_sigcatch
+/*
+ * The KSEGRP is allocated resources across a number of CPUs.
+ * (Including a number of CPUxQUANTA. It parcels these QUANTA up among
+ * Its KSEs, each of which should be running in a different CPU.
+ * Priority and total available sheduled quanta are properties of a KSEGRP.
+ * Multiple KSEGRPs in a single process compete against each other
+ * for total quanta in the same way that a forked child competes against
+ * it's parent process.
+ */
+struct ksegrp;
-#define p_rlimit p_limit->pl_rlimit
+/*
+ * A process is the owner of all system resources allocated to a task
+ * except CPU quanta.
+ * All KSEGs under one process see, and have the same access to, these
+ * resources (e.g. files, memory, sockets, permissions kqueues).
+ * A process may compete for CPU cycles on the same basis as a
+ * forked process cluster by spawning several KSEGRPs.
+ */
+struct proc;
+
+/***************
+ * In pictures:
+ With a single run queue used by all processors:
+
+ RUNQ: --->KSE---KSE--... SLEEPQ:[]---THREAD---THREAD---THREAD
+ | / []---THREAD
+ KSEG---THREAD--THREAD--THREAD []
+ []---THREAD---THREAD
+
+ (processors run THREADs from the KSEG until they are exhausted or
+ the KSEG exhausts its quantum)
+
+With PER-CPU run queues:
+KSEs on the separate run queues directly
+They would be given priorities calculated from the KSEG.
+
+ *
+ *****************/
+
+/*
+ * Kernel runnable context (thread).
+ * This is what is put to sleep and reactivated.
+ * The first KSE available in the correct group will run this thread.
+ * If several are available, use the one on the same CPU as last time.
+ */
+struct thread {
+ struct proc *td_proc; /* Associated process. */
+ struct ksegrp *td_ksegrp; /* Associated KSEG. */
+ struct kse *td_last_kse; /* Where it wants to be if possible */
+ struct kse *td_kse; /* and is now if running */
+
+ TAILQ_ENTRY(thread) td_plist; /* All threads in this proc */
+ TAILQ_ENTRY(thread) td_kglist; /* All threads in this ksegrp */
+
+ /* The two queues below should someday be merged */
+ TAILQ_ENTRY(thread) td_slpq; /* (j) Sleep queue. XXXKSE */
+ TAILQ_ENTRY(thread) td_blkq; /* (j) mutex queue. XXXKSE */
+ TAILQ_ENTRY(thread) td_runq; /* (j) run queue(s). XXXKSE */
+
+#define td_startzero td_flags
+ int td_flags; /* (c) P_* flags. */
+ int td_dupfd; /* (c) ret value from fdopen. XXX */
+ void *td_wchan; /* (j) Sleep address. */
+ const char *td_wmesg; /* (j) Reason for sleep. */
+ u_char td_lastcpu; /* (j) Last cpu we were on. */
+ short td_locks; /* (*) DEBUG: lockmgr count of locks */
+ struct mtx *td_blocked; /* (j) Mutex process is blocked on. */
+ struct ithd *td_ithd; /* (b) For interrupt threads only. */
+ const char *td_mtxname; /* (j) Name of mutex blocked on. */
+ LIST_HEAD(, mtx) td_contested; /* (j) Contested locks. */
+ struct lock_list_entry *td_sleeplocks; /* (k) Held sleep locks. */
+ int td_intr_nesting_level; /* (k) Interrupt recursion. */
+#define td_endzero td_md
+
+#define td_startcopy td_endzero
+ /* XXXKSE p_md is in the "on your own" section in old struct proc */
+ struct mdthread td_md; /* (k) Any machine-dependent fields. */
+ register_t td_retval[2]; /* (k) Syscall aux returns. */
+#define td_endcopy td_pcb
+
+ struct pcb *td_pcb; /* (k) Kv addr of pcb and kstack. */
+ struct callout td_slpcallout; /* (h) Callout for sleep. */
+ struct trapframe *td_frame; /* (k) */
+ struct vm_object *td_kstack_obj;/* (a) kstack object. */
+ vm_offset_t td_kstack; /* kstack mapped address */
+};
+#define TDF_ONRUNQ 0x00000001 /* This KE is on a run queue */
+
+/*
+ * The schedulable entity that can be given a context to run.
+ * A process may have several of these. Probably one per processor
+ * but posibly a few more. In this universe they are grouped
+ * with a KSEG that contains the priority and niceness
+ * for the group.
+ */
+struct kse {
+ struct proc *ke_proc; /* Associated process. */
+ struct ksegrp *ke_ksegrp; /* Associated KSEG. */
+ struct thread *ke_thread; /* Associated thread, if running. */
+ TAILQ_ENTRY(kse) ke_kglist; /* Queue of all KSEs in ke_ksegrp. */
+ TAILQ_ENTRY(kse) ke_kgrlist; /* Queue of all KSEs in this state. */
+ TAILQ_ENTRY(kse) ke_procq; /* (j) Run queue. */
+ TAILQ_HEAD(, thread) ke_runq; /* (td_runq) RUNNABLE bound to KSE. */
+
+#define ke_startzero ke_flags
+ int ke_flags; /* (c) P_* flags. */
+ /*u_int ke_estcpu; */ /* (j) Time averaged val of cpticks. */
+ int ke_cpticks; /* (j) Ticks of cpu time. */
+ fixpt_t ke_pctcpu; /* (j) %cpu during p_swtime. */
+ u_int64_t ke_uu; /* (j) Previous user time in usec. */
+ u_int64_t ke_su; /* (j) Previous system time in usec. */
+ u_int64_t ke_iu; /* (j) Previous intr time in usec. */
+ u_int64_t ke_uticks; /* (j) Statclock hits in user mode. */
+ u_int64_t ke_sticks; /* (j) Statclock hits in system mode. */
+ u_int64_t ke_iticks; /* (j) Statclock hits in intr. */
+ u_char ke_oncpu; /* (j) Which cpu we are on. */
+ u_int ke_slptime; /* (j) Time since last idle. */
+ char ke_rqindex; /* (j) Run queue index. */
+#define ke_endzero ke_priority
+
+#define ke_startcopy ke_endzero
+ u_char ke_priority; /* (j) Process priority. */
+ u_char ke_usrpri; /* (j) User pri from cpu & nice. */
+#define ke_endcopy ke_end
+
+ int ke_end; /* dummy entry */
+};
+
+/*
+ * Kernel-scheduled entity group (KSEG). The scheduler considers each KSEG to
+ * be an indivisible unit from a time-sharing perspective, though each KSEG may
+ * contain multiple KSEs.
+ */
+struct ksegrp {
+ struct proc *kg_proc; /* Process that contains this KSEG. */
+ TAILQ_ENTRY(ksegrp) kg_ksegrp; /* Queue of KSEGs in kg_proc. */
+ TAILQ_HEAD(, kse) kg_kseq; /* (ke_kglist) All KSEs */
+ TAILQ_HEAD(, kse) kg_rq; /* (ke_kgrlist) Runnable KSEs */
+ TAILQ_HEAD(, kse) kg_iq; /* (ke_kgrlist) Idle KSEs */
+ TAILQ_HEAD(, thread) kg_threads;/* (td_kglist) All threads. */
+ TAILQ_HEAD(, thread) kg_runq; /* (td_runq)unbound RUNNABLE threads */
+ TAILQ_HEAD(, thread) kg_slpq; /* (td_runq)NONRUNNABLE threads. */
+
+#define kg_startzero kg_estcpu
+ u_int kg_slptime; /* (j) how long completely blocked. */
+ u_int kg_estcpu; /* sum of the same field in kses */
+#define kg_endzero kg_pri
+
+#define kg_startcopy kg_endzero
+ struct priority kg_pri; /* (j) Process priority. */
+ char kg_nice; /* (j?/k?) Process "nice" value. */
+ struct rtprio kg_rtprio; /* (j) Realtime priority. */
+#define kg_endcopy kg_runnable
+
+ int kg_runnable; /* # runnable threads on queue */
+ int kg_runq_kses; /* # kse's on runq. */
+ int kg_kses; /* # kse's in group. */
+};
- int p_flag; /* (c) P_* flags. */
- int p_sflag; /* (j) PS_* flags. */
- int p_stat; /* (j) S* process status. */
+/*
+ * The old fashionned process. May have multiple threads, KSEGRPs
+ * and KSEs. Starts off with a single embedded KSEGRP, KSE and THREAD.
+ */
+struct proc {
+ LIST_ENTRY(proc) p_list; /* (d) List of all processes. */
+ TAILQ_HEAD(, ksegrp) p_ksegrps; /* (kg_ksegrp) All KSEGs. */
+ TAILQ_HEAD(, thread) p_threads; /* (td_plist) threads. (shortcut) */
+ struct ucred *p_ucred; /* (c + k) Process owner's identity. */
+ struct filedesc *p_fd; /* (b) Ptr to open files structure. */
+ /* accumulated stats for all KSEs? */
+ struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */
+ struct plimit *p_limit; /* (m) Process limits. */
+ struct vm_object *p_upages_obj; /* (a) Upages object. */
+ struct procsig *p_procsig; /* (c) Signal actions, state (CPU). */
+
+ struct ksegrp p_ksegrp;
+ struct kse p_kse;
+ struct thread p_thread;
+
+ /*
+ * The following don't make too much sense..
+ * See the td_ or ke_ versions of the same flags
+ */
+ int p_flag; /* (c) P_* flags. */
+ int p_sflag; /* (j) PS_* flags. */
+ int p_stat; /* (j) S* process status. */
pid_t p_pid; /* (b) Process identifier. */
LIST_ENTRY(proc) p_hash; /* (d) Hash chain. */
LIST_ENTRY(proc) p_pglist; /* (c) List of processes in pgrp. */
- struct proc *p_pptr; /* (c + e) Pointer to parent process. */
+ struct proc *p_pptr; /* (c + e) Pointer to parent process. */
LIST_ENTRY(proc) p_sibling; /* (e) List of sibling processes. */
LIST_HEAD(, proc) p_children; /* (e) Pointer to list of children. */
/* The following fields are all zeroed upon creation in fork. */
#define p_startzero p_oppid
-
- pid_t p_oppid; /* (c + e) Save parent pid during ptrace. XXX */
- int p_dupfd; /* (c) Sideways ret value from fdopen. XXX */
- struct vmspace *p_vmspace; /* (b) Address space. */
-
- /* scheduling */
- u_int p_estcpu; /* (j) Time averaged value of p_cpticks. */
- int p_cpticks; /* (j) Ticks of cpu time. */
- fixpt_t p_pctcpu; /* (j) %cpu during p_swtime. */
- struct callout p_slpcallout; /* (h) Callout for sleep. */
- void *p_wchan; /* (j) Sleep address. */
- const char *p_wmesg; /* (j) Reason for sleep. */
- u_int p_swtime; /* (j) Time swapped in or out. */
- u_int p_slptime; /* (j) Time since last blocked. */
-
- struct callout p_itcallout; /* (h) Interval timer callout. */
- struct itimerval p_realtimer; /* (h?/k?) Alarm timer. */
- u_int64_t p_runtime; /* (j) Real time in microsec. */
- u_int64_t p_uu; /* (j) Previous user time in microsec. */
- u_int64_t p_su; /* (j) Previous system time in microsec. */
- u_int64_t p_iu; /* (j) Previous interrupt time in microsec. */
- u_int64_t p_uticks; /* (j) Statclock hits in user mode. */
- u_int64_t p_sticks; /* (j) Statclock hits in system mode. */
- u_int64_t p_iticks; /* (j) Statclock hits processing intr. */
-
- int p_traceflag; /* (j?) Kernel trace points. */
- struct vnode *p_tracep; /* (j?) Trace to vnode. */
-
- sigset_t p_siglist; /* (c) Signals arrived but not delivered. */
-
- struct vnode *p_textvp; /* (b) Vnode of executable. */
-
- struct mtx p_mtx; /* (k) Lock for this struct. */
- char p_lock; /* (c) Process lock (prevent swap) count. */
- u_char p_oncpu; /* (j) Which cpu we are on. */
- u_char p_lastcpu; /* (j) Last cpu we were on. */
- char p_rqindex; /* (j) Run queue index. */
-
- short p_locks; /* (*) DEBUG: lockmgr count of held locks */
- u_int p_stops; /* (c) Procfs event bitmask. */
- u_int p_stype; /* (c) Procfs stop event type. */
- char p_step; /* (c) Procfs stop *once* flag. */
- u_char p_pfsflags; /* (c) Procfs flags. */
- char p_pad3[2]; /* Alignment. */
- register_t p_retval[2]; /* (k) Syscall aux returns. */
- struct sigiolst p_sigiolst; /* (c) List of sigio sources. */
- int p_sigparent; /* (c) Signal to parent on exit. */
- sigset_t p_oldsigmask; /* (c) Saved mask from before sigpause. */
- int p_sig; /* (n) For core dump/debugger XXX. */
- u_long p_code; /* (n) For core dump/debugger XXX. */
- struct klist p_klist; /* (c) Knotes attached to this process. */
- struct lock_list_entry *p_sleeplocks; /* (k) Held sleep locks. */
- struct mtx *p_blocked; /* (j) Mutex process is blocked on. */
- const char *p_mtxname; /* (j) Name of mutex blocked on. */
- LIST_HEAD(, mtx) p_contested; /* (j) Contested locks. */
-
+ pid_t p_oppid; /* (c + e) Save ppid in ptrace. XXX */
+ struct vmspace *p_vmspace; /* (b) Address space. */
+ u_int p_swtime; /* (j) Time swapped in or out. */
+ struct itimerval p_realtimer; /* (h?/k?) Alarm timer. */
+ u_int64_t p_runtime; /* (j) Real time in microsec. */
+ int p_traceflag; /* (j?) Kernel trace points. */
+ struct vnode *p_tracep; /* (j?) Trace to vnode. */
+ sigset_t p_siglist; /* (c) Sigs arrived, not delivered. */
+ struct vnode *p_textvp; /* (b) Vnode of executable. */
+ struct mtx p_mtx; /* (k) Lock for this struct. */
+ char p_lock; /* (c) Proclock (prevent swap) count. */
+ struct klist p_klist; /* (c) Knotes attached to this proc. */
+ struct sigiolst p_sigiolst; /* (c) List of sigio sources. */
+ int p_sigparent; /* (c) Signal to parent on exit. */
+ sigset_t p_oldsigmask; /* (c) Saved mask from pre sigpause. */
+ int p_sig; /* (n) For core dump/debugger XXX. */
+ u_long p_code; /* (n) For core dump/debugger XXX. */
+ u_int p_stops; /* (c) Procfs event bitmask. */
+ u_int p_stype; /* (c) Procfs stop event type. */
+ char p_step; /* (c) Procfs stop *once* flag. */
+ u_char p_pfsflags; /* (c) Procfs flags. */
struct nlminfo *p_nlminfo; /* (?) only used by/for lockd */
- void *p_aioinfo; /* (c) ASYNC I/O info. */
- struct ithd *p_ithd; /* (b) For interrupt threads only. */
- int p_intr_nesting_level; /* (k) Interrupt recursion. */
-
+ void *p_aioinfo; /* (c) ASYNC I/O info. */
/* End area that is zeroed on creation. */
-#define p_endzero p_startcopy
-
-/* The following fields are all copied upon creation in fork. */
#define p_startcopy p_sigmask
- sigset_t p_sigmask; /* (c) Current signal mask. */
- stack_t p_sigstk; /* (c) Stack pointer and on-stack flag. */
-
- int p_magic; /* (b) Magic number. */
- struct priority p_pri; /* (j) Process priority. */
- char p_nice; /* (j?/k?) Process "nice" value. */
- char p_comm[MAXCOMLEN + 1]; /* (b) Process name. */
-
- struct pgrp *p_pgrp; /* (e?/c?) Pointer to process group. */
- struct sysentvec *p_sysent; /* (b) System call dispatch information. */
- struct pargs *p_args; /* (c + k) Process arguments. */
-
+/* The following fields are all copied upon creation in fork. */
+#define p_endzero p_startcopy
+ sigset_t p_sigmask; /* (c) Current signal mask. */
+ stack_t p_sigstk; /* (c) Stack ptr and on-stack flag. */
+ int p_magic; /* (b) Magic number. */
+ char p_comm[MAXCOMLEN + 1]; /* (b) Process name. */
+ struct pgrp *p_pgrp; /* (e?/c?) Pointer to process group. */
+ struct sysentvec *p_sysent; /* (b) Syscall dispatch info. */
+ struct pargs *p_args; /* (c + k) Process arguments. */
/* End area that is copied on creation. */
-#define p_endcopy p_addr
-
- struct user *p_addr; /* (k) Kernel virtual addr of u-area (CPU). */
- struct mdproc p_md; /* (k) Any machine-dependent fields. */
-
- u_short p_xstat; /* (c) Exit status for wait; also stop sig. */
- u_short p_acflag; /* (c) Accounting flags. */
- struct rusage *p_ru; /* (a) Exit information. XXX */
-
- struct proc *p_peers; /* (c) */
- struct proc *p_leader; /* (c) */
- void *p_emuldata; /* (c) Emulator state data. */
- struct trapframe *p_frame; /* (k) */
+#define p_endcopy p_xstat
+
+ u_short p_xstat; /* (c) Exit status; also stop sig. */
+ struct mdproc p_md; /* (k) Any machine-dependent fields. */
+ struct callout p_itcallout; /* (h) Interval timer callout. */
+ struct user *p_uarea; /* was p_addr. changed to break stuff */
+ u_short p_acflag; /* (c) Accounting flags. */
+ struct rusage *p_ru; /* (a) Exit information. XXX */
+ struct proc *p_peers; /* (c) */
+ struct proc *p_leader; /* (c) */
+ void *p_emuldata; /* (c) Emulator state data. */
};
+#define p_rlimit p_limit->pl_rlimit
+#define p_sigacts p_procsig->ps_sigacts
+#define p_sigignore p_procsig->ps_sigignore
+#define p_sigcatch p_procsig->ps_sigcatch
#define p_session p_pgrp->pg_session
#define p_pgid p_pgrp->pg_id
@@ -283,25 +452,25 @@ struct proc {
#define SMTX 7 /* Blocked on a mutex. */
/* These flags are kept in p_flag. */
+/* In a KSE world some go to a thread or a KSE (*)*/
#define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */
#define P_CONTROLT 0x00002 /* Has a controlling terminal. */
-#define P_KTHREAD 0x00004 /* Kernel thread. */
+#define P_KTHREAD 0x00004 /* Kernel thread. (*)*/
#define P_NOLOAD 0x00008 /* Ignore during load avg calculations. */
#define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */
-#define P_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */
#define P_SUGID 0x00100 /* Had set id privileges since last exec. */
#define P_SYSTEM 0x00200 /* System proc: no sigs, stats or swapping. */
#define P_TRACED 0x00800 /* Debugged process being traced. */
#define P_WAITED 0x01000 /* Debugging process has waited for child. */
#define P_WEXIT 0x02000 /* Working on exiting. */
#define P_EXEC 0x04000 /* Process called exec. */
+#define P_KSES 0x08000 /* Process is using KSEs. */
/* Should be moved to machine-dependent areas. */
#define P_BUFEXHAUST 0x100000 /* Dirty buffers flush is in progress. */
#define P_COWINPROGRESS 0x400000 /* Snapshot copy-on-write in progress. */
-#define P_DEADLKTREAT 0x800000 /* Lock aquisition - deadlock treatment. */
#define P_JAILED 0x1000000 /* Process is in jail. */
#define P_OLDMASK 0x2000000 /* Need to restore mask after suspend. */
@@ -309,18 +478,24 @@ struct proc {
/* These flags are kept in p_sflag and are protected with sched_lock. */
#define PS_INMEM 0x00001 /* Loaded into memory. */
-#define PS_OWEUPC 0x00002 /* Owe process an addupc() call at next ast. */
#define PS_PROFIL 0x00004 /* Has started profiling. */
-#define PS_SINTR 0x00008 /* Sleep is interruptible. */
-#define PS_TIMEOUT 0x00010 /* Timing out during sleep. */
#define PS_ALRMPEND 0x00020 /* Pending SIGVTALRM needs to be posted. */
#define PS_PROFPEND 0x00040 /* Pending SIGPROF needs to be posted. */
-#define PS_CVWAITQ 0x00080 /* Proces is on a cv_waitq (not slpq). */
#define PS_SWAPINREQ 0x00100 /* Swapin request due to wakeup. */
#define PS_SWAPPING 0x00200 /* Process is being swapped. */
-#define PS_ASTPENDING 0x00400 /* Process has a pending ast. */
-#define PS_NEEDRESCHED 0x00800 /* Process needs to yield. */
-#define PS_TIMOFAIL 0x01000 /* Timeout from sleep after we were awake. */
+
+#define TDF_SINTR 0x00008 /* Sleep is interruptible. */
+#define TDF_TIMEOUT 0x00010 /* Timing out during sleep. */
+#define TDF_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */
+#define TDF_CVWAITQ 0x00080 /* Proces is on a cv_waitq (not slpq). */
+#define TDF_DEADLKTREAT 0x800000 /* Lock aquisition - deadlock treatment. */
+
+#define KEF_OWEUPC 0x00002 /* Owe process an addupc() call at next ast. */
+#define KEF_ASTPENDING 0x00400 /* KSE has a pending ast. */
+#define KEF_NEEDRESCHED 0x00800 /* Process needs to yield. */
+#define TDF_TIMOFAIL 0x01000 /* Timeout from sleep after we were awake. */
+
+#define KEF_ONRUNQ 0x00000001 /* This KE is on a run queue */
#define P_MAGIC 0xbeefface
@@ -333,10 +508,22 @@ MALLOC_DECLARE(M_SUBPROC);
MALLOC_DECLARE(M_ZOMBIE);
#endif
+#define FOREACH_PROC_IN_SYSTEM(p) \
+ LIST_FOREACH((p), &allproc, p_list)
+#define FOREACH_KSEGRP_IN_PROC(p, kg) \
+ TAILQ_FOREACH((kg), &(p)->p_ksegrps, kg_ksegrp)
+#define FOREACH_THREAD_IN_GROUP(kg, td) \
+ TAILQ_FOREACH((td), &(kg)->kg_threads, td_kglist)
+#define FOREACH_KSE_IN_GROUP(kg, ke) \
+ TAILQ_FOREACH((ke), &(kg)->kg_kseq, ke_kglist)
+#define FOREACH_THREAD_IN_PROC(p, td) \
+ TAILQ_FOREACH((td), &(p)->p_threads, td_plist)
+
static __inline int
sigonstack(size_t sp)
{
- register struct proc *p = curproc;
+ register struct thread *td = curthread;
+ struct proc *p = td->td_proc;
return ((p->p_flag & P_ALTSTACK) ?
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
@@ -352,9 +539,9 @@ sigonstack(size_t sp)
* Notify the current process (p) that it has a signal pending,
* process as soon as possible.
*/
-#define signotify(p) do { \
+#define signotify(ke) do { \
mtx_assert(&sched_lock, MA_OWNED); \
- (p)->p_sflag |= PS_ASTPENDING; \
+ (ke)->ke_flags |= KEF_ASTPENDING; \
} while (0)
/* Handy macro to determine if p1 can mangle p2. */
@@ -429,6 +616,7 @@ extern u_long pgrphash;
extern struct sx allproc_lock;
extern struct sx proctree_lock;
extern struct proc proc0; /* Process slot for swapper. */
+extern struct thread *thread0; /* Primary thread in proc0 */
extern int hogticks; /* Limit on kernel cpu hogs. */
extern int nprocs, maxproc; /* Current and max number of procs. */
extern int maxprocperuid; /* Max procs per uid. */
@@ -439,6 +627,7 @@ extern int sched_quantum; /* Scheduling quantum in ticks. */
LIST_HEAD(proclist, proc);
TAILQ_HEAD(procqueue, proc);
+TAILQ_HEAD(threadqueue, thread);
extern struct proclist allproc; /* List of all processes. */
extern struct proclist zombproc; /* List of zombie processes. */
extern struct proc *initproc, *pageproc; /* Process slots for init, pager. */
@@ -465,14 +654,14 @@ struct pgrp *pgfind __P((pid_t)); /* Find process group by id. */
struct proc *zpfind __P((pid_t)); /* Find zombie process by id. */
void ast __P((struct trapframe *framep));
-struct proc *chooseproc __P((void));
+struct thread *choosethread __P((void));
int enterpgrp __P((struct proc *p, pid_t pgid, int mksess));
void faultin __P((struct proc *p));
void fixjobc __P((struct proc *p, struct pgrp *pgrp, int entering));
-int fork1 __P((struct proc *, int, struct proc **));
+int fork1 __P((struct thread *, int, struct proc **));
void fork_exit __P((void (*)(void *, struct trapframe *), void *,
struct trapframe *));
-void fork_return __P((struct proc *, struct trapframe *));
+void fork_return __P((struct thread *, struct trapframe *));
int inferior __P((struct proc *p));
int leavepgrp __P((struct proc *p));
void mi_switch __P((void));
@@ -482,32 +671,33 @@ int p_cansched __P((struct proc *p1, struct proc *p2));
int p_cansignal __P((struct proc *p1, struct proc *p2, int signum));
int p_trespass __P((struct proc *p1, struct proc *p2));
void procinit __P((void));
+void proc_linkup __P((struct proc *p));
void proc_reparent __P((struct proc *child, struct proc *newparent));
int procrunnable __P((void));
-void remrunqueue __P((struct proc *));
-void resetpriority __P((struct proc *));
+void remrunqueue __P((struct thread *));
+void resetpriority __P((struct ksegrp *));
int roundrobin_interval __P((void));
-void schedclock __P((struct proc *));
-void setrunnable __P((struct proc *));
-void setrunqueue __P((struct proc *));
+void schedclock __P((struct thread *));
+void setrunnable __P((struct thread *));
+void setrunqueue __P((struct thread *));
void setsugid __P((struct proc *p));
void sleepinit __P((void));
void stopevent __P((struct proc *, u_int, u_int));
void cpu_idle __P((void));
void cpu_switch __P((void));
void cpu_throw __P((void)) __dead2;
-void unsleep __P((struct proc *));
-void updatepri __P((struct proc *));
-void userret __P((struct proc *, struct trapframe *, u_int));
-void maybe_resched __P((struct proc *));
-
-void cpu_exit __P((struct proc *));
-void exit1 __P((struct proc *, int)) __dead2;
-void cpu_fork __P((struct proc *, struct proc *, int));
-void cpu_set_fork_handler __P((struct proc *, void (*)(void *), void *));
+void unsleep __P((struct thread *));
+void updatepri __P((struct thread *));
+void userret __P((struct thread *, struct trapframe *, u_int));
+void maybe_resched __P((struct ksegrp *));
+
+void cpu_exit __P((struct thread *));
+void exit1 __P((struct thread *, int)) __dead2;
+void cpu_fork __P((struct thread *, struct proc *, int));
+void cpu_set_fork_handler __P((struct thread *, void (*)(void *), void *));
int trace_req __P((struct proc *));
void cpu_wait __P((struct proc *));
-int cpu_coredump __P((struct proc *, struct vnode *, struct ucred *));
+int cpu_coredump __P((struct thread *, struct vnode *, struct ucred *));
#endif /* _KERNEL */
#endif /* !_SYS_PROC_H_ */