]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
91447636 | 2 | * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. |
1c79356b A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
37839358 A |
6 | * The contents of this file constitute Original Code as defined in and |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
43866e37 | 11 | * |
37839358 A |
12 | * This Original Code and all software distributed under the License are |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
1c79356b A |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
37839358 A |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
1c79356b A |
19 | * |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | /* | |
23 | * @OSF_FREE_COPYRIGHT@ | |
24 | */ | |
25 | /* | |
26 | * Mach Operating System | |
27 | * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University | |
28 | * All Rights Reserved. | |
29 | * | |
30 | * Permission to use, copy, modify and distribute this software and its | |
31 | * documentation is hereby granted, provided that both the copyright | |
32 | * notice and this permission notice appear in all copies of the | |
33 | * software, derivative works or modified versions, and any portions | |
34 | * thereof, and that both notices appear in supporting documentation. | |
35 | * | |
36 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" | |
37 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR | |
38 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | |
39 | * | |
40 | * Carnegie Mellon requests users of this software to return to | |
41 | * | |
42 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | |
43 | * School of Computer Science | |
44 | * Carnegie Mellon University | |
45 | * Pittsburgh PA 15213-3890 | |
46 | * | |
47 | * any improvements or extensions that they make and grant Carnegie Mellon | |
48 | * the rights to redistribute these changes. | |
49 | */ | |
50 | /* | |
51 | */ | |
52 | /* | |
53 | * File: thread.h | |
54 | * Author: Avadis Tevanian, Jr. | |
55 | * | |
56 | * This file contains the structure definitions for threads. | |
57 | * | |
58 | */ | |
59 | /* | |
60 | * Copyright (c) 1993 The University of Utah and | |
61 | * the Computer Systems Laboratory (CSL). All rights reserved. | |
62 | * | |
63 | * Permission to use, copy, modify and distribute this software and its | |
64 | * documentation is hereby granted, provided that both the copyright | |
65 | * notice and this permission notice appear in all copies of the | |
66 | * software, derivative works or modified versions, and any portions | |
67 | * thereof, and that both notices appear in supporting documentation. | |
68 | * | |
69 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS | |
70 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF | |
71 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | |
72 | * | |
73 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any | |
74 | * improvements that they make and grant CSL redistribution rights. | |
75 | * | |
76 | */ | |
77 | ||
78 | #ifndef _KERN_THREAD_H_ | |
79 | #define _KERN_THREAD_H_ | |
80 | ||
81 | #include <mach/kern_return.h> | |
82 | #include <mach/mach_types.h> | |
83 | #include <mach/message.h> | |
84 | #include <mach/boolean.h> | |
55e303ae | 85 | #include <mach/vm_param.h> |
1c79356b A |
86 | #include <mach/thread_info.h> |
87 | #include <mach/thread_status.h> | |
55e303ae | 88 | #include <mach/exception_types.h> |
9bccf70c | 89 | |
1c79356b A |
90 | #include <kern/kern_types.h> |
91 | ||
91447636 | 92 | #include <sys/cdefs.h> |
1c79356b | 93 | |
9bccf70c | 94 | #ifdef MACH_KERNEL_PRIVATE |
1c79356b | 95 | |
55e303ae A |
96 | #include <cputypes.h> |
97 | ||
98 | #include <mach_assert.h> | |
1c79356b A |
99 | #include <mach_host.h> |
100 | #include <mach_prof.h> | |
1c79356b A |
101 | #include <mach_ldebug.h> |
102 | ||
91447636 A |
103 | #include <ipc/ipc_types.h> |
104 | ||
1c79356b | 105 | #include <mach/port.h> |
1c79356b A |
106 | #include <kern/cpu_number.h> |
107 | #include <kern/queue.h> | |
1c79356b A |
108 | #include <kern/timer.h> |
109 | #include <kern/lock.h> | |
91447636 | 110 | #include <kern/locks.h> |
1c79356b A |
111 | #include <kern/sched.h> |
112 | #include <kern/sched_prim.h> | |
1c79356b A |
113 | #include <kern/thread_call.h> |
114 | #include <kern/timer_call.h> | |
115 | #include <kern/task.h> | |
55e303ae | 116 | #include <kern/exception.h> |
91447636 | 117 | |
1c79356b | 118 | #include <ipc/ipc_kmsg.h> |
55e303ae | 119 | |
91447636 | 120 | #include <machine/cpu_data.h> |
1c79356b A |
121 | #include <machine/thread.h> |
122 | ||
55e303ae | 123 | struct thread { |
1c79356b | 124 | /* |
9bccf70c A |
125 | * NOTE: The runq field in the thread structure has an unusual |
126 | * locking protocol. If its value is RUN_QUEUE_NULL, then it is | |
127 | * locked by the thread_lock, but if its value is something else | |
128 | * (i.e. a run_queue) then it is locked by that run_queue's lock. | |
129 | * | |
91447636 A |
130 | * When the thread is on a wait queue, these first three fields |
131 | * are treated as an unofficial union with a wait_queue_element. | |
132 | * If you change these, you must change that definition as well | |
133 | * (kern/wait_queue.h). | |
1c79356b | 134 | */ |
9bccf70c A |
135 | /* Items examined often, modified infrequently */ |
136 | queue_chain_t links; /* run/wait queue links */ | |
137 | run_queue_t runq; /* run queue thread is on SEE BELOW */ | |
138 | wait_queue_t wait_queue; /* wait queue we are currently on */ | |
139 | event64_t wait_event; /* wait queue event */ | |
91447636 A |
140 | integer_t options; /* options set by thread itself */ |
141 | #define TH_OPT_INTMASK 0x03 /* interrupt / abort level */ | |
142 | #define TH_OPT_VMPRIV 0x04 /* may allocate reserved memory */ | |
143 | #define TH_OPT_DELAYIDLE 0x08 /* performing delayed idle */ | |
144 | #define TH_OPT_CALLOUT 0x10 /* executing as callout */ | |
1c79356b | 145 | |
9bccf70c | 146 | /* Data updated during assert_wait/thread_wakeup */ |
55e303ae | 147 | decl_simple_lock_data(,sched_lock) /* scheduling lock (thread_lock()) */ |
0b4e3aa0 | 148 | decl_simple_lock_data(,wake_lock) /* covers wake_active (wake_lock())*/ |
9bccf70c A |
149 | boolean_t wake_active; /* Someone is waiting for this */ |
150 | int at_safe_point; /* thread_abort_safely allowed */ | |
151 | ast_t reason; /* why we blocked */ | |
152 | wait_result_t wait_result; /* outcome of wait - | |
0b4e3aa0 A |
153 | * may be examined by this thread |
154 | * WITHOUT locking */ | |
91447636 A |
155 | thread_continue_t continuation; /* continue here next dispatch */ |
156 | void *parameter; /* continuation parameter */ | |
0b4e3aa0 | 157 | |
9bccf70c A |
158 | /* Data updated/used in thread_invoke */ |
159 | struct funnel_lock *funnel_lock; /* Non-reentrancy funnel */ | |
160 | int funnel_state; | |
161 | #define TH_FN_OWNED 0x1 /* we own the funnel */ | |
162 | #define TH_FN_REFUNNEL 0x2 /* re-acquire funnel on dispatch */ | |
0b4e3aa0 | 163 | |
9bccf70c | 164 | vm_offset_t kernel_stack; /* current kernel stack */ |
55e303ae | 165 | vm_offset_t reserved_stack; /* reserved kernel stack */ |
0b4e3aa0 A |
166 | |
167 | /* Thread state: */ | |
9bccf70c | 168 | int state; |
1c79356b A |
169 | /* |
170 | * Thread states [bits or'ed] | |
171 | */ | |
55e303ae A |
172 | #define TH_WAIT 0x01 /* queued for waiting */ |
173 | #define TH_SUSP 0x02 /* stopped or requested to stop */ | |
174 | #define TH_RUN 0x04 /* running or on runq */ | |
175 | #define TH_UNINT 0x08 /* waiting uninteruptibly */ | |
176 | #define TH_TERMINATE 0x10 /* halted at termination */ | |
1c79356b | 177 | |
55e303ae A |
178 | #define TH_ABORT 0x20 /* abort interruptible waits */ |
179 | #define TH_ABORT_SAFELY 0x40 /* ... but only those at safe point */ | |
1c79356b | 180 | |
55e303ae | 181 | #define TH_IDLE 0x80 /* processor idle thread */ |
1c79356b A |
182 | |
183 | #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT) | |
184 | ||
9bccf70c A |
185 | /* Scheduling information */ |
186 | integer_t sched_mode; /* scheduling mode bits */ | |
187 | #define TH_MODE_REALTIME 0x0001 /* time constraints supplied */ | |
188 | #define TH_MODE_TIMESHARE 0x0002 /* use timesharing algorithm */ | |
189 | #define TH_MODE_PREEMPT 0x0004 /* can preempt kernel contexts */ | |
190 | #define TH_MODE_FAILSAFE 0x0008 /* fail-safe has tripped */ | |
191 | #define TH_MODE_PROMOTED 0x0010 /* sched pri has been promoted */ | |
91447636 A |
192 | #define TH_MODE_DEPRESS 0x0020 /* normal depress yield */ |
193 | #define TH_MODE_POLLDEPRESS 0x0040 /* polled depress yield */ | |
9bccf70c A |
194 | #define TH_MODE_ISDEPRESSED (TH_MODE_DEPRESS | TH_MODE_POLLDEPRESS) |
195 | ||
196 | integer_t sched_pri; /* scheduled (current) priority */ | |
197 | integer_t priority; /* base priority */ | |
198 | integer_t max_priority; /* max base priority */ | |
199 | integer_t task_priority; /* copy of task base priority */ | |
200 | ||
201 | integer_t promotions; /* level of promotion */ | |
202 | integer_t pending_promoter_index; | |
203 | void *pending_promoter[2]; | |
1c79356b | 204 | |
9bccf70c | 205 | integer_t importance; /* task-relative importance */ |
1c79356b | 206 | |
55e303ae | 207 | /* real-time parameters */ |
9bccf70c | 208 | struct { /* see mach/thread_policy.h */ |
0b4e3aa0 A |
209 | uint32_t period; |
210 | uint32_t computation; | |
211 | uint32_t constraint; | |
1c79356b | 212 | boolean_t preemptible; |
55e303ae A |
213 | |
214 | uint64_t deadline; | |
1c79356b A |
215 | } realtime; |
216 | ||
0b4e3aa0 A |
217 | uint32_t current_quantum; /* duration of current quantum */ |
218 | ||
9bccf70c A |
219 | /* Data used during setrun/dispatch */ |
220 | timer_data_t system_timer; /* system mode timer */ | |
221 | processor_set_t processor_set; /* assigned processor set */ | |
222 | processor_t bound_processor; /* bound to a processor? */ | |
223 | processor_t last_processor; /* processor last dispatched on */ | |
224 | uint64_t last_switch; /* time of last context switch */ | |
225 | ||
0b4e3aa0 | 226 | /* Fail-safe computation since last unblock or qualifying yield */ |
9bccf70c | 227 | uint64_t computation_metered; |
0b4e3aa0 | 228 | uint64_t computation_epoch; |
9bccf70c A |
229 | integer_t safe_mode; /* saved mode during fail-safe */ |
230 | natural_t safe_release; /* when to release fail-safe */ | |
1c79356b | 231 | |
55e303ae | 232 | /* Statistics and timesharing calculations */ |
91447636 A |
233 | natural_t sched_stamp; /* last scheduler tick */ |
234 | natural_t sched_usage; /* timesharing cpu usage [sched] */ | |
235 | natural_t pri_shift; /* usage -> priority from pset */ | |
236 | natural_t cpu_usage; /* instrumented cpu usage [%cpu] */ | |
237 | natural_t cpu_delta; /* accumulated cpu_usage delta */ | |
1c79356b | 238 | |
9bccf70c | 239 | /* Timing data structures */ |
91447636 A |
240 | timer_data_t user_timer; /* user mode timer */ |
241 | uint64_t system_timer_save; /* saved system timer value */ | |
242 | uint64_t user_timer_save; /* saved user timer value */ | |
1c79356b | 243 | |
9bccf70c | 244 | /* Timed wait expiration */ |
91447636 A |
245 | timer_call_data_t wait_timer; |
246 | integer_t wait_timer_active; | |
247 | boolean_t wait_timer_is_set; | |
1c79356b | 248 | |
9bccf70c | 249 | /* Priority depression expiration */ |
91447636 A |
250 | timer_call_data_t depress_timer; |
251 | integer_t depress_timer_active; | |
1c79356b A |
252 | |
253 | /* Various bits of stashed state */ | |
254 | union { | |
255 | struct { | |
0b4e3aa0 A |
256 | mach_msg_return_t state; /* receive state */ |
257 | ipc_object_t object; /* object received on */ | |
91447636 | 258 | mach_vm_address_t msg_addr; /* receive buffer pointer */ |
0b4e3aa0 A |
259 | mach_msg_size_t msize; /* max size for recvd msg */ |
260 | mach_msg_option_t option; /* options for receive */ | |
261 | mach_msg_size_t slist_size; /* scatter list size */ | |
262 | struct ipc_kmsg *kmsg; /* received message */ | |
263 | mach_port_seqno_t seqno; /* seqno of recvd message */ | |
9bccf70c A |
264 | mach_msg_continue_t continuation; |
265 | } receive; | |
1c79356b | 266 | struct { |
0b4e3aa0 A |
267 | struct semaphore *waitsemaphore; /* semaphore ref */ |
268 | struct semaphore *signalsemaphore; /* semaphore ref */ | |
269 | int options; /* semaphore options */ | |
270 | kern_return_t result; /* primary result */ | |
9bccf70c A |
271 | mach_msg_continue_t continuation; |
272 | } sema; | |
1c79356b | 273 | struct { |
9bccf70c A |
274 | int option; /* switch option */ |
275 | } swtch; | |
276 | int misc; /* catch-all for other state */ | |
277 | } saved; | |
1c79356b | 278 | |
9bccf70c A |
279 | /* IPC data structures */ |
280 | struct ipc_kmsg_queue ith_messages; | |
9bccf70c | 281 | mach_port_t ith_rpc_reply; /* reply port for kernel RPCs */ |
1c79356b A |
282 | |
283 | /* Ast/Halt data structures */ | |
9bccf70c A |
284 | vm_offset_t recover; /* page fault recover(copyin/out) */ |
285 | int ref_count; /* number of references to me */ | |
1c79356b | 286 | |
9bccf70c | 287 | /* Processor set info */ |
55e303ae | 288 | queue_chain_t pset_threads; /* list of all threads in pset */ |
1c79356b | 289 | #if MACH_HOST |
9bccf70c A |
290 | boolean_t may_assign; /* may assignment change? */ |
291 | boolean_t assign_active; /* waiting for may_assign */ | |
1c79356b A |
292 | #endif /* MACH_HOST */ |
293 | ||
55e303ae A |
294 | /* Activation */ |
295 | queue_chain_t task_threads; | |
296 | ||
297 | /*** Machine-dependent state ***/ | |
91447636 | 298 | struct machine_thread machine; |
55e303ae A |
299 | |
300 | /* Task membership */ | |
301 | struct task *task; | |
302 | vm_map_t map; | |
303 | ||
91447636 | 304 | decl_mutex_data(,mutex) |
55e303ae A |
305 | |
306 | /* Kernel holds on this thread */ | |
307 | int suspend_count; | |
308 | ||
309 | /* User level suspensions */ | |
310 | int user_stop_count; | |
311 | ||
312 | /* Pending thread ast(s) */ | |
313 | ast_t ast; | |
314 | ||
91447636 | 315 | /* Miscellaneous bits guarded by mutex */ |
55e303ae A |
316 | uint32_t |
317 | /* Indicates that the thread has not been terminated */ | |
318 | active:1, | |
319 | ||
320 | /* Indicates that the thread has been started after creation */ | |
321 | started:1, | |
322 | :0; | |
323 | ||
324 | /* Return Handers */ | |
325 | struct ReturnHandler { | |
326 | struct ReturnHandler *next; | |
327 | void (*handler)( | |
328 | struct ReturnHandler *rh, | |
91447636 | 329 | struct thread *thread); |
55e303ae A |
330 | } *handlers, special_handler; |
331 | ||
332 | /* Ports associated with this thread */ | |
333 | struct ipc_port *ith_self; /* not a right, doesn't hold ref */ | |
334 | struct ipc_port *ith_sself; /* a send right */ | |
335 | struct exception_action exc_actions[EXC_TYPES_COUNT]; | |
336 | ||
337 | /* Owned ulocks (a lock set element) */ | |
338 | queue_head_t held_ulocks; | |
339 | ||
340 | #if MACH_PROF | |
341 | /* Profiling */ | |
342 | boolean_t profiled; | |
343 | boolean_t profiled_own; | |
344 | struct prof_data *profil_buffer; | |
345 | #endif /* MACH_PROF */ | |
346 | ||
347 | #ifdef MACH_BSD | |
348 | void *uthread; | |
349 | #endif | |
0b4e3aa0 | 350 | }; |
1c79356b | 351 | |
1c79356b A |
352 | #define ith_state saved.receive.state |
353 | #define ith_object saved.receive.object | |
91447636 | 354 | #define ith_msg_addr saved.receive.msg_addr |
1c79356b A |
355 | #define ith_msize saved.receive.msize |
356 | #define ith_option saved.receive.option | |
357 | #define ith_scatter_list_size saved.receive.slist_size | |
358 | #define ith_continuation saved.receive.continuation | |
359 | #define ith_kmsg saved.receive.kmsg | |
360 | #define ith_seqno saved.receive.seqno | |
361 | ||
362 | #define sth_waitsemaphore saved.sema.waitsemaphore | |
363 | #define sth_signalsemaphore saved.sema.signalsemaphore | |
364 | #define sth_options saved.sema.options | |
365 | #define sth_result saved.sema.result | |
366 | #define sth_continuation saved.sema.continuation | |
367 | ||
55e303ae | 368 | extern void thread_bootstrap(void); |
1c79356b | 369 | |
55e303ae | 370 | extern void thread_init(void); |
9bccf70c | 371 | |
91447636 | 372 | extern void thread_daemon_init(void); |
1c79356b | 373 | |
91447636 A |
374 | #define thread_reference_internal(thread) \ |
375 | hw_atomic_add(&(thread)->ref_count, 1) | |
376 | ||
377 | #define thread_deallocate_internal(thread) \ | |
378 | hw_atomic_sub(&(thread)->ref_count, 1) | |
379 | ||
380 | #define thread_reference(thread) \ | |
381 | MACRO_BEGIN \ | |
382 | if ((thread) != THREAD_NULL) \ | |
383 | thread_reference_internal(thread); \ | |
384 | MACRO_END | |
1c79356b | 385 | |
55e303ae A |
386 | extern void thread_deallocate( |
387 | thread_t thread); | |
1c79356b | 388 | |
55e303ae | 389 | extern void thread_terminate_self(void); |
1c79356b | 390 | |
91447636 A |
391 | extern kern_return_t thread_terminate_internal( |
392 | thread_t thread); | |
393 | ||
394 | extern void thread_terminate_enqueue( | |
395 | thread_t thread); | |
396 | ||
397 | extern void thread_stack_enqueue( | |
398 | thread_t thread); | |
399 | ||
55e303ae | 400 | extern void thread_hold( |
91447636 | 401 | thread_t thread); |
1c79356b | 402 | |
55e303ae | 403 | extern void thread_release( |
91447636 | 404 | thread_t thread); |
1c79356b | 405 | |
91447636 | 406 | #define thread_lock_init(th) simple_lock_init(&(th)->sched_lock, 0) |
55e303ae A |
407 | #define thread_lock(th) simple_lock(&(th)->sched_lock) |
408 | #define thread_unlock(th) simple_unlock(&(th)->sched_lock) | |
409 | #define thread_lock_try(th) simple_lock_try(&(th)->sched_lock) | |
1c79356b | 410 | |
91447636 | 411 | #define thread_should_halt_fast(thread) (!(thread)->active) |
1c79356b | 412 | |
91447636 A |
413 | #define wake_lock_init(th) simple_lock_init(&(th)->wake_lock, 0) |
414 | #define wake_lock(th) simple_lock(&(th)->wake_lock) | |
415 | #define wake_unlock(th) simple_unlock(&(th)->wake_lock) | |
9bccf70c | 416 | #define wake_lock_try(th) simple_lock_try(&(th)->wake_lock) |
1c79356b | 417 | |
91447636 A |
418 | extern void stack_alloc( |
419 | thread_t thread); | |
1c79356b | 420 | |
55e303ae A |
421 | extern void stack_free( |
422 | thread_t thread); | |
1c79356b | 423 | |
55e303ae A |
424 | extern void stack_free_stack( |
425 | vm_offset_t stack); | |
1c79356b | 426 | |
91447636 A |
427 | extern boolean_t stack_alloc_try( |
428 | thread_t thread); | |
429 | ||
55e303ae | 430 | extern void stack_collect(void); |
1c79356b | 431 | |
91447636 A |
432 | extern void stack_init(void); |
433 | ||
434 | extern kern_return_t thread_state_initialize( | |
435 | thread_t thread); | |
436 | ||
1c79356b | 437 | extern kern_return_t thread_setstatus( |
91447636 | 438 | thread_t thread, |
1c79356b A |
439 | int flavor, |
440 | thread_state_t tstate, | |
441 | mach_msg_type_number_t count); | |
442 | ||
443 | extern kern_return_t thread_getstatus( | |
91447636 | 444 | thread_t thread, |
1c79356b A |
445 | int flavor, |
446 | thread_state_t tstate, | |
447 | mach_msg_type_number_t *count); | |
448 | ||
91447636 A |
449 | extern kern_return_t thread_info_internal( |
450 | thread_t thread, | |
1c79356b A |
451 | thread_flavor_t flavor, |
452 | thread_info_t thread_info_out, | |
453 | mach_msg_type_number_t *thread_info_count); | |
454 | ||
55e303ae A |
455 | extern void thread_task_priority( |
456 | thread_t thread, | |
457 | integer_t priority, | |
458 | integer_t max_priority); | |
1c79356b | 459 | |
91447636 A |
460 | extern void thread_policy_reset( |
461 | thread_t thread); | |
1c79356b | 462 | |
91447636 A |
463 | extern kern_return_t kernel_thread_create( |
464 | thread_continue_t continuation, | |
465 | void *parameter, | |
466 | integer_t priority, | |
467 | thread_t *new_thread); | |
1c79356b | 468 | |
91447636 A |
469 | extern kern_return_t kernel_thread_start_priority( |
470 | thread_continue_t continuation, | |
471 | void *parameter, | |
472 | integer_t priority, | |
473 | thread_t *new_thread); | |
1c79356b | 474 | |
55e303ae A |
475 | extern void machine_stack_attach( |
476 | thread_t thread, | |
91447636 | 477 | vm_offset_t stack); |
1c79356b | 478 | |
55e303ae A |
479 | extern vm_offset_t machine_stack_detach( |
480 | thread_t thread); | |
481 | ||
482 | extern void machine_stack_handoff( | |
483 | thread_t old, | |
484 | thread_t new); | |
485 | ||
486 | extern thread_t machine_switch_context( | |
487 | thread_t old_thread, | |
488 | thread_continue_t continuation, | |
489 | thread_t new_thread); | |
490 | ||
491 | extern void machine_load_context( | |
492 | thread_t thread); | |
493 | ||
91447636 A |
494 | extern kern_return_t machine_thread_state_initialize( |
495 | thread_t thread); | |
9bccf70c | 496 | |
55e303ae | 497 | extern kern_return_t machine_thread_set_state( |
91447636 | 498 | thread_t thread, |
55e303ae A |
499 | thread_flavor_t flavor, |
500 | thread_state_t state, | |
501 | mach_msg_type_number_t count); | |
502 | ||
503 | extern kern_return_t machine_thread_get_state( | |
91447636 | 504 | thread_t thread, |
55e303ae A |
505 | thread_flavor_t flavor, |
506 | thread_state_t state, | |
507 | mach_msg_type_number_t *count); | |
508 | ||
509 | extern kern_return_t machine_thread_dup( | |
91447636 A |
510 | thread_t self, |
511 | thread_t target); | |
55e303ae A |
512 | |
513 | extern void machine_thread_init(void); | |
514 | ||
515 | extern kern_return_t machine_thread_create( | |
516 | thread_t thread, | |
517 | task_t task); | |
c0fea474 A |
518 | extern void machine_thread_switch_addrmode( |
519 | thread_t thread, | |
520 | int oldmode_is64bit); | |
55e303ae A |
521 | |
522 | extern void machine_thread_destroy( | |
523 | thread_t thread); | |
524 | ||
91447636 A |
525 | extern void machine_set_current_thread( |
526 | thread_t thread); | |
55e303ae A |
527 | |
528 | extern void machine_thread_terminate_self(void); | |
529 | ||
91447636 A |
530 | extern kern_return_t machine_thread_get_kern_state( |
531 | thread_t thread, | |
532 | thread_flavor_t flavor, | |
533 | thread_state_t tstate, | |
534 | mach_msg_type_number_t *count); | |
535 | ||
536 | ||
55e303ae A |
537 | /* |
538 | * XXX Funnel locks XXX | |
539 | */ | |
540 | ||
541 | struct funnel_lock { | |
542 | int fnl_type; /* funnel type */ | |
91447636 | 543 | lck_mtx_t *fnl_mutex; /* underlying mutex for the funnel */ |
55e303ae A |
544 | void * fnl_mtxholder; /* thread (last)holdng mutex */ |
545 | void * fnl_mtxrelease; /* thread (last)releasing mutex */ | |
91447636 | 546 | lck_mtx_t *fnl_oldmutex; /* Mutex before collapsing split funnel */ |
55e303ae A |
547 | }; |
548 | ||
55e303ae A |
549 | typedef struct ReturnHandler ReturnHandler; |
550 | ||
91447636 A |
551 | #define thread_mtx_lock(thread) mutex_lock(&(thread)->mutex) |
552 | #define thread_mtx_try(thread) mutex_try(&(thread)->mutex) | |
553 | #define thread_mtx_unlock(thread) mutex_unlock(&(thread)->mutex) | |
55e303ae A |
554 | |
555 | extern void act_execute_returnhandlers(void); | |
556 | ||
557 | extern void install_special_handler( | |
91447636 | 558 | thread_t thread); |
55e303ae A |
559 | |
560 | extern void special_handler( | |
561 | ReturnHandler *rh, | |
91447636 | 562 | thread_t thread); |
1c79356b | 563 | |
9bccf70c | 564 | #else /* MACH_KERNEL_PRIVATE */ |
1c79356b | 565 | |
91447636 | 566 | __BEGIN_DECLS |
1c79356b | 567 | |
91447636 A |
568 | extern thread_t current_thread(void); |
569 | ||
570 | extern void thread_reference( | |
571 | thread_t thread); | |
55e303ae | 572 | |
91447636 A |
573 | extern void thread_deallocate( |
574 | thread_t thread); | |
55e303ae | 575 | |
91447636 | 576 | __END_DECLS |
1c79356b | 577 | |
9bccf70c | 578 | #endif /* MACH_KERNEL_PRIVATE */ |
1c79356b | 579 | |
91447636 | 580 | #ifdef KERNEL_PRIVATE |
1c79356b | 581 | |
91447636 | 582 | typedef struct funnel_lock funnel_t; |
9bccf70c | 583 | |
91447636 | 584 | #ifdef MACH_KERNEL_PRIVATE |
9bccf70c | 585 | |
91447636 A |
586 | extern void funnel_lock( |
587 | funnel_t *lock); | |
9bccf70c | 588 | |
91447636 A |
589 | extern void funnel_unlock( |
590 | funnel_t *lock); | |
55e303ae | 591 | |
91447636 A |
592 | vm_offset_t min_valid_stack_address(void); |
593 | vm_offset_t max_valid_stack_address(void); | |
55e303ae | 594 | |
91447636 | 595 | #endif /* MACH_KERNEL_PRIVATE */ |
55e303ae | 596 | |
91447636 | 597 | __BEGIN_DECLS |
55e303ae | 598 | |
91447636 | 599 | extern funnel_t *thread_funnel_get(void); |
9bccf70c | 600 | |
91447636 A |
601 | extern boolean_t thread_funnel_set( |
602 | funnel_t *lock, | |
603 | boolean_t funneled); | |
55e303ae | 604 | |
91447636 A |
605 | extern thread_t kernel_thread( |
606 | task_t task, | |
607 | void (*start)(void)); | |
55e303ae | 608 | |
91447636 | 609 | __END_DECLS |
55e303ae | 610 | |
91447636 | 611 | #endif /* KERNEL_PRIVATE */ |
55e303ae | 612 | |
91447636 | 613 | __BEGIN_DECLS |
55e303ae | 614 | |
91447636 | 615 | #ifdef XNU_KERNEL_PRIVATE |
9bccf70c | 616 | |
55e303ae A |
617 | /* |
618 | * XXX Funnel locks XXX | |
619 | */ | |
620 | ||
9bccf70c | 621 | #define THR_FUNNEL_NULL (funnel_t *)0 |
1c79356b | 622 | |
55e303ae A |
623 | extern funnel_t *funnel_alloc( |
624 | int type); | |
1c79356b | 625 | |
91447636 A |
626 | extern void funnel_free( |
627 | funnel_t *lock); | |
1c79356b | 628 | |
91447636 A |
629 | extern void thread_read_times( |
630 | thread_t thread, | |
631 | time_value_t *user_time, | |
632 | time_value_t *system_time); | |
1c79356b | 633 | |
91447636 A |
634 | extern void thread_setuserstack( |
635 | thread_t thread, | |
636 | mach_vm_offset_t user_stack); | |
1c79356b | 637 | |
91447636 A |
638 | extern uint64_t thread_adjuserstack( |
639 | thread_t thread, | |
640 | int adjust); | |
55e303ae | 641 | |
91447636 | 642 | extern void thread_setentrypoint( |
55e303ae | 643 | thread_t thread, |
91447636 A |
644 | mach_vm_offset_t entry); |
645 | ||
c0fea474 A |
646 | extern void thread_setsinglestep( |
647 | thread_t thread, | |
648 | int on); | |
649 | ||
91447636 A |
650 | extern kern_return_t thread_wire_internal( |
651 | host_priv_t host_priv, | |
652 | thread_t thread, | |
653 | boolean_t wired, | |
654 | boolean_t *prev_state); | |
655 | ||
656 | /* JMM - These are only temporary */ | |
657 | extern boolean_t is_thread_running(thread_t); /* True is TH_RUN */ | |
658 | extern boolean_t is_thread_idle(thread_t); /* True is TH_IDLE */ | |
55e303ae | 659 | |
91447636 A |
660 | extern kern_return_t thread_dup(thread_t); |
661 | ||
662 | extern task_t get_threadtask(thread_t); | |
c0fea474 A |
663 | #define thread_is_64bit(thd) \ |
664 | task_has_64BitAddr(get_threadtask(thd)) | |
665 | ||
91447636 A |
666 | |
667 | extern void *get_bsdthread_info(thread_t); | |
668 | extern void set_bsdthread_info(thread_t, void *); | |
669 | extern void *uthread_alloc(task_t, thread_t); | |
670 | extern void uthread_free(task_t, void *, void *); | |
671 | ||
672 | extern boolean_t thread_should_halt( | |
673 | thread_t thread); | |
674 | ||
675 | #endif /* XNU_KERNEL_PRIVATE */ | |
676 | ||
677 | extern kern_return_t kernel_thread_start( | |
678 | thread_continue_t continuation, | |
679 | void *parameter, | |
680 | thread_t *new_thread); | |
55e303ae | 681 | |
91447636 | 682 | __END_DECLS |
55e303ae | 683 | |
1c79356b | 684 | #endif /* _KERN_THREAD_H_ */ |