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