]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kern/thread_act.h
xnu-344.21.73.tar.gz
[apple/xnu.git] / osfmk / kern / thread_act.h
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
d7e50217 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
d7e50217
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
d7e50217
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * @OSF_FREE_COPYRIGHT@
27 */
28/*
29 * Copyright (c) 1993 The University of Utah and
30 * the Computer Systems Laboratory (CSL). All rights reserved.
31 *
32 * Permission to use, copy, modify and distribute this software and its
33 * documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
37 *
38 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
39 * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
40 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 *
42 * CSL requests users of this software to return to csl-dist@cs.utah.edu any
43 * improvements that they make and grant CSL redistribution rights.
44 *
45 * Author: Bryan Ford, University of Utah CSL
46 *
47 * File: thread_act.h
48 *
49 * thread activation definitions
50 */
51#ifndef _KERN_THREAD_ACT_H_
52#define _KERN_THREAD_ACT_H_
53
54#include <mach/mach_types.h>
1c79356b
A
55#include <mach/vm_param.h>
56#include <mach/thread_info.h>
57#include <mach/exception_types.h>
58
9bccf70c
A
59#include <sys/appleapiopts.h>
60
61#ifdef __APPLE_API_PRIVATE
62
63#ifdef MACH_KERNEL_PRIVATE
1c79356b 64
1c79356b
A
65#include <mach_assert.h>
66#include <thread_swapper.h>
67#include <cputypes.h>
68
69#include <kern/lock.h>
70#include <kern/queue.h>
71#include <kern/etap_macros.h>
72#include <kern/exception.h>
73#include <kern/thread.h>
1c79356b
A
74#include <ipc/ipc_port.h>
75#include <machine/thread_act.h>
76
9bccf70c
A
77/*
78 * Here is a description of the states an thread_activation may be in.
1c79356b
A
79 *
80 * An activation always has a valid task pointer, and it is always constant.
81 * The activation is only linked onto the task's activation list until
82 * the activation is terminated.
83 *
9bccf70c 84 * The thread holds a reference on the activation while using it.
1c79356b
A
85 *
86 * An activation is active until thread_terminate is called on it;
87 * then it is inactive, waiting for all references to be dropped.
88 * Future control operations on the terminated activation will fail,
89 * with the exception that act_yank still works if the activation is
9bccf70c
A
90 * still on an RPC chain. A terminated activation always has a null
91 * thread pointer.
1c79356b
A
92 *
93 * An activation is suspended when suspend_count > 0.
1c79356b
A
94 *
95 * Locking note: access to data relevant to scheduling state (user_stop_count,
96 * suspend_count, handlers, special_handler) is controlled by the combination
97 * of locks acquired by act_lock_thread(). That is, not only must act_lock()
9bccf70c 98 * be held, but migration through the activation must be frozen (so that the
1c79356b
A
99 * thread pointer doesn't change). If a shuttle is associated with the
100 * activation, then its thread_lock() must also be acquired to change these
101 * data. Regardless of whether a shuttle is present, the data must be
102 * altered at splsched().
103 */
104
105typedef struct ReturnHandler {
106 struct ReturnHandler *next;
107 void (*handler)(struct ReturnHandler *rh,
108 struct thread_activation *thr_act);
109} ReturnHandler;
110
111typedef struct thread_activation {
112
113 /*** task linkage ***/
114
115 /* Links for task's circular list of activations. The activation
116 * is only on the task's activation list while active. Must be
117 * first.
118 */
119 queue_chain_t thr_acts;
120
121 /* Indicators for whether this activation is in the midst of
122 * resuming or has already been resumed in a kernel-loaded
123 * task -- these flags are basically for quick access to
124 * this information.
125 */
126 boolean_t kernel_loaded; /* running in kernel-loaded task */
127 boolean_t kernel_loading; /* about to run kernel-loaded */
128
9bccf70c
A
129 boolean_t inited;
130
1c79356b
A
131 /*** Machine-dependent state ***/
132 struct MachineThrAct mact;
133
134 /*** Consistency ***/
135 decl_mutex_data(,lock)
136 decl_simple_lock_data(,sched_lock)
137 int ref_count;
138
139 /* Reference to the task this activation is in.
140 * Constant for the life of the activation
141 */
142 struct task *task;
143 vm_map_t map; /* cached current map */
144
1c79356b
A
145 /*** Thread linkage ***/
146 /* Shuttle using this activation, zero if not in use. The shuttle
147 * holds a reference on the activation while this is nonzero.
148 */
149 struct thread_shuttle *thread;
150
151 /* The rest in this section is only valid when thread is nonzero. */
152
153 /* Next higher and next lower activation on the thread's activation
154 * stack. For a topmost activation or the null_act, higher is
155 * undefined. The bottommost activation is always the null_act.
156 */
157 struct thread_activation *higher, *lower;
158
159 /* Alert bits pending at this activation; some of them may have
160 * propagated from lower activations.
161 */
162 unsigned alerts;
163
164 /* Mask of alert bits to be allowed to pass through from lower levels.
165 */
166 unsigned alert_mask;
167
1c79356b
A
168 /*** Control information ***/
169
170 /* Number of outstanding suspensions on this activation. */
171 int suspend_count;
172
173 /* User-visible scheduling state */
174 int user_stop_count; /* outstanding stops */
175
176 /* ast is needed - see ast.h */
9bccf70c 177 ast_t ast;
1c79356b
A
178
179 /* This is normally true, but is set to false when the
180 * activation is terminated.
181 */
182 int active;
183
184 /* Chain of return handlers to be called before the thread is
185 * allowed to return to this invocation
186 */
187 ReturnHandler *handlers;
188
189 /* A special ReturnHandler attached to the above chain to
190 * handle suspension and such
191 */
192 ReturnHandler special_handler;
193
194 /* Special ports attached to this activation */
195 struct ipc_port *ith_self; /* not a right, doesn't hold ref */
196 struct ipc_port *ith_sself; /* a send right */
197 struct exception_action exc_actions[EXC_TYPES_COUNT];
198
199 /* A list of ulocks (a lock set element) currently held by the thread
200 */
201 queue_head_t held_ulocks;
202
203#if MACH_PROF
204 /* Profiling data structures */
205 boolean_t act_profiled; /* is activation being profiled? */
206 boolean_t act_profiled_own;
207 /* is activation being profiled
208 * on its own ? */
209 struct prof_data *profil_buffer;/* prof struct if either is so */
210#endif /* MACH_PROF */
211
212#ifdef MACH_BSD
213 void *uthread;
214#endif
215
216} Thread_Activation;
217
1c79356b
A
218/* Alert bits */
219#define SERVER_TERMINATED 0x01
220#define ORPHANED 0x02
221#define CLIENT_TERMINATED 0x04
222#define TIME_CONSTRAINT_UNSATISFIED 0x08
223
1c79356b
A
224#define act_lock_init(thr_act) mutex_init(&(thr_act)->lock, ETAP_THREAD_ACT)
225#define act_lock(thr_act) mutex_lock(&(thr_act)->lock)
226#define act_lock_try(thr_act) mutex_try(&(thr_act)->lock)
227#define act_unlock(thr_act) mutex_unlock(&(thr_act)->lock)
228
229/* Sanity check the ref count. If it is 0, we may be doubly zfreeing.
230 * If it is larger than max int, it has been corrupted, probably by being
231 * modified into an address (this is architecture dependent, but it's
232 * safe to assume there cannot really be max int references).
233 */
234#define ACT_MAX_REFERENCES \
235 (unsigned)(~0 ^ (1 << (sizeof(int)*BYTE_SIZE - 1)))
236
237#define act_reference_fast(thr_act) \
238 MACRO_BEGIN \
239 if (thr_act) { \
240 act_lock(thr_act); \
241 assert((thr_act)->ref_count < ACT_MAX_REFERENCES); \
242 (thr_act)->ref_count++; \
243 act_unlock(thr_act); \
244 } \
245 MACRO_END
246
247#define act_reference(thr_act) act_reference_fast(thr_act)
248
249#define act_locked_act_reference(thr_act) \
250 MACRO_BEGIN \
251 if (thr_act) { \
252 assert((thr_act)->ref_count < ACT_MAX_REFERENCES); \
253 (thr_act)->ref_count++; \
254 } \
255 MACRO_END
256
1c79356b
A
257#define act_deallocate_fast(thr_act) \
258 MACRO_BEGIN \
259 if (thr_act) { \
260 int new_value; \
261 act_lock(thr_act); \
262 assert((thr_act)->ref_count > 0 && \
263 (thr_act)->ref_count <= ACT_MAX_REFERENCES); \
264 new_value = --(thr_act)->ref_count; \
265 act_unlock(thr_act); \
266 if (new_value == 0) \
267 act_free(thr_act); \
268 } \
269 MACRO_END
270
271#define act_deallocate(thr_act) act_deallocate_fast(thr_act)
272
273#define act_locked_act_deallocate(thr_act) \
274 MACRO_BEGIN \
275 if (thr_act) { \
276 int new_value; \
277 assert((thr_act)->ref_count > 0 && \
278 (thr_act)->ref_count <= ACT_MAX_REFERENCES); \
279 new_value = --(thr_act)->ref_count; \
280 if (new_value == 0) { \
281 panic("a_l_act_deallocate: would free act"); \
282 } \
283 } \
284 MACRO_END
285
9bccf70c 286extern struct thread_activation pageout_act;
1c79356b
A
287
288extern void act_init(void);
1c79356b
A
289extern void thread_release(thread_act_t);
290extern kern_return_t thread_dowait(thread_act_t, boolean_t);
291extern void thread_hold(thread_act_t);
1c79356b 292
1c79356b
A
293extern kern_return_t thread_get_special_port(thread_act_t, int,
294 ipc_port_t *);
295extern kern_return_t thread_set_special_port(thread_act_t, int,
296 ipc_port_t);
297extern thread_t act_lock_thread(thread_act_t);
298extern void act_unlock_thread(thread_act_t);
299extern void install_special_handler(thread_act_t);
300extern thread_act_t thread_lock_act(thread_t);
301extern void thread_unlock_act(thread_t);
302extern void act_attach(thread_act_t, thread_t, unsigned);
303extern void act_execute_returnhandlers(void);
304extern void act_detach(thread_act_t);
305extern void act_free(thread_act_t);
306
307/* machine-dependent functions */
308extern void act_machine_return(kern_return_t);
309extern void act_machine_init(void);
310extern kern_return_t act_machine_create(struct task *, thread_act_t);
311extern void act_machine_destroy(thread_act_t);
312extern kern_return_t act_machine_set_state(thread_act_t,
313 thread_flavor_t, thread_state_t,
314 mach_msg_type_number_t );
315extern kern_return_t act_machine_get_state(thread_act_t,
316 thread_flavor_t, thread_state_t,
317 mach_msg_type_number_t *);
318extern void act_machine_switch_pcb(thread_act_t);
319extern void act_virtual_machine_destroy(thread_act_t);
320
321extern kern_return_t act_create(task_t, thread_act_t *);
322extern kern_return_t act_get_state(thread_act_t, int, thread_state_t,
323 mach_msg_type_number_t *);
324extern kern_return_t act_set_state(thread_act_t, int, thread_state_t,
325 mach_msg_type_number_t);
326
327extern int dump_act(thread_act_t); /* debugging */
328
9bccf70c
A
329#if MACH_ASSERT
330/*
331 * Debugging support - "watchacts", a patchable selective trigger
332 */
333extern unsigned int watchacts; /* debug printf trigger */
334#define WA_SCHED 0x001 /* kern/sched_prim.c */
335#define WA_THR 0x002 /* kern/thread.c */
336#define WA_ACT_LNK 0x004 /* kern/thread_act.c act mgmt */
337#define WA_ACT_HDLR 0x008 /* kern/thread_act.c act hldrs */
338#define WA_TASK 0x010 /* kern/task.c */
339#define WA_BOOT 0x020 /* bootstrap,startup.c */
340#define WA_PCB 0x040 /* machine/pcb.c */
341#define WA_PORT 0x080 /* ports + port sets */
342#define WA_EXIT 0x100 /* exit path */
343#define WA_SWITCH 0x200 /* context switch (!!) */
344#define WA_STATE 0x400 /* get/set state (!!) */
345#define WA_ALL (~0)
346#endif /* MACH_ASSERT */
1c79356b 347
9bccf70c 348#else /* MACH_KERNEL_PRIVATE */
1c79356b 349
1c79356b
A
350extern void act_reference(thread_act_t);
351extern void act_deallocate(thread_act_t);
352
9bccf70c 353#endif /* MACH_KERNEL_PRIVATE */
1c79356b 354
1c79356b
A
355extern kern_return_t act_alert(thread_act_t, unsigned);
356extern kern_return_t act_alert_mask(thread_act_t, unsigned );
357extern kern_return_t post_alert(thread_act_t, unsigned);
358
9bccf70c 359typedef void (thread_apc_handler_t)(thread_act_t);
1c79356b
A
360
361extern kern_return_t thread_apc_set(thread_act_t, thread_apc_handler_t);
362extern kern_return_t thread_apc_clear(thread_act_t, thread_apc_handler_t);
363
9bccf70c 364extern vm_map_t swap_act_map(thread_act_t, vm_map_t);
1c79356b
A
365
366extern void *get_bsdthread_info(thread_act_t);
367extern void set_bsdthread_info(thread_act_t, void *);
9bccf70c
A
368extern task_t get_threadtask(thread_act_t);
369
370#endif /* __APPLE_API_PRIVATE */
371
372#ifdef __APPLE_API_UNSTABLE
373
374#if !defined(MACH_KERNEL_PRIVATE)
375
376extern thread_act_t current_act(void);
377
378#endif /* MACH_KERNEL_PRIVATE */
379
380#endif /* __APPLE_API_UNSTABLE */
381
382extern kern_return_t thread_abort(thread_act_t);
383extern kern_return_t thread_abort_safely(thread_act_t);
384extern kern_return_t thread_resume(thread_act_t);
385extern kern_return_t thread_suspend(thread_act_t);
386extern kern_return_t thread_terminate(thread_act_t);
1c79356b
A
387
388#endif /* _KERN_THREAD_ACT_H_ */