xref: /minix3/minix/kernel/proc.h (revision 6b0f33d0fc0227339bf6308f08fe358bbd70074d)
1433d6423SLionel Sambuc #ifndef PROC_H
2433d6423SLionel Sambuc #define PROC_H
3433d6423SLionel Sambuc 
4433d6423SLionel Sambuc #include <minix/const.h>
5433d6423SLionel Sambuc #include <sys/cdefs.h>
6433d6423SLionel Sambuc 
7433d6423SLionel Sambuc #ifndef __ASSEMBLY__
8433d6423SLionel Sambuc 
9433d6423SLionel Sambuc /* Here is the declaration of the process table.  It contains all process
10433d6423SLionel Sambuc  * data, including registers, flags, scheduling priority, memory map,
11433d6423SLionel Sambuc  * accounting, message passing (IPC) information, and so on.
12433d6423SLionel Sambuc  *
13433d6423SLionel Sambuc  * Many assembly code routines reference fields in it.  The offsets to these
14433d6423SLionel Sambuc  * fields are defined in the assembler include file sconst.h.  When changing
15433d6423SLionel Sambuc  * struct proc, be sure to change sconst.h to match.
16433d6423SLionel Sambuc  */
17433d6423SLionel Sambuc #include <minix/com.h>
18433d6423SLionel Sambuc #include <minix/portio.h>
19433d6423SLionel Sambuc #include "const.h"
20433d6423SLionel Sambuc #include "priv.h"
21433d6423SLionel Sambuc 
22433d6423SLionel Sambuc struct proc {
23433d6423SLionel Sambuc   struct stackframe_s p_reg;	/* process' registers saved in stack frame */
24433d6423SLionel Sambuc   struct segframe p_seg;	/* segment descriptors */
25433d6423SLionel Sambuc   proc_nr_t p_nr;		/* number of this process (for fast access) */
26433d6423SLionel Sambuc   struct priv *p_priv;		/* system privileges structure */
27433d6423SLionel Sambuc   volatile u32_t p_rts_flags;	/* process is runnable only if zero */
28433d6423SLionel Sambuc   volatile u32_t p_misc_flags;	/* flags that do not suspend the process */
29433d6423SLionel Sambuc 
30433d6423SLionel Sambuc   char p_priority;		/* current process priority */
31433d6423SLionel Sambuc   u64_t p_cpu_time_left;	/* time left to use the cpu */
32433d6423SLionel Sambuc   unsigned p_quantum_size_ms;	/* assigned time quantum in ms
33433d6423SLionel Sambuc 				   FIXME remove this */
34433d6423SLionel Sambuc   struct proc *p_scheduler;	/* who should get out of quantum msg */
35433d6423SLionel Sambuc   unsigned p_cpu;		/* what CPU is the process running on */
36433d6423SLionel Sambuc #ifdef CONFIG_SMP
37433d6423SLionel Sambuc   bitchunk_t p_cpu_mask[BITMAP_CHUNKS(CONFIG_MAX_CPUS)]; /* what CPUs is the
38433d6423SLionel Sambuc 							    process allowed to
39433d6423SLionel Sambuc 							    run on */
40433d6423SLionel Sambuc   bitchunk_t p_stale_tlb[BITMAP_CHUNKS(CONFIG_MAX_CPUS)]; /* On which cpu are
41433d6423SLionel Sambuc 				possibly stale entries from this process and has
42433d6423SLionel Sambuc 				to be fresed the next kernel touches this
43433d6423SLionel Sambuc 				processes memory
44433d6423SLionel Sambuc 				 */
45433d6423SLionel Sambuc #endif
46433d6423SLionel Sambuc 
47433d6423SLionel Sambuc   /* Accounting statistics that get passed to the process' scheduler */
48433d6423SLionel Sambuc   struct {
49433d6423SLionel Sambuc 	u64_t enter_queue;	/* time when enqueued (cycles) */
50433d6423SLionel Sambuc 	u64_t time_in_queue;	/* time spent in queue */
51433d6423SLionel Sambuc 	unsigned long dequeues;
52433d6423SLionel Sambuc 	unsigned long ipc_sync;
53433d6423SLionel Sambuc 	unsigned long ipc_async;
54433d6423SLionel Sambuc 	unsigned long preempted;
55433d6423SLionel Sambuc   } p_accounting;
56433d6423SLionel Sambuc 
57*6b0f33d0SDavid van Moolenbroek   clock_t p_dequeued;		/* uptime at which process was last dequeued */
58*6b0f33d0SDavid van Moolenbroek 
59433d6423SLionel Sambuc   clock_t p_user_time;		/* user time in ticks */
60433d6423SLionel Sambuc   clock_t p_sys_time;		/* sys time in ticks */
61433d6423SLionel Sambuc 
62433d6423SLionel Sambuc   clock_t p_virt_left;		/* number of ticks left on virtual timer */
63433d6423SLionel Sambuc   clock_t p_prof_left;		/* number of ticks left on profile timer */
64433d6423SLionel Sambuc 
65433d6423SLionel Sambuc   u64_t p_cycles;		/* how many cycles did the process use */
66433d6423SLionel Sambuc   u64_t p_kcall_cycles;		/* kernel cycles caused by this proc (kcall) */
67433d6423SLionel Sambuc   u64_t p_kipc_cycles;		/* cycles caused by this proc (ipc) */
68433d6423SLionel Sambuc 
691f3ef2b2SDavid van Moolenbroek   u64_t p_tick_cycles;		/* cycles accumulated for up to a clock tick */
701f3ef2b2SDavid van Moolenbroek   struct cpuavg p_cpuavg;	/* running CPU average, for ps(1) */
711f3ef2b2SDavid van Moolenbroek 
72433d6423SLionel Sambuc   struct proc *p_nextready;	/* pointer to next ready process */
73433d6423SLionel Sambuc   struct proc *p_caller_q;	/* head of list of procs wishing to send */
74433d6423SLionel Sambuc   struct proc *p_q_link;	/* link to next proc wishing to send */
75433d6423SLionel Sambuc   endpoint_t p_getfrom_e;	/* from whom does process want to receive? */
76433d6423SLionel Sambuc   endpoint_t p_sendto_e;	/* to whom does process want to send? */
77433d6423SLionel Sambuc 
78433d6423SLionel Sambuc   sigset_t p_pending;		/* bit map for pending kernel signals */
79433d6423SLionel Sambuc 
80433d6423SLionel Sambuc   char p_name[PROC_NAME_LEN];	/* name of the process, including \0 */
81433d6423SLionel Sambuc 
82433d6423SLionel Sambuc   endpoint_t p_endpoint;	/* endpoint number, generation-aware */
83433d6423SLionel Sambuc 
84433d6423SLionel Sambuc   message p_sendmsg;		/* Message from this process if SENDING */
85433d6423SLionel Sambuc   message p_delivermsg;		/* Message for this process if MF_DELIVERMSG */
86433d6423SLionel Sambuc   vir_bytes p_delivermsg_vir;	/* Virtual addr this proc wants message at */
87433d6423SLionel Sambuc 
88433d6423SLionel Sambuc   /* If handler functions detect a process wants to do something with
89433d6423SLionel Sambuc    * memory that isn't present, VM has to fix it. Until it has asked
90433d6423SLionel Sambuc    * what needs to be done and fixed it, save necessary state here.
91433d6423SLionel Sambuc    *
92433d6423SLionel Sambuc    * The requester gets a copy of its request message in reqmsg and gets
93433d6423SLionel Sambuc    * VMREQUEST set.
94433d6423SLionel Sambuc    */
95433d6423SLionel Sambuc   struct {
96433d6423SLionel Sambuc 	struct proc	*nextrestart;	/* next in vmrestart chain */
97433d6423SLionel Sambuc 	struct proc	*nextrequestor;	/* next in vmrequest chain */
98433d6423SLionel Sambuc #define VMSTYPE_SYS_NONE	0
99433d6423SLionel Sambuc #define VMSTYPE_KERNELCALL	1
100433d6423SLionel Sambuc #define VMSTYPE_DELIVERMSG	2
101433d6423SLionel Sambuc #define VMSTYPE_MAP		3
102433d6423SLionel Sambuc 
103433d6423SLionel Sambuc 	int		type;		/* suspended operation */
10450b7f13fSCristiano Giuffrida 	union ixfer_saved{
105433d6423SLionel Sambuc 		/* VMSTYPE_SYS_MESSAGE */
106433d6423SLionel Sambuc 		message		reqmsg;	/* suspended request message */
107433d6423SLionel Sambuc 	} saved;
108433d6423SLionel Sambuc 
109433d6423SLionel Sambuc 	/* Parameters of request to VM */
110433d6423SLionel Sambuc 	int		req_type;
111433d6423SLionel Sambuc 	endpoint_t	target;
11250b7f13fSCristiano Giuffrida 	union ixfer_params{
113433d6423SLionel Sambuc 		struct {
114433d6423SLionel Sambuc 			vir_bytes 	start, length;	/* memory range */
115433d6423SLionel Sambuc 			u8_t		writeflag;	/* nonzero for write access */
116433d6423SLionel Sambuc 		} check;
117433d6423SLionel Sambuc 	} params;
118433d6423SLionel Sambuc 	/* VM result when available */
119433d6423SLionel Sambuc 	int		vmresult;
120433d6423SLionel Sambuc 
121433d6423SLionel Sambuc 	/* If the suspended operation is a sys_call, its details are
122433d6423SLionel Sambuc 	 * stored here.
123433d6423SLionel Sambuc 	 */
124433d6423SLionel Sambuc   } p_vmrequest;
125433d6423SLionel Sambuc 
126433d6423SLionel Sambuc   int p_found;	/* consistency checking variables */
127433d6423SLionel Sambuc   int p_magic;		/* check validity of proc pointers */
128433d6423SLionel Sambuc 
129433d6423SLionel Sambuc   /* if MF_SC_DEFER is set, this struct is valid and contains the
130433d6423SLionel Sambuc    * do_ipc() arguments that are still to be executed
131433d6423SLionel Sambuc    */
132433d6423SLionel Sambuc   struct { reg_t r1, r2, r3; } p_defer;
133433d6423SLionel Sambuc 
134433d6423SLionel Sambuc #if DEBUG_TRACE
135433d6423SLionel Sambuc   int p_schedules;
136433d6423SLionel Sambuc #endif
137433d6423SLionel Sambuc };
138433d6423SLionel Sambuc 
139433d6423SLionel Sambuc #endif /* __ASSEMBLY__ */
140433d6423SLionel Sambuc 
141433d6423SLionel Sambuc /* Bits for the runtime flags. A process is runnable iff p_rts_flags == 0. */
142433d6423SLionel Sambuc #define RTS_SLOT_FREE	0x01	/* process slot is free */
143433d6423SLionel Sambuc #define RTS_PROC_STOP	0x02	/* process has been stopped */
144433d6423SLionel Sambuc #define RTS_SENDING	0x04	/* process blocked trying to send */
145433d6423SLionel Sambuc #define RTS_RECEIVING	0x08	/* process blocked trying to receive */
146433d6423SLionel Sambuc #define RTS_SIGNALED	0x10	/* set when new kernel signal arrives */
147433d6423SLionel Sambuc #define RTS_SIG_PENDING	0x20	/* unready while signal being processed */
148433d6423SLionel Sambuc #define RTS_P_STOP	0x40	/* set when process is being traced */
149433d6423SLionel Sambuc #define RTS_NO_PRIV	0x80	/* keep forked system process from running */
150433d6423SLionel Sambuc #define RTS_NO_ENDPOINT	0x100	/* process cannot send or receive messages */
151433d6423SLionel Sambuc #define RTS_VMINHIBIT	0x200	/* not scheduled until pagetable set by VM */
152433d6423SLionel Sambuc #define RTS_PAGEFAULT	0x400	/* process has unhandled pagefault */
153433d6423SLionel Sambuc #define RTS_VMREQUEST	0x800	/* originator of vm memory request */
154433d6423SLionel Sambuc #define RTS_VMREQTARGET	0x1000	/* target of vm memory request */
155433d6423SLionel Sambuc #define RTS_PREEMPTED	0x4000	/* this process was preempted by a higher
156433d6423SLionel Sambuc 				   priority process and we should pick a new one
157433d6423SLionel Sambuc 				   to run. Processes with this flag should be
158433d6423SLionel Sambuc 				   returned to the front of their current
159433d6423SLionel Sambuc 				   priority queue if they are still runnable
160433d6423SLionel Sambuc 				   before we pick a new one
161433d6423SLionel Sambuc 				 */
162433d6423SLionel Sambuc #define RTS_NO_QUANTUM	0x8000	/* process ran out of its quantum and we should
163433d6423SLionel Sambuc 				   pick a new one. Process was dequeued and
164433d6423SLionel Sambuc 				   should be enqueued at the end of some run
165433d6423SLionel Sambuc 				   queue again */
166433d6423SLionel Sambuc #define RTS_BOOTINHIBIT	0x10000	/* not ready until VM has made it */
167433d6423SLionel Sambuc 
168433d6423SLionel Sambuc /* A process is runnable iff p_rts_flags == 0. */
169433d6423SLionel Sambuc #define rts_f_is_runnable(flg)	((flg) == 0)
170433d6423SLionel Sambuc #define proc_is_runnable(p)	(rts_f_is_runnable((p)->p_rts_flags))
171433d6423SLionel Sambuc 
172433d6423SLionel Sambuc #define proc_is_preempted(p)	((p)->p_rts_flags & RTS_PREEMPTED)
173433d6423SLionel Sambuc #define proc_no_quantum(p)	((p)->p_rts_flags & RTS_NO_QUANTUM)
174433d6423SLionel Sambuc #define proc_ptr_ok(p)		((p)->p_magic == PMAGIC)
175433d6423SLionel Sambuc #define proc_used_fpu(p)	((p)->p_misc_flags & (MF_FPU_INITIALIZED))
176433d6423SLionel Sambuc 
177433d6423SLionel Sambuc /* test whether the process is scheduled by the kernel's default policy  */
178433d6423SLionel Sambuc #define proc_kernel_scheduler(p)	((p)->p_scheduler == NULL || \
179433d6423SLionel Sambuc 					(p)->p_scheduler == (p))
180433d6423SLionel Sambuc 
181433d6423SLionel Sambuc /* Macro to return: on which process is a certain process blocked?
182433d6423SLionel Sambuc  * return endpoint number (can be ANY) or NONE. It's important to
183433d6423SLionel Sambuc  * check RTS_SENDING first, and then RTS_RECEIVING, as they could
184433d6423SLionel Sambuc  * both be on (if a ipc_sendrec() blocks on sending), and p_getfrom_e
185433d6423SLionel Sambuc  * could be nonsense even though RTS_RECEIVING is on.
186433d6423SLionel Sambuc  */
187433d6423SLionel Sambuc #define P_BLOCKEDON(p)							\
188433d6423SLionel Sambuc 	(								\
189433d6423SLionel Sambuc 		((p)->p_rts_flags & RTS_SENDING) ? 			\
190433d6423SLionel Sambuc 		(p)->p_sendto_e : 					\
191433d6423SLionel Sambuc 		(							\
192433d6423SLionel Sambuc 			(						\
193433d6423SLionel Sambuc 				((p)->p_rts_flags & RTS_RECEIVING) ?	\
194433d6423SLionel Sambuc 				(p)->p_getfrom_e : 			\
195433d6423SLionel Sambuc 				NONE					\
196433d6423SLionel Sambuc 			) 						\
197433d6423SLionel Sambuc 		)							\
198433d6423SLionel Sambuc 	)
199433d6423SLionel Sambuc 
200433d6423SLionel Sambuc /* These runtime flags can be tested and manipulated by these macros. */
201433d6423SLionel Sambuc 
202433d6423SLionel Sambuc #define RTS_ISSET(rp, f) (((rp)->p_rts_flags & (f)) == (f))
203433d6423SLionel Sambuc 
204433d6423SLionel Sambuc 
205433d6423SLionel Sambuc /* Set flag and dequeue if the process was runnable. */
206433d6423SLionel Sambuc #define RTS_SET(rp, f)							\
207433d6423SLionel Sambuc 	do {								\
208433d6423SLionel Sambuc 		const int rts = (rp)->p_rts_flags;			\
209433d6423SLionel Sambuc 		(rp)->p_rts_flags |= (f);				\
210433d6423SLionel Sambuc 		if(rts_f_is_runnable(rts) && !proc_is_runnable(rp)) {	\
211433d6423SLionel Sambuc 			dequeue(rp);					\
212433d6423SLionel Sambuc 		}							\
213433d6423SLionel Sambuc 	} while(0)
214433d6423SLionel Sambuc 
215433d6423SLionel Sambuc /* Clear flag and enqueue if the process was not runnable but is now. */
216433d6423SLionel Sambuc #define RTS_UNSET(rp, f) 						\
217433d6423SLionel Sambuc 	do {								\
218433d6423SLionel Sambuc 		int rts;						\
219433d6423SLionel Sambuc 		rts = (rp)->p_rts_flags;				\
220433d6423SLionel Sambuc 		(rp)->p_rts_flags &= ~(f);				\
221433d6423SLionel Sambuc 		if(!rts_f_is_runnable(rts) && proc_is_runnable(rp)) {	\
222433d6423SLionel Sambuc 			enqueue(rp);					\
223433d6423SLionel Sambuc 		}							\
224433d6423SLionel Sambuc 	} while(0)
225433d6423SLionel Sambuc 
226433d6423SLionel Sambuc /* Set flags to this value. */
227433d6423SLionel Sambuc #define RTS_SETFLAGS(rp, f)					\
228433d6423SLionel Sambuc 	do {								\
229433d6423SLionel Sambuc 		if(proc_is_runnable(rp) && (f)) { dequeue(rp); }		\
230433d6423SLionel Sambuc 		(rp)->p_rts_flags = (f);				\
231433d6423SLionel Sambuc 	} while(0)
232433d6423SLionel Sambuc 
233433d6423SLionel Sambuc /* Misc flags */
234433d6423SLionel Sambuc #define MF_REPLY_PEND	0x001	/* reply to IPC_REQUEST is pending */
235433d6423SLionel Sambuc #define MF_VIRT_TIMER	0x002	/* process-virtual timer is running */
236433d6423SLionel Sambuc #define MF_PROF_TIMER	0x004	/* process-virtual profile timer is running */
237433d6423SLionel Sambuc #define MF_KCALL_RESUME 0x008	/* processing a kernel call was interrupted,
238433d6423SLionel Sambuc 				   most likely because we need VM to resolve a
239433d6423SLionel Sambuc 				   problem or a long running copy was preempted.
240433d6423SLionel Sambuc 				   We need to resume the kernel call execution
241433d6423SLionel Sambuc 				   now
242433d6423SLionel Sambuc 				 */
243433d6423SLionel Sambuc #define MF_DELIVERMSG	0x040	/* Copy message for him before running */
244433d6423SLionel Sambuc #define MF_SIG_DELAY	0x080	/* Send signal when no longer sending */
245433d6423SLionel Sambuc #define MF_SC_ACTIVE	0x100	/* Syscall tracing: in a system call now */
246433d6423SLionel Sambuc #define MF_SC_DEFER	0x200	/* Syscall tracing: deferred system call */
247433d6423SLionel Sambuc #define MF_SC_TRACE	0x400	/* Syscall tracing: trigger syscall events */
248433d6423SLionel Sambuc #define MF_FPU_INITIALIZED	0x1000  /* process already used math, so fpu
249433d6423SLionel Sambuc 					 * regs are significant (initialized)*/
250433d6423SLionel Sambuc #define MF_SENDING_FROM_KERNEL	0x2000 /* message of this process is from kernel */
251433d6423SLionel Sambuc #define MF_CONTEXT_SET	0x4000 /* don't touch context */
252433d6423SLionel Sambuc #define MF_SPROF_SEEN	0x8000 /* profiling has seen this process */
253433d6423SLionel Sambuc #define MF_FLUSH_TLB	0x10000	/* if set, TLB must be flushed before letting
254433d6423SLionel Sambuc 				   this process run again. Currently it only
255433d6423SLionel Sambuc 				   applies to SMP */
256433d6423SLionel Sambuc #define MF_SENDA_VM_MISS 0x20000 /* set if a processes wanted to receive an asyn
257433d6423SLionel Sambuc 				    message from this sender but could not
258433d6423SLionel Sambuc 				    because of VM modifying the sender's address
259433d6423SLionel Sambuc 				    space*/
260433d6423SLionel Sambuc #define MF_STEP		 0x40000 /* Single-step process */
2618bab0dfaSBen Gras #define MF_MSGFAILED	 0x80000
262366d18b2SDavid van Moolenbroek #define MF_NICED	0x100000 /* user has lowered max process priority */
263433d6423SLionel Sambuc 
264433d6423SLionel Sambuc /* Magic process table addresses. */
265433d6423SLionel Sambuc #define BEG_PROC_ADDR (&proc[0])
266433d6423SLionel Sambuc #define BEG_USER_ADDR (&proc[NR_TASKS])
267433d6423SLionel Sambuc #define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS])
268433d6423SLionel Sambuc 
269433d6423SLionel Sambuc #define proc_addr(n)      (&(proc[NR_TASKS + (n)]))
270433d6423SLionel Sambuc #define proc_nr(p) 	  ((p)->p_nr)
271433d6423SLionel Sambuc 
272433d6423SLionel Sambuc #define isokprocn(n)      ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS)
273433d6423SLionel Sambuc #define isemptyn(n)       isemptyp(proc_addr(n))
274433d6423SLionel Sambuc #define isemptyp(p)       ((p)->p_rts_flags == RTS_SLOT_FREE)
275433d6423SLionel Sambuc #define iskernelp(p)	  ((p) < BEG_USER_ADDR)
276433d6423SLionel Sambuc #define iskerneln(n)	  ((n) < 0)
277433d6423SLionel Sambuc #define isuserp(p)        isusern((p) >= BEG_USER_ADDR)
278433d6423SLionel Sambuc #define isusern(n)        ((n) >= 0)
279433d6423SLionel Sambuc #define isrootsysn(n)	  ((n) == ROOT_SYS_PROC_NR)
280433d6423SLionel Sambuc 
281433d6423SLionel Sambuc #ifndef __ASSEMBLY__
282433d6423SLionel Sambuc 
283433d6423SLionel Sambuc EXTERN struct proc proc[NR_TASKS + NR_PROCS];	/* process table */
284433d6423SLionel Sambuc 
285433d6423SLionel Sambuc int mini_send(struct proc *caller_ptr, endpoint_t dst_e, message *m_ptr,
286433d6423SLionel Sambuc 	int flags);
287433d6423SLionel Sambuc 
288433d6423SLionel Sambuc #endif /* __ASSEMBLY__ */
289433d6423SLionel Sambuc 
290433d6423SLionel Sambuc #endif /* PROC_H */
291