|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: #include <mach/mach_types.h>
23: #include <kern/queue.h>
24: #include <kern/ast.h>
25: #include <kern/thread.h>
26: #include <kern/task.h>
27: #include <kern/spl.h>
28: #include <kern/lock.h>
29: #include <vm/vm_map.h>
30: #include <vm/pmap.h>
31: #include <ipc/ipc_port.h>
32: #include <ipc/ipc_object.h>
33:
34: #undef clear_wait
35: #undef act_deallocate
36: #undef act_reference
37: #undef thread_should_halt
38: #undef ipc_port_release
39: #undef thread_ast_set
40:
41: decl_simple_lock_data(extern,reaper_lock)
42: extern queue_head_t reaper_queue;
43:
44: /* BSD KERN COMPONENT INTERFACE */
45:
46: thread_act_t get_firstthread(task_t);
47: vm_map_t get_task_map(task_t);
48: ipc_space_t get_task_ipcspace(task_t);
49: boolean_t is_kerneltask(task_t);
50: boolean_t is_thread_idle(thread_t);
51: boolean_t is_thread_running(thread_t);
52: thread_shuttle_t getshuttle_thread( thread_act_t);
53: thread_act_t getact_thread( thread_shuttle_t);
54: vm_offset_t get_map_min( vm_map_t);
55: vm_offset_t get_map_max( vm_map_t);
56: void act_reference( thread_act_t);
57: void act_deallocate( thread_act_t);
58: int get_task_userstop(task_t);
59: int get_thread_userstop(thread_act_t);
60: int inc_task_userstop(task_t);
61: boolean_t thread_should_abort(thread_shuttle_t);
62: void task_act_iterate_wth_args(task_t, void(*)(thread_act_t, void *), void *);
63: void ipc_port_release(ipc_port_t);
64: void thread_ast_set(thread_act_t, ast_t);
65: boolean_t is_thread_active(thread_t);
66: event_t get_thread_waitevent(thread_t);
67: kern_return_t get_thread_waitresult(thread_t);
68: vm_size_t get_vmmap_size(vm_map_t);
69: int get_vmmap_entries(vm_map_t);
70: int get_task_numacts(task_t);
71:
72:
73:
74: /*
75: *
76: */
77: void *get_bsdtask_info(task_t t)
78: {
79: return(t->bsd_info);
80: }
81:
82: /*
83: *
84: */
85: void set_bsdtask_info(task_t t,void * v)
86: {
87: t->bsd_info=v;
88: }
89:
90: /*
91: *
92: */
93: void *get_bsdthread_info(thread_act_t th)
94: {
95: return(&th->bsd_space[0]);
96: }
97:
98: /*
99: *
100: */
101: thread_act_t get_firstthread(task_t task)
102: {
103: return((thread_act_t)queue_first(&task->thr_acts));
104: }
105:
106: /*
107: *
108: */
109: vm_map_t get_task_map(task_t t)
110: {
111: return(t->map);
112: }
113:
114: /*
115: *
116: */
117: ipc_space_t get_task_ipcspace(task_t t)
118: {
119: return(t->itk_space);
120: }
121:
122: int get_task_numacts(task_t t)
123: {
124: return(t->thr_act_count);
125: }
126:
127: /*
128: *
129: */
130: void set_task_map(task_t t,vm_map_t map)
131: {
132: t->map = map;
133: }
134:
135: /*
136: *
137: */
138: void set_act_map(thread_act_t t,vm_map_t map)
139: {
140: t->map = map;
141: }
142:
143: /*
144: *
145: */
146: pmap_t get_task_pmap(task_t t)
147: {
148: return(t->map->pmap);
149: }
150:
151: /*
152: *
153: */
154: pmap_t get_map_pmap(vm_map_t map)
155: {
156: return(map->pmap);
157: }
158: /*
159: *
160: */
161: task_t get_threadtask(thread_act_t th)
162: {
163: return(th->task);
164: }
165:
166:
167: /*
168: *
169: */
170: boolean_t is_thread_idle(thread_t th)
171: {
172: return(th->state & TH_IDLE == TH_IDLE);
173: }
174:
175: /*
176: *
177: */
178: boolean_t is_thread_running(thread_t th)
179: {
180: return(th->state & TH_RUN == TH_RUN);
181: }
182:
183: /*
184: *
185: */
186: thread_shuttle_t
187: getshuttle_thread(
188: thread_act_t th)
189: {
190: #ifdef DEBUG
191: assert(th->thread);
192: #endif
193: return(th->thread);
194: }
195:
196: /*
197: *
198: */
199: thread_act_t
200: getact_thread(
201: thread_shuttle_t th)
202: {
203: #ifdef DEBUG
204: assert(th->top_act);
205: #endif
206: return(th->top_act);
207: }
208:
209: /*
210: *
211: */
212: vm_offset_t
213: get_map_min(
214: vm_map_t map)
215: {
216: return(vm_map_min(map));
217: }
218:
219: /*
220: *
221: */
222: vm_offset_t
223: get_map_max(
224: vm_map_t map)
225: {
226: return(vm_map_max(map));
227: }
228: vm_size_t
229: get_vmmap_size(
230: vm_map_t map)
231: {
232: return(map->size);
233: }
234: int
235: get_vmmap_entries(
236: vm_map_t map)
237: {
238: return(map->hdr.nentries);
239: }
240:
241: /*
242: *
243: */
244: void
245: act_reference(
246: thread_act_t thr_act)
247: {
248: if (thr_act) {
249: act_lock(thr_act);
250: assert((thr_act)->ref_count < ACT_MAX_REFERENCES);
251: if ((thr_act)->ref_count <= 0)
252: panic("act_reference: already freed");
253: (thr_act)->ref_count++;
254: act_unlock(thr_act);
255: }
256: }
257:
258: /*
259: *
260: */
261: void
262: act_deallocate(
263: thread_act_t thr_act)
264: {
265: if (thr_act) {
266: int new_value;
267: act_lock(thr_act);
268: assert((thr_act)->ref_count > 0 &&
269: (thr_act)->ref_count <= ACT_MAX_REFERENCES);
270: new_value = --(thr_act)->ref_count;
271: if (new_value == 0)
272: { act_free(thr_act); }
273: else
274: act_unlock(thr_act);
275: }
276: }
277:
278: /*
279: *
280: */
281: int
282: get_task_userstop(
283: task_t task)
284: {
285: return(task->user_stop_count);
286: }
287:
288: /*
289: *
290: */
291: int
292: get_thread_userstop(
293: thread_act_t th)
294: {
295: return(th->user_stop_count);
296: }
297:
298: /*
299: *
300: */
301: int
302: inc_task_userstop(
303: task_t task)
304: {
305: int i=0;
306: i = task->user_stop_count;
307: task->user_stop_count++;
308: return(i);
309: }
310:
311:
312: /*
313: *
314: */
315: boolean_t
316: thread_should_abort(
317: thread_shuttle_t th)
318: {
319: return( (!th->top_act || !th->top_act->active ||
320: th->state & TH_ABORT));
321: }
322: /*
323: *
324: */
325: void
326: task_act_iterate_wth_args(
327: task_t task,
328: void (*func_callback)(thread_act_t, void *),
329: void *func_arg)
330: {
331: thread_act_t inc, ninc;
332:
333: for (inc = (thread_act_t)queue_first(&task->thr_acts);
334: inc != (thread_act_t)&task->thr_acts;
335: inc = ninc) {
336: ninc = (thread_act_t)queue_next(&inc->thr_acts);
337: (void) (*func_callback)(inc, func_arg);
338: }
339:
340: }
341:
342: void
343: ipc_port_release(
344: ipc_port_t port)
345: {
346: ipc_object_release(&(port)->ip_object);
347: }
348:
349: void
350: thread_ast_set(
351: thread_act_t act,
352: ast_t reason)
353: {
354: act->ast |= reason;
355: }
356:
357: boolean_t
358: is_thread_active(
359: thread_shuttle_t th)
360: {
361: return(th->active);
362: }
363:
364: event_t
365: get_thread_waitevent(
366: thread_shuttle_t th)
367: {
368: return(th->wait_event);
369: }
370:
371: kern_return_t
372: get_thread_waitresult(
373: thread_shuttle_t th)
374: {
375: return(th->wait_result);
376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.