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