|
|
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/boolean.h>
38: #include <mach/thread_info.h>
39: #include <mach/thread_status.h>
40: #include <mach/machine/vm_types.h>
41: #include <mach/message.h>
42: #include <mach/port.h>
43: #include <mach/vm_prot.h>
44: #include <kern/ast.h>
45: #include <kern/cpu_number.h>
1.1.1.3 root 46: #include <kern/mach_clock.h>
1.1 root 47: #include <kern/queue.h>
48: #include <kern/pc_sample.h>
49: #include <kern/processor.h>
50: #include <kern/sched_prim.h> /* event_t, continuation_t */
51: #include <kern/timer.h>
52: #include <kern/lock.h>
53: #include <kern/sched.h>
54: #include <kern/task.h> /* for current_space(), current_map() */
55: #include <machine/thread.h>
56: #include <ipc/ipc_kmsg_queue.h>
57:
58: struct thread {
59: /* Run queues */
60: queue_chain_t links; /* current run queue links */
61: run_queue_t runq; /* run queue p is on SEE BELOW */
62: /*
63: * NOTE: The runq field in the thread structure has an unusual
64: * locking protocol. If its value is RUN_QUEUE_NULL, then it is
65: * locked by the thread_lock, but if its value is something else
66: * (i.e. a run_queue) then it is locked by that run_queue's lock.
67: */
68:
69: /* Task information */
70: task_t task; /* Task to which I belong */
71: queue_chain_t thread_list; /* list of threads in task */
72:
1.1.1.4 root 73: /* Flags */
74: /* The flags are grouped here, but documented at the original
75: position. */
76: union {
77: struct {
78: unsigned state:16;
79: unsigned wake_active:1;
80: unsigned vm_privilege:1;
81: unsigned active:1;
82: };
83: event_t event_key;
84: /* These keys can be used with thread_wakeup and friends. */
85: #define TH_EV_WAKE_ACTIVE(t) ((event_t) (&(t)->event_key + 0))
86: #define TH_EV_STATE(t) ((event_t) (&(t)->event_key + 1))
87: };
88:
1.1 root 89: /* Thread bookkeeping */
90: queue_chain_t pset_threads; /* list of all threads in proc set*/
91:
92: /* Self-preservation */
93: decl_simple_lock_data(,lock)
94: int ref_count; /* number of references to me */
95:
96: /* Hardware state */
97: pcb_t pcb; /* hardware pcb & machine state */
98: vm_offset_t kernel_stack; /* accurate only if the thread is
99: not swapped and not executing */
100: vm_offset_t stack_privilege;/* reserved kernel stack */
101:
102: /* Swapping information */
1.1.1.5 ! root 103: continuation_t swap_func; /* start here after swapin */
1.1 root 104:
105: /* Blocking information */
106: event_t wait_event; /* event we are waiting on */
107: int suspend_count; /* internal use only */
108: kern_return_t wait_result; /* outcome of wait -
109: may be examined by this thread
110: WITHOUT locking */
1.1.1.4 root 111: /* Defined above */
112: /* boolean_t wake_active; someone is waiting for this
1.1 root 113: thread to become suspended */
1.1.1.4 root 114: /* int state; Thread state: */
1.1 root 115: /*
116: * Thread states [bits or'ed]
117: */
118: #define TH_WAIT 0x01 /* thread is queued for waiting */
119: #define TH_SUSP 0x02 /* thread has been asked to stop */
120: #define TH_RUN 0x04 /* thread is running or on runq */
121: #define TH_UNINT 0x08 /* thread is waiting uninteruptibly */
122: #define TH_HALTED 0x10 /* thread is halted at clean point ? */
123:
124: #define TH_IDLE 0x80 /* thread is an idle thread */
125:
126: #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT)
127:
128: #define TH_SWAPPED 0x0100 /* thread has no kernel stack */
129: #define TH_SW_COMING_IN 0x0200 /* thread is waiting for kernel stack */
130:
131: #define TH_SWAP_STATE (TH_SWAPPED | TH_SW_COMING_IN)
132:
133: /* Scheduling information */
134: int priority; /* thread's priority */
135: int max_priority; /* maximum priority */
136: int sched_pri; /* scheduled (computed) priority */
137: #if MACH_FIXPRI
138: int sched_data; /* for use by policy */
139: int policy; /* scheduling policy */
140: #endif /* MACH_FIXPRI */
141: int depress_priority; /* depressed from this priority */
142: unsigned int cpu_usage; /* exp. decaying cpu usage [%cpu] */
143: unsigned int sched_usage; /* load-weighted cpu usage [sched] */
144: unsigned int sched_stamp; /* last time priority was updated */
145:
146: /* VM global variables */
147:
148: vm_offset_t recover; /* page fault recovery (copyin/out) */
1.1.1.4 root 149: /* Defined above */
150: /* boolean_t vm_privilege; Can use reserved memory? */
1.1 root 151:
152: /* User-visible scheduling state */
153: int user_stop_count; /* outstanding stops */
154:
155: /* IPC data structures */
156: struct thread *ith_next, *ith_prev;
157: mach_msg_return_t ith_state;
158: union {
159: mach_msg_size_t msize; /* max size for recvd msg */
160: struct ipc_kmsg *kmsg; /* received message */
161: } data;
162: mach_port_seqno_t ith_seqno; /* seqno of recvd message */
163:
164: /* This queue is used only when destroying messages:
165: it prevents nasty recursion problems when destroying one message
166: causes other messages to be destroyed.
167: This queue should always be empty under normal circumstances.
168: See ipc_kmsg_destroy() for more details. */
169: struct ipc_kmsg_queue ith_messages;
170:
171: decl_simple_lock_data(, ith_lock_data)
172: struct ipc_port *ith_self; /* not a right, doesn't hold ref */
173: struct ipc_port *ith_sself; /* a send right */
174: struct ipc_port *ith_exception; /* a send right */
175:
176: mach_port_t ith_mig_reply; /* reply port for mig */
177: struct ipc_port *ith_rpc_reply; /* reply port for kernel RPCs */
178:
179: /* State saved when thread's stack is discarded */
180: union {
181: struct {
182: mach_msg_header_t *msg;
183: mach_msg_option_t option;
184: mach_msg_size_t rcv_size;
185: mach_msg_timeout_t timeout;
186: mach_port_t notify;
187: struct ipc_object *object;
188: struct ipc_mqueue *mqueue;
189: } receive;
190: struct {
191: struct ipc_port *port;
192: int exc;
193: int code;
194: int subcode;
195: } exception;
196: void *other; /* catch-all for other state */
197: } saved;
198:
199: /* Timing data structures */
200: timer_data_t user_timer; /* user mode timer */
201: timer_data_t system_timer; /* system mode timer */
202: timer_save_data_t user_timer_save; /* saved user timer value */
203: timer_save_data_t system_timer_save; /* saved sys timer val. */
204: unsigned int cpu_delta; /* cpu usage since last update */
205: unsigned int sched_delta; /* weighted cpu usage since update */
206:
1.1.1.2 root 207: /* Creation time stamp */
208: time_value_t creation_time;
209:
1.1 root 210: /* Time-outs */
211: timer_elt_data_t timer; /* timer for thread */
212: timer_elt_data_t depress_timer; /* timer for priority depression */
213:
214: /* Ast/Halt data structures */
1.1.1.4 root 215: /* Defined above */
216: /* boolean_t active; how alive is the thread */
1.1 root 217: int ast; /* ast's needed. See ast.h */
218:
219: /* Processor data structures */
220: processor_set_t processor_set; /* assigned processor set */
221: processor_t bound_processor; /* bound to processor ?*/
222:
223: sample_control_t pc_sample;
224:
225: #if MACH_HOST
226: boolean_t may_assign; /* may assignment change? */
227: boolean_t assign_active; /* someone waiting for may_assign */
228: #endif /* MACH_HOST */
229:
230: #if NCPUS > 1
231: processor_t last_processor; /* processor this last ran on */
232: #endif /* NCPUS > 1 */
233: };
234:
235: /* typedef of thread_t is in kern/kern_types.h */
236: typedef struct thread_shuttle *thread_shuttle_t;
237: #define THREAD_NULL ((thread_t) 0)
238: #define THREAD_SHUTTLE_NULL ((thread_shuttle_t)0)
239:
240: #define ith_msize data.msize
241: #define ith_kmsg data.kmsg
242: #define ith_wait_result wait_result
243:
244: #define ith_msg saved.receive.msg
245: #define ith_option saved.receive.option
246: #define ith_rcv_size saved.receive.rcv_size
247: #define ith_timeout saved.receive.timeout
248: #define ith_notify saved.receive.notify
249: #define ith_object saved.receive.object
250: #define ith_mqueue saved.receive.mqueue
251:
252: #define ith_port saved.exception.port
253: #define ith_exc saved.exception.exc
254: #define ith_exc_code saved.exception.code
255: #define ith_exc_subcode saved.exception.subcode
256:
257: #define ith_other saved.other
258:
259: #ifndef _KERN_KERN_TYPES_H_
260: typedef struct thread *thread_t;
261:
262: #define THREAD_NULL ((thread_t) 0)
263:
264: typedef mach_port_t *thread_array_t;
265: #endif /* _KERN_KERN_TYPES_H_ */
266:
267:
268: extern thread_t active_threads[NCPUS]; /* active threads */
269: extern vm_offset_t active_stacks[NCPUS]; /* active kernel stacks */
270:
271: #ifdef KERNEL
272: /*
273: * User routines
274: */
275:
276: extern kern_return_t thread_create(
277: task_t parent_task,
278: thread_t *child_thread);
279: extern kern_return_t thread_terminate(
280: thread_t thread);
1.1.1.4 root 281: extern kern_return_t thread_terminate_release(
282: thread_t thread,
283: task_t task,
284: mach_port_t thread_name,
285: mach_port_t reply_port,
286: vm_offset_t address,
287: vm_size_t size);
1.1 root 288: extern kern_return_t thread_suspend(
289: thread_t thread);
290: extern kern_return_t thread_resume(
291: thread_t thread);
292: extern kern_return_t thread_abort(
293: thread_t thread);
1.1.1.3 root 294: extern void thread_start(
295: thread_t thread,
296: continuation_t start);
297: extern thread_t kernel_thread(
298: task_t task,
299: continuation_t start,
300: void *arg);
301: extern kern_return_t thread_priority(
302: thread_t thread,
303: int priority,
304: boolean_t set_max);
305: extern void thread_set_own_priority(
306: int priority);
307: extern kern_return_t thread_max_priority(
308: thread_t thread,
309: processor_set_t pset,
310: int max_priority);
311: extern kern_return_t thread_policy(
312: thread_t thread,
313: int policy,
314: int data);
315: extern void consider_thread_collect(
316: void);
317: extern void stack_privilege(
318: thread_t thread);
1.1 root 319: extern kern_return_t thread_get_state(
320: thread_t thread,
321: int flavor,
322: thread_state_t old_state,
323: natural_t *old_state_count);
324: extern kern_return_t thread_set_state(
325: thread_t thread,
326: int flavor,
327: thread_state_t new_state,
328: natural_t new_state_count);
329: extern kern_return_t thread_get_special_port(
330: thread_t thread,
331: int which,
332: struct ipc_port **portp);
333: extern kern_return_t thread_set_special_port(
334: thread_t thread,
335: int which,
336: struct ipc_port *port);
337: extern kern_return_t thread_info(
338: thread_t thread,
339: int flavor,
340: thread_info_t thread_info_out,
341: natural_t *thread_info_count);
342: extern kern_return_t thread_assign(
343: thread_t thread,
344: processor_set_t new_pset);
345: extern kern_return_t thread_assign_default(
346: thread_t thread);
1.1.1.3 root 347: extern void stack_collect(void);
1.1 root 348: #endif
349:
350: /*
351: * Kernel-only routines
352: */
353:
354: extern void thread_init(void);
355: extern void thread_reference(thread_t);
356: extern void thread_deallocate(thread_t);
357: extern void thread_hold(thread_t);
358: extern kern_return_t thread_dowait(
359: thread_t thread,
360: boolean_t must_halt);
361: extern void thread_release(thread_t);
362: extern kern_return_t thread_halt(
363: thread_t thread,
364: boolean_t must_halt);
1.1.1.5 ! root 365: extern void thread_halt_self(continuation_t);
1.1 root 366: extern void thread_force_terminate(thread_t);
367: extern thread_t kernel_thread(
368: task_t task,
369: void (*start)(void),
370: void * arg);
371:
1.1.1.4 root 372: extern void reaper_thread(void) __attribute__((noreturn));
1.1 root 373:
374: #if MACH_HOST
375: extern void thread_freeze(
376: thread_t thread);
377: extern void thread_doassign(
378: thread_t thread,
379: processor_set_t new_pset,
380: boolean_t release_freeze);
381: extern void thread_unfreeze(
382: thread_t thread);
383: #endif /* MACH_HOST */
384:
385: /*
386: * Macro-defined routines
387: */
388:
389: #define thread_pcb(th) ((th)->pcb)
390:
391: #define thread_lock(th) simple_lock(&(th)->lock)
392: #define thread_unlock(th) simple_unlock(&(th)->lock)
393:
394: #define thread_should_halt(thread) \
395: ((thread)->ast & (AST_HALT|AST_TERMINATE))
396:
397: /*
398: * Machine specific implementations of the current thread macro
399: * designate this by defining CURRENT_THREAD.
400: */
401: #ifndef CURRENT_THREAD
402: #define current_thread() (active_threads[cpu_number()])
403: #endif /* CURRENT_THREAD */
404:
405: #define current_stack() (active_stacks[cpu_number()])
406:
407: #define current_task() (current_thread()->task)
408: #define current_space() (current_task()->itk_space)
409: #define current_map() (current_task()->map)
410:
1.1.1.4 root 411: #if MACH_DEBUG
412: void stack_init(vm_offset_t stack);
413: void stack_finalize(vm_offset_t stack);
414: #endif /* MACH_DEBUG */
415:
1.1 root 416: #endif /* _KERN_THREAD_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.