4 /* Here is the declaration of the process table. It contains all process
5 * data, including registers, flags, scheduling priority, memory map,
6 * accounting, message passing (IPC) information, and so on.
8 * Many assembly code routines reference fields in it. The offsets to these
9 * fields are defined in the assembler include file sconst.h. When changing
10 * struct proc, be sure to change sconst.h to match.
12 #include <minix/com.h>
13 #include <minix/portio.h>
18 struct stackframe_s p_reg
; /* process' registers saved in stack frame */
19 struct segframe p_seg
; /* segment descriptors */
20 proc_nr_t p_nr
; /* number of this process (for fast access) */
21 struct priv
*p_priv
; /* system privileges structure */
22 short p_rts_flags
; /* process is runnable only if zero */
23 short p_misc_flags
; /* flags that do not suspend the process */
25 char p_priority
; /* current scheduling priority */
26 char p_max_priority
; /* maximum scheduling priority */
27 char p_ticks_left
; /* number of scheduling ticks left */
28 char p_quantum_size
; /* quantum size in ticks */
30 struct mem_map p_memmap
[NR_LOCAL_SEGS
]; /* memory map (T, D, S) */
31 struct pagefault p_pagefault
; /* valid if PAGEFAULT in p_rts_flags set */
32 struct proc
*p_nextpagefault
; /* next on PAGEFAULT chain */
34 clock_t p_user_time
; /* user time in ticks */
35 clock_t p_sys_time
; /* sys time in ticks */
37 clock_t p_virt_left
; /* number of ticks left on virtual timer */
38 clock_t p_prof_left
; /* number of ticks left on profile timer */
40 struct proc
*p_nextready
; /* pointer to next ready process */
41 struct proc
*p_caller_q
; /* head of list of procs wishing to send */
42 struct proc
*p_q_link
; /* link to next proc wishing to send */
43 int p_getfrom_e
; /* from whom does process want to receive? */
44 int p_sendto_e
; /* to whom does process want to send? */
46 sigset_t p_pending
; /* bit map for pending kernel signals */
48 char p_name
[P_NAME_LEN
]; /* name of the process, including \0 */
50 endpoint_t p_endpoint
; /* endpoint number, generation-aware */
52 message p_sendmsg
; /* Message from this process if SENDING */
53 message p_delivermsg
; /* Message for this process if MF_DELIVERMSG */
54 vir_bytes p_delivermsg_vir
; /* Virtual addr this proc wants message at */
55 vir_bytes p_delivermsg_lin
; /* Linear addr this proc wants message at */
57 /* If handler functions detect a process wants to do something with
58 * memory that isn't present, VM has to fix it. Until it has asked
59 * what needs to be done and fixed it, save necessary state here.
61 * The requester gets a copy of its request message in reqmsg and gets
65 struct proc
*nextrestart
; /* next in vmrestart chain */
66 struct proc
*nextrequestor
; /* next in vmrequest chain */
67 #define VMSTYPE_SYS_NONE 0
68 #define VMSTYPE_KERNELCALL 1
69 #define VMSTYPE_DELIVERMSG 2
70 int type
; /* suspended operation */
72 /* VMSTYPE_SYS_MESSAGE */
73 message reqmsg
; /* suspended request message */
76 /* Parameters of request to VM */
77 vir_bytes start
, length
; /* memory range */
78 u8_t writeflag
; /* nonzero for write access */
81 /* VM result when available */
88 /* If the suspended operation is a sys_call, its details are
93 struct proc
*next_soft_notify
;
98 #define PMAGIC 0xC0FFEE1
99 int p_magic
; /* check validity of proc pointers */
107 /* Bits for the runtime flags. A process is runnable iff p_rts_flags == 0. */
108 #define SLOT_FREE 0x01 /* process slot is free */
109 #define NO_PRIORITY 0x02 /* process has been stopped */
110 #define SENDING 0x04 /* process blocked trying to send */
111 #define RECEIVING 0x08 /* process blocked trying to receive */
112 #define SIGNALED 0x10 /* set when new kernel signal arrives */
113 #define SIG_PENDING 0x20 /* unready while signal being processed */
114 #define P_STOP 0x40 /* set when process is being traced */
115 #define NO_PRIV 0x80 /* keep forked system process from running */
116 #define NO_ENDPOINT 0x100 /* process cannot send or receive messages */
117 #define VMINHIBIT 0x200 /* not scheduled until pagetable set by VM */
118 #define PAGEFAULT 0x400 /* process has unhandled pagefault */
119 #define VMREQUEST 0x800 /* originator of vm memory request */
120 #define VMREQTARGET 0x1000 /* target of vm memory request */
122 /* These runtime flags can be tested and manipulated by these macros. */
124 #define RTS_ISSET(rp, f) (((rp)->p_rts_flags & (f)) == (f))
127 /* Set flag and dequeue if the process was runnable. */
128 #define RTS_SET(rp, f) \
130 vmassert(intr_disabled()); \
131 if(!(rp)->p_rts_flags) { dequeue(rp); } \
132 (rp)->p_rts_flags |= (f); \
133 vmassert(intr_disabled()); \
136 /* Clear flag and enqueue if the process was not runnable but is now. */
137 #define RTS_UNSET(rp, f) \
140 vmassert(intr_disabled()); \
141 rts = (rp)->p_rts_flags; \
142 (rp)->p_rts_flags &= ~(f); \
143 if(rts && !(rp)->p_rts_flags) { enqueue(rp); } \
144 vmassert(intr_disabled()); \
147 /* Set flag and dequeue if the process was runnable. */
148 #define RTS_LOCK_SET(rp, f) \
151 if(!intr_disabled()) { u = 1; lock; } \
152 if(!(rp)->p_rts_flags) { dequeue(rp); } \
153 (rp)->p_rts_flags |= (f); \
157 /* Clear flag and enqueue if the process was not runnable but is now. */
158 #define RTS_LOCK_UNSET(rp, f) \
162 if(!intr_disabled()) { u = 1; lock; } \
163 rts = (rp)->p_rts_flags; \
164 (rp)->p_rts_flags &= ~(f); \
165 if(rts && !(rp)->p_rts_flags) { enqueue(rp); } \
169 /* Set flags to this value. */
170 #define RTS_LOCK_SETFLAGS(rp, f) \
173 if(!intr_disabled()) { u = 1; lock; } \
174 if(!(rp)->p_rts_flags && (f)) { dequeue(rp); } \
175 (rp)->p_rts_flags = (f); \
180 #define MF_REPLY_PEND 0x01 /* reply to IPC_REQUEST is pending */
181 #define MF_VIRT_TIMER 0x02 /* process-virtual timer is running */
182 #define MF_PROF_TIMER 0x04 /* process-virtual profile timer is running */
183 #define MF_ASYNMSG 0x10 /* Asynchrous message pending */
184 #define MF_FULLVM 0x20
185 #define MF_DELIVERMSG 0x40 /* Copy message for him before running */
187 /* Scheduling priorities for p_priority. Values must start at zero (highest
188 * priority) and increment. Priorities of the processes in the boot image
189 * can be set in table.c. IDLE must have a queue for itself, to prevent low
190 * priority user processes to run round-robin with IDLE.
192 #define NR_SCHED_QUEUES 16 /* MUST equal minimum priority + 1 */
193 #define TASK_Q 0 /* highest, used for kernel tasks */
194 #define MAX_USER_Q 0 /* highest priority for user processes */
195 #define USER_Q 7 /* default (should correspond to nice 0) */
196 #define MIN_USER_Q 14 /* minimum priority for user processes */
197 #define IDLE_Q 15 /* lowest, only IDLE process goes here */
199 /* Magic process table addresses. */
200 #define BEG_PROC_ADDR (&proc[0])
201 #define BEG_USER_ADDR (&proc[NR_TASKS])
202 #define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS])
204 #define NIL_PROC ((struct proc *) 0)
205 #define NIL_SYS_PROC ((struct proc *) 1)
206 #define cproc_addr(n) (&(proc + NR_TASKS)[(n)])
207 #define proc_addr(n) (&(proc[NR_TASKS + (n)]))
208 #define proc_nr(p) ((p)->p_nr)
210 #define isokprocn(n) ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS)
211 #define isemptyn(n) isemptyp(proc_addr(n))
212 #define isemptyp(p) ((p)->p_rts_flags == SLOT_FREE)
213 #define iskernelp(p) ((p) < BEG_USER_ADDR)
214 #define iskerneln(n) ((n) < 0)
215 #define isuserp(p) isusern((p) >= BEG_USER_ADDR)
216 #define isusern(n) ((n) >= 0)
218 /* The process table and pointers to process table slots. The pointers allow
219 * faster access because now a process entry can be found by indexing the
220 * pproc_addr array, while accessing an element i requires a multiplication
221 * with sizeof(struct proc) to determine the address.
223 EXTERN
struct proc proc
[NR_TASKS
+ NR_PROCS
]; /* process table */
224 EXTERN
struct proc
*rdy_head
[NR_SCHED_QUEUES
]; /* ptrs to ready list headers */
225 EXTERN
struct proc
*rdy_tail
[NR_SCHED_QUEUES
]; /* ptrs to ready list tails */