|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1993-1987 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * File: thread.h
28: * Author: Avadis Tevanian, Jr.
29: *
30: * This file contains the structure definitions for threads.
31: *
32: */
33:
34: #ifndef _KERN_THREAD_H_
35: #define _KERN_THREAD_H_
36:
37: #include <mach_ipc_compat.h>
38: #include <hw_footprint.h>
39: #include <mach_fixpri.h>
40: #include <mach_host.h>
41: #include <net_atm.h>
42:
43: #include <mach/boolean.h>
44: #include <mach/thread_info.h>
45: #include <mach/thread_status.h>
46: #include <mach/machine/vm_types.h>
47: #include <mach/message.h>
48: #include <mach/port.h>
49: #include <mach/vm_prot.h>
50: #include <kern/ast.h>
51: #include <kern/cpu_number.h>
52: #include <kern/queue.h>
53: #include <kern/pc_sample.h>
54: #include <kern/processor.h>
55: #include <kern/sched_prim.h> /* event_t, continuation_t */
56: #include <kern/time_out.h>
57: #include <kern/timer.h>
58: #include <kern/lock.h>
59: #include <kern/sched.h>
60: #include <kern/task.h> /* for current_space(), current_map() */
61: #include <machine/thread.h>
62: #include <ipc/ipc_kmsg_queue.h>
63:
64: struct thread {
65: /* Run queues */
66: queue_chain_t links; /* current run queue links */
67: run_queue_t runq; /* run queue p is on SEE BELOW */
68: /*
69: * NOTE: The runq field in the thread structure has an unusual
70: * locking protocol. If its value is RUN_QUEUE_NULL, then it is
71: * locked by the thread_lock, but if its value is something else
72: * (i.e. a run_queue) then it is locked by that run_queue's lock.
73: */
74:
75: /* Task information */
76: task_t task; /* Task to which I belong */
77: queue_chain_t thread_list; /* list of threads in task */
78:
79: /* Thread bookkeeping */
80: queue_chain_t pset_threads; /* list of all threads in proc set*/
81:
82: /* Self-preservation */
83: decl_simple_lock_data(,lock)
84: int ref_count; /* number of references to me */
85:
86: /* Hardware state */
87: pcb_t pcb; /* hardware pcb & machine state */
88: vm_offset_t kernel_stack; /* accurate only if the thread is
89: not swapped and not executing */
90: vm_offset_t stack_privilege;/* reserved kernel stack */
91:
92: /* Swapping information */
93: void (*swap_func)(); /* start here after swapin */
94:
95: /* Blocking information */
96: event_t wait_event; /* event we are waiting on */
97: int suspend_count; /* internal use only */
98: kern_return_t wait_result; /* outcome of wait -
99: may be examined by this thread
100: WITHOUT locking */
101: boolean_t wake_active; /* someone is waiting for this
102: thread to become suspended */
103: int state; /* Thread state: */
104: /*
105: * Thread states [bits or'ed]
106: */
107: #define TH_WAIT 0x01 /* thread is queued for waiting */
108: #define TH_SUSP 0x02 /* thread has been asked to stop */
109: #define TH_RUN 0x04 /* thread is running or on runq */
110: #define TH_UNINT 0x08 /* thread is waiting uninteruptibly */
111: #define TH_HALTED 0x10 /* thread is halted at clean point ? */
112:
113: #define TH_IDLE 0x80 /* thread is an idle thread */
114:
115: #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT)
116:
117: #define TH_SWAPPED 0x0100 /* thread has no kernel stack */
118: #define TH_SW_COMING_IN 0x0200 /* thread is waiting for kernel stack */
119:
120: #define TH_SWAP_STATE (TH_SWAPPED | TH_SW_COMING_IN)
121:
122: /* Scheduling information */
123: int priority; /* thread's priority */
124: int max_priority; /* maximum priority */
125: int sched_pri; /* scheduled (computed) priority */
126: #if MACH_FIXPRI
127: int sched_data; /* for use by policy */
128: int policy; /* scheduling policy */
129: #endif /* MACH_FIXPRI */
130: int depress_priority; /* depressed from this priority */
131: unsigned int cpu_usage; /* exp. decaying cpu usage [%cpu] */
132: unsigned int sched_usage; /* load-weighted cpu usage [sched] */
133: unsigned int sched_stamp; /* last time priority was updated */
134:
135: /* VM global variables */
136:
137: vm_offset_t recover; /* page fault recovery (copyin/out) */
138: boolean_t vm_privilege; /* Can use reserved memory? */
139:
140: /* User-visible scheduling state */
141: int user_stop_count; /* outstanding stops */
142:
143: /* IPC data structures */
144: struct thread *ith_next, *ith_prev;
145: mach_msg_return_t ith_state;
146: union {
147: mach_msg_size_t msize; /* max size for recvd msg */
148: struct ipc_kmsg *kmsg; /* received message */
149: } data;
150: mach_port_seqno_t ith_seqno; /* seqno of recvd message */
151:
152: /* This queue is used only when destroying messages:
153: it prevents nasty recursion problems when destroying one message
154: causes other messages to be destroyed.
155: This queue should always be empty under normal circumstances.
156: See ipc_kmsg_destroy() for more details. */
157: struct ipc_kmsg_queue ith_messages;
158:
159: decl_simple_lock_data(, ith_lock_data)
160: struct ipc_port *ith_self; /* not a right, doesn't hold ref */
161: struct ipc_port *ith_sself; /* a send right */
162: struct ipc_port *ith_exception; /* a send right */
163: #if MACH_IPC_COMPAT
164: struct ipc_port *ith_reply; /* a send right */
165: #endif /* MACH_IPC_COMPAT */
166:
167: mach_port_t ith_mig_reply; /* reply port for mig */
168: struct ipc_port *ith_rpc_reply; /* reply port for kernel RPCs */
169:
170: /* State saved when thread's stack is discarded */
171: union {
172: struct {
173: mach_msg_header_t *msg;
174: mach_msg_option_t option;
175: mach_msg_size_t rcv_size;
176: mach_msg_timeout_t timeout;
177: mach_port_t notify;
178: struct ipc_object *object;
179: struct ipc_mqueue *mqueue;
180: } receive;
181: struct {
182: struct ipc_port *port;
183: int exc;
184: int code;
185: int subcode;
186: } exception;
187: void *other; /* catch-all for other state */
188: } saved;
189:
190: /* Timing data structures */
191: timer_data_t user_timer; /* user mode timer */
192: timer_data_t system_timer; /* system mode timer */
193: timer_save_data_t user_timer_save; /* saved user timer value */
194: timer_save_data_t system_timer_save; /* saved sys timer val. */
195: unsigned int cpu_delta; /* cpu usage since last update */
196: unsigned int sched_delta; /* weighted cpu usage since update */
197:
198: /* Creation time stamp */
199: time_value_t creation_time;
200:
201: /* Time-outs */
202: timer_elt_data_t timer; /* timer for thread */
203: timer_elt_data_t depress_timer; /* timer for priority depression */
204:
205: /* Ast/Halt data structures */
206: boolean_t active; /* how alive is the thread */
207: int ast; /* ast's needed. See ast.h */
208:
209: /* Processor data structures */
210: processor_set_t processor_set; /* assigned processor set */
211: processor_t bound_processor; /* bound to processor ?*/
212:
213: sample_control_t pc_sample;
214:
215: #if MACH_HOST
216: boolean_t may_assign; /* may assignment change? */
217: boolean_t assign_active; /* someone waiting for may_assign */
218: #endif /* MACH_HOST */
219:
220: #if NCPUS > 1
221: processor_t last_processor; /* processor this last ran on */
222: #endif /* NCPUS > 1 */
223:
224: #if NET_ATM
225: nw_ep_owned_t nw_ep_waited;
226: #endif /* NET_ATM */
227: };
228:
229: /* typedef of thread_t is in kern/kern_types.h */
230: typedef struct thread_shuttle *thread_shuttle_t;
231: #define THREAD_NULL ((thread_t) 0)
232: #define THREAD_SHUTTLE_NULL ((thread_shuttle_t)0)
233:
234: #define ith_msize data.msize
235: #define ith_kmsg data.kmsg
236: #define ith_wait_result wait_result
237:
238: #define ith_msg saved.receive.msg
239: #define ith_option saved.receive.option
240: #define ith_rcv_size saved.receive.rcv_size
241: #define ith_timeout saved.receive.timeout
242: #define ith_notify saved.receive.notify
243: #define ith_object saved.receive.object
244: #define ith_mqueue saved.receive.mqueue
245:
246: #define ith_port saved.exception.port
247: #define ith_exc saved.exception.exc
248: #define ith_exc_code saved.exception.code
249: #define ith_exc_subcode saved.exception.subcode
250:
251: #define ith_other saved.other
252:
253: #ifndef _KERN_KERN_TYPES_H_
254: typedef struct thread *thread_t;
255:
256: #define THREAD_NULL ((thread_t) 0)
257:
258: typedef mach_port_t *thread_array_t;
259: #endif /* _KERN_KERN_TYPES_H_ */
260:
261:
262: extern thread_t active_threads[NCPUS]; /* active threads */
263: extern vm_offset_t active_stacks[NCPUS]; /* active kernel stacks */
264:
265: #ifdef KERNEL
266: /*
267: * User routines
268: */
269:
270: extern kern_return_t thread_create(
271: task_t parent_task,
272: thread_t *child_thread);
273: extern kern_return_t thread_terminate(
274: thread_t thread);
275: extern kern_return_t thread_suspend(
276: thread_t thread);
277: extern kern_return_t thread_resume(
278: thread_t thread);
279: extern kern_return_t thread_abort(
280: thread_t thread);
281: extern kern_return_t thread_get_state(
282: thread_t thread,
283: int flavor,
284: thread_state_t old_state,
285: natural_t *old_state_count);
286: extern kern_return_t thread_set_state(
287: thread_t thread,
288: int flavor,
289: thread_state_t new_state,
290: natural_t new_state_count);
291: extern kern_return_t thread_get_special_port(
292: thread_t thread,
293: int which,
294: struct ipc_port **portp);
295: extern kern_return_t thread_set_special_port(
296: thread_t thread,
297: int which,
298: struct ipc_port *port);
299: extern kern_return_t thread_info(
300: thread_t thread,
301: int flavor,
302: thread_info_t thread_info_out,
303: natural_t *thread_info_count);
304: extern kern_return_t thread_assign(
305: thread_t thread,
306: processor_set_t new_pset);
307: extern kern_return_t thread_assign_default(
308: thread_t thread);
309: #endif
310:
311: /*
312: * Kernel-only routines
313: */
314:
315: extern void thread_init(void);
316: extern void thread_reference(thread_t);
317: extern void thread_deallocate(thread_t);
318: extern void thread_hold(thread_t);
319: extern kern_return_t thread_dowait(
320: thread_t thread,
321: boolean_t must_halt);
322: extern void thread_release(thread_t);
323: extern kern_return_t thread_halt(
324: thread_t thread,
325: boolean_t must_halt);
326: extern void thread_halt_self(void);
327: extern void thread_force_terminate(thread_t);
328: extern void thread_set_own_priority(
329: int priority);
330: extern thread_t kernel_thread(
331: task_t task,
332: void (*start)(void),
333: void * arg);
334:
335: extern void reaper_thread(void);
336:
337: #if MACH_HOST
338: extern void thread_freeze(
339: thread_t thread);
340: extern void thread_doassign(
341: thread_t thread,
342: processor_set_t new_pset,
343: boolean_t release_freeze);
344: extern void thread_unfreeze(
345: thread_t thread);
346: #endif /* MACH_HOST */
347:
348: /*
349: * Macro-defined routines
350: */
351:
352: #define thread_pcb(th) ((th)->pcb)
353:
354: #define thread_lock(th) simple_lock(&(th)->lock)
355: #define thread_unlock(th) simple_unlock(&(th)->lock)
356:
357: #define thread_should_halt(thread) \
358: ((thread)->ast & (AST_HALT|AST_TERMINATE))
359:
360: /*
361: * Machine specific implementations of the current thread macro
362: * designate this by defining CURRENT_THREAD.
363: */
364: #ifndef CURRENT_THREAD
365: #define current_thread() (active_threads[cpu_number()])
366: #endif /* CURRENT_THREAD */
367:
368: #define current_stack() (active_stacks[cpu_number()])
369:
370: #define current_task() (current_thread()->task)
371: #define current_space() (current_task()->itk_space)
372: #define current_map() (current_task()->map)
373:
374: #endif /* _KERN_THREAD_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.