|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Mach Operating System
27: * Copyright (c) 1992,1991,1990,1989 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 [email protected]
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: * processor.h: Processor and processor-set definitions.
53: */
54:
55: #ifndef _KERN_PROCESSOR_H_
56: #define _KERN_PROCESSOR_H_
57:
58: /*
59: * Data structures for managing processors and sets of processors.
60: */
61:
62: #import <mach/features.h>
63:
64: #include <mach/boolean.h>
65: #include <mach/kern_return.h>
66: #include <mach/port.h>
67: #include <mach/processor_info.h>
68: #include <kern/cpu_number.h>
69: #include <kern/lock.h>
70: #include <kern/queue.h>
71: #include <kern/sched.h>
72: #include <kern/kern_types.h>
73: #include <kern/host.h>
74:
75: #if NCPUS > 1
76: #include <machine/ast_types.h>
77: #endif /* NCPUS > 1 */
78:
79: struct processor_set {
80: struct run_queue runq; /* runq for this set */
81: queue_head_t idle_queue; /* idle processors */
82: int idle_count; /* how many ? */
83: decl_simple_lock_data(, idle_lock) /* lock for above */
84: queue_head_t processors; /* all processors here */
85: int processor_count; /* how many ? */
86: boolean_t empty; /* true if no processors */
87: queue_head_t tasks; /* tasks assigned */
88: int task_count; /* how many */
89: queue_head_t threads; /* threads in this set */
90: int thread_count; /* how many */
91: int ref_count; /* structure ref count */
92: decl_simple_lock_data(, ref_lock) /* lock for ref count */
93: queue_chain_t all_psets; /* link for all_psets */
94: boolean_t active; /* is pset in use */
95: decl_simple_lock_data(, lock) /* lock for everything else */
96: struct ipc_port * pset_self; /* port for operations */
97: struct ipc_port * pset_name_self; /* port for information */
98: int max_priority; /* maximum priority */
99: #if MACH_FIXPRI
100: int policies; /* bit vector for policies */
101: #endif /* MACH_FIXPRI */
102: int set_quantum; /* current default quantum */
103: #if NCPUS > 1
104: int quantum_adj_index; /* runtime quantum adj. */
105: decl_simple_lock_data(, quantum_adj_lock) /* lock for above */
106: int machine_quantum[NCPUS+1]; /* ditto */
107: #endif /* NCPUS > 1 */
108: long mach_factor; /* mach_factor */
109: long load_average; /* load_average */
110: long sched_load; /* load avg for scheduler */
111: };
112:
113: typedef struct processor_set *processor_set_name_t;
114:
115: extern struct processor_set default_pset;
116:
117: struct processor {
118: struct run_queue runq; /* local runq for this processor */
119: /* XXX want to do this round robin eventually */
120: queue_chain_t processor_queue; /* idle/assign/shutdown queue link */
121: int state; /* See below */
122: struct thread *next_thread; /* next thread to run if dispatched */
123: struct thread *idle_thread; /* this processor's idle thread. */
124: int quantum; /* quantum for current thread */
125: boolean_t first_quantum; /* first quantum in succession */
126: int last_quantum; /* last quantum assigned */
127:
128: processor_set_t processor_set; /* processor set I belong to */
129: processor_set_t processor_set_next; /* set I will belong to */
130: queue_chain_t processors; /* all processors in set */
131: decl_simple_lock_data(, lock)
132: struct ipc_port *processor_self; /* port for operations */
133: int slot_num; /* machine-indep slot number */
134: #if NCPUS > 1
135: ast_check_t ast_check_data; /* for remote ast_check invocation */
136: #endif /* NCPUS > 1 */
137: /* punt id data temporarily */
138: };
139:
140: extern struct processor processor_array[NCPUS];
141:
142: /*
143: * Chain of all processor sets.
144: */
145: extern queue_head_t all_psets;
146: extern int all_psets_count;
147: decl_simple_lock_data(extern, all_psets_lock);
148:
149: /*
150: * The lock ordering is:
151: *
152: * all_psets_lock
153: * |
154: * |
155: * V
156: * pset_lock
157: * |
158: * +-----------+---------------+-------------------+
159: * | | | |
160: * | | | |
161: * | | V V
162: * | | task_lock pset_self->ip_lock
163: * | | | |
164: * | | +-----------+---------------+ |
165: * | | | | |
166: * | V V V V
167: * | thread_lock* pset_ref_lock
168: * | |
169: * | +-------+
170: * | | |
171: * | | V
172: * | | runq_lock*
173: * | |
174: * V V
175: * processor_lock*
176: * |
177: * |
178: * V
179: * pset_idle_lock*
180: * |
181: * |
182: * V
183: * action_lock*
184: *
185: * Locks marked with "*" are taken at splsched.
186: */
187:
188: /*
189: * XXX need a pointer to the master processor structure
190: */
191:
192: extern processor_t master_processor;
193:
194: /*
195: * NOTE: The processor->processor_set link is needed in one of the
196: * scheduler's critical paths. [Figure out where to look for another
197: * thread to run on this processor.] It is accessed without locking.
198: * The following access protocol controls this field.
199: *
200: * Read from own processor - just read.
201: * Read from another processor - lock processor structure during read.
202: * Write from own processor - lock processor structure during write.
203: * Write from another processor - NOT PERMITTED.
204: *
205: */
206:
207: /*
208: * Processor state locking:
209: *
210: * Values for the processor state are defined below. If the processor
211: * is off-line or being shutdown, then it is only necessary to lock
212: * the processor to change its state. Otherwise it is only necessary
213: * to lock its processor set's idle_lock. Scheduler code will
214: * typically lock only the idle_lock, but processor manipulation code
215: * will often lock both.
216: */
217:
218: #define PROCESSOR_OFF_LINE 0 /* Not in system */
219: #define PROCESSOR_RUNNING 1 /* Running normally */
220: #define PROCESSOR_IDLE 2 /* idle */
221: #define PROCESSOR_DISPATCHING 3 /* dispatching (idle -> running) */
222: #define PROCESSOR_ASSIGN 4 /* Assignment is changing */
223: #define PROCESSOR_SHUTDOWN 5 /* Being shutdown */
224:
225: /*
226: * Use processor ptr array to find current processor's data structure.
227: * This replaces a multiplication (index into processor_array) with
228: * an array lookup and a memory reference. It also allows us to save
229: * space if processor numbering gets too sparse.
230: */
231:
232: extern processor_t processor_ptr[NCPUS];
233:
234: #define cpu_to_processor(i) (processor_ptr[i])
235:
236: #define current_processor() (processor_ptr[cpu_number()])
237: #define current_processor_set() (current_processor()->processor_set)
238:
239: /* Compatibility -- will go away */
240:
241: #define cpu_state(slot_num) (processor_ptr[slot_num]->state)
242: #define cpu_idle(slot_num) (cpu_state(slot_num) == PROCESSOR_IDLE)
243:
244: /* Useful lock macros */
245:
246: #define pset_lock(pset) simple_lock(&(pset)->lock)
247: #define pset_unlock(pset) simple_unlock(&(pset)->lock)
248: #define pset_ref_lock(pset) simple_lock(&(pset)->ref_lock)
249: #define pset_ref_unlock(pset) simple_unlock(&(pset)->ref_lock)
250:
251: #define processor_lock(pr) simple_lock(&(pr)->lock)
252: #define processor_unlock(pr) simple_unlock(&(pr)->lock)
253:
254: typedef mach_port_t *processor_array_t;
255: typedef mach_port_t *processor_set_array_t;
256: typedef mach_port_t *processor_set_name_array_t;
257:
258:
259: /*
260: * Exported functions
261: */
262:
263: /* Initialization */
264:
265: #if MACH_HOST
266: extern void pset_sys_bootstrap(void);
267: extern void pset_sys_init(void);
268: #endif /* MACH_HOST */
269:
270: /* Pset internal functions */
271:
272: extern void pset_reference(processor_set_t);
273: extern void pset_deallocate(processor_set_t);
274: extern void pset_remove_processor(processor_set_t, processor_t);
275: extern void pset_add_processor(processor_set_t, processor_t);
276: extern void pset_remove_task(processor_set_t, struct task *);
277: extern void pset_add_task(processor_set_t, struct task *);
278: extern void pset_remove_thread(processor_set_t, struct thread *);
279: extern void pset_add_thread(processor_set_t, struct thread *);
280: extern void thread_change_psets(struct thread *,
281: processor_set_t, processor_set_t);
282:
283: /* Processor interface */
284:
285: extern kern_return_t processor_get_assignment(
286: processor_t processor,
287: processor_set_t *processor_set);
288:
289: extern kern_return_t processor_info(
290: processor_t processor,
291: int flavor,
292: host_t * host,
293: processor_info_t info,
294: natural_t * count);
295:
296: extern kern_return_t processor_start(
297: processor_t processor);
298:
299: extern kern_return_t processor_exit(
300: processor_t processor);
301:
302: extern kern_return_t processor_control(
303: processor_t processor,
304: processor_info_t info,
305: natural_t count);
306:
307: /* Pset interface */
308:
309: extern kern_return_t processor_set_create(
310: host_t host,
311: processor_set_t *new_set,
312: processor_set_t *new_name);
313:
314: extern kern_return_t processor_set_destroy(
315: processor_set_t pset);
316:
317: extern kern_return_t processor_set_info(
318: processor_set_t pset,
319: int flavor,
320: host_t *host,
321: processor_set_info_t info,
322: natural_t *count);
323:
324: extern kern_return_t processor_set_max_priority(
325: processor_set_t pset,
326: int max_priority,
327: boolean_t change_threads);
328:
329: extern kern_return_t processor_set_policy_enable(
330: processor_set_t pset,
331: int policy);
332:
333: extern kern_return_t processor_set_policy_disable(
334: processor_set_t pset,
335: int policy,
336: boolean_t change_threads);
337:
338: extern kern_return_t processor_set_tasks(
339: processor_set_t pset,
340: task_array_t *task_list,
341: natural_t *count);
342:
343: extern kern_return_t processor_set_threads(
344: processor_set_t pset,
345: thread_array_t *thread_list,
346: natural_t *count);
347:
348: #endif /* _KERN_PROCESSOR_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.