- simplify findhole() for use for 1 page only
[minix.git] / kernel / proc.h
blobac07514b04468354f264f8db948df8d8a1d1117a
1 #ifndef PROC_H
2 #define PROC_H
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>
14 #include "const.h"
15 #include "priv.h"
17 struct proc {
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
62 * VMREQUEST set.
64 struct {
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 */
71 union {
72 /* VMSTYPE_SYS_MESSAGE */
73 message reqmsg; /* suspended request message */
74 } saved;
76 /* Parameters of request to VM */
77 vir_bytes start, length; /* memory range */
78 u8_t writeflag; /* nonzero for write access */
79 endpoint_t who;
81 /* VM result when available */
82 int vmresult;
84 #if DEBUG_VMASSERT
85 char stacktrace[200];
86 #endif
88 /* If the suspended operation is a sys_call, its details are
89 * stored here.
91 } p_vmrequest;
93 struct proc *next_soft_notify;
94 int p_softnotified;
96 #if DEBUG_SCHED_CHECK
97 int p_ready, p_found;
98 #define PMAGIC 0xC0FFEE1
99 int p_magic; /* check validity of proc pointers */
100 #endif
102 #if DEBUG_TRACE
103 int p_schedules;
104 #endif
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) \
129 do { \
130 vmassert(intr_disabled()); \
131 if(!(rp)->p_rts_flags) { dequeue(rp); } \
132 (rp)->p_rts_flags |= (f); \
133 vmassert(intr_disabled()); \
134 } while(0)
136 /* Clear flag and enqueue if the process was not runnable but is now. */
137 #define RTS_UNSET(rp, f) \
138 do { \
139 int rts; \
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()); \
145 } while(0)
147 /* Set flag and dequeue if the process was runnable. */
148 #define RTS_LOCK_SET(rp, f) \
149 do { \
150 int u = 0; \
151 if(!intr_disabled()) { u = 1; lock; } \
152 if(!(rp)->p_rts_flags) { dequeue(rp); } \
153 (rp)->p_rts_flags |= (f); \
154 if(u) { unlock; } \
155 } while(0)
157 /* Clear flag and enqueue if the process was not runnable but is now. */
158 #define RTS_LOCK_UNSET(rp, f) \
159 do { \
160 int rts; \
161 int u = 0; \
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); } \
166 if(u) { unlock; } \
167 } while(0)
169 /* Set flags to this value. */
170 #define RTS_LOCK_SETFLAGS(rp, f) \
171 do { \
172 int u = 0; \
173 if(!intr_disabled()) { u = 1; lock; } \
174 if(!(rp)->p_rts_flags && (f)) { dequeue(rp); } \
175 (rp)->p_rts_flags = (f); \
176 if(u) { unlock; } \
177 } while(0)
179 /* Misc flags */
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 */
227 #endif /* PROC_H */