|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1993,1992,1991,1990,1989,1988 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * host.c
28: *
29: * Non-ipc host functions.
30: */
31:
32: #include <cpus.h>
33: #include <mach_host.h>
34:
35: #include <kern/assert.h>
36: #include <kern/kalloc.h>
37: #include <kern/host.h>
38: #include <mach/host_info.h>
39: #include <mach/kern_return.h>
40: #include <mach/machine.h>
41: #include <mach/port.h>
42: #include <kern/processor.h>
43: #include <kern/ipc_host.h>
44:
45: #include <mach/vm_param.h>
46:
47:
48:
49: host_data_t realhost;
50:
51: kern_return_t host_processors(
52: host_t host,
53: processor_array_t *processor_list,
54: natural_t *countp)
55: {
56: register int i;
57: register processor_t *tp;
58: vm_offset_t addr;
59: unsigned int count;
60:
61: if (host == HOST_NULL)
62: return KERN_INVALID_ARGUMENT;
63:
64: /*
65: * Determine how many processors we have.
66: * (This number shouldn't change.)
67: */
68:
69: count = 0;
70: for (i = 0; i < NCPUS; i++)
71: if (machine_slot[i].is_cpu)
72: count++;
73:
74: if (count == 0)
75: panic("host_processors");
76:
77: addr = kalloc((vm_size_t) (count * sizeof(mach_port_t)));
78: if (addr == 0)
79: return KERN_RESOURCE_SHORTAGE;
80:
81: tp = (processor_t *) addr;
82: for (i = 0; i < NCPUS; i++)
83: if (machine_slot[i].is_cpu)
84: *tp++ = cpu_to_processor(i);
85:
86: *countp = count;
87: *processor_list = (mach_port_t *) addr;
88:
89: /* do the conversion that Mig should handle */
90:
91: tp = (processor_t *) addr;
92: for (i = 0; i < count; i++)
93: ((mach_port_t *) tp)[i] =
94: (mach_port_t)convert_processor_to_port(tp[i]);
95:
96: return KERN_SUCCESS;
97: }
98:
99: kern_return_t host_info(
100: host_t host,
101: int flavor,
102: host_info_t info,
103: natural_t *count)
104: {
105: register integer_t i, *slot_ptr;
106:
107: if (host == HOST_NULL)
108: return KERN_INVALID_ARGUMENT;
109:
110: switch(flavor) {
111:
112: case HOST_BASIC_INFO:
113: {
114: register host_basic_info_t basic_info;
115:
116: /*
117: * Basic information about this host.
118: */
119: if (*count < HOST_BASIC_INFO_COUNT)
120: return KERN_FAILURE;
121:
122: basic_info = (host_basic_info_t) info;
123:
124: basic_info->max_cpus = machine_info.max_cpus;
125: basic_info->avail_cpus = machine_info.avail_cpus;
126: basic_info->memory_size = machine_info.memory_size;
127: basic_info->cpu_type =
128: machine_slot[master_processor->slot_num].cpu_type;
129: basic_info->cpu_subtype =
130: machine_slot[master_processor->slot_num].cpu_subtype;
131:
132: *count = HOST_BASIC_INFO_COUNT;
133: return KERN_SUCCESS;
134: }
135:
136: case HOST_PROCESSOR_SLOTS:
137: /*
138: * Return numbers of slots with active processors
139: * in them.
140: */
141: if (*count < NCPUS)
142: return KERN_INVALID_ARGUMENT;
143:
144: slot_ptr = (integer_t *)info;
145: *count = 0;
146: for (i = 0; i < NCPUS; i++) {
147: if (machine_slot[i].is_cpu &&
148: machine_slot[i].running) {
149: *slot_ptr++ = i;
150: (*count)++;
151: }
152: }
153: return KERN_SUCCESS;
154:
155: case HOST_SCHED_INFO:
156: {
157: register host_sched_info_t sched_info;
158: extern int tick; /* microseconds per clock tick */
159: extern int min_quantum;
160: /* minimum quantum, in microseconds */
161:
162: /*
163: * Return scheduler information.
164: */
165: if (*count < HOST_SCHED_INFO_COUNT)
166: return(KERN_FAILURE);
167:
168: sched_info = (host_sched_info_t) info;
169:
170: sched_info->min_timeout = tick / 1000;
171: sched_info->min_quantum = min_quantum / 1000;
172: /* convert microseconds to milliseconds */
173:
174: *count = HOST_SCHED_INFO_COUNT;
175: return KERN_SUCCESS;
176: }
177:
178: case HOST_LOAD_INFO:
179: {
180: register host_load_info_t load_info;
181: extern long avenrun[3], mach_factor[3];
182:
183: if (*count < HOST_LOAD_INFO_COUNT)
184: return KERN_FAILURE;
185:
186: load_info = (host_load_info_t) info;
187:
188: bcopy((char *) avenrun,
189: (char *) load_info->avenrun,
190: sizeof avenrun);
191: bcopy((char *) mach_factor,
192: (char *) load_info->mach_factor,
193: sizeof mach_factor);
194:
195: *count = HOST_LOAD_INFO_COUNT;
196: return KERN_SUCCESS;
197: }
198:
199: default:
200: return KERN_INVALID_ARGUMENT;
201: }
202: }
203:
204: /*
205: * Return kernel version string (more than you ever
206: * wanted to know about what version of the kernel this is).
207: */
208:
209: kern_return_t host_kernel_version(
210: host_t host,
211: kernel_version_t out_version)
212: {
213: extern char version[];
214:
215: if (host == HOST_NULL)
216: return KERN_INVALID_ARGUMENT;
217:
218: (void) strncpy(out_version, version, sizeof(kernel_version_t));
219:
220: return KERN_SUCCESS;
221: }
222:
223: /*
224: * host_processor_sets:
225: *
226: * List all processor sets on the host.
227: */
228: #if MACH_HOST
229: kern_return_t
230: host_processor_sets(
231: host_t host,
232: processor_set_name_array_t *pset_list,
233: natural_t *count)
234: {
235: unsigned int actual; /* this many psets */
236: processor_set_t pset;
237: processor_set_t *psets;
238: int i;
239:
240: vm_size_t size;
241: vm_size_t size_needed;
242: vm_offset_t addr;
243:
244: if (host == HOST_NULL)
245: return KERN_INVALID_ARGUMENT;
246:
247: size = 0; addr = 0;
248:
249: for (;;) {
250: simple_lock(&all_psets_lock);
251: actual = all_psets_count;
252:
253: /* do we have the memory we need? */
254:
255: size_needed = actual * sizeof(mach_port_t);
256: if (size_needed <= size)
257: break;
258:
259: /* unlock and allocate more memory */
260: simple_unlock(&all_psets_lock);
261:
262: if (size != 0)
263: kfree(addr, size);
264:
265: assert(size_needed > 0);
266: size = size_needed;
267:
268: addr = kalloc(size);
269: if (addr == 0)
270: return KERN_RESOURCE_SHORTAGE;
271: }
272:
273: /* OK, have memory and the all_psets_lock */
274:
275: psets = (processor_set_t *) addr;
276:
277: for (i = 0, pset = (processor_set_t) queue_first(&all_psets);
278: i < actual;
279: i++, pset = (processor_set_t) queue_next(&pset->all_psets)) {
280: /* take ref for convert_pset_name_to_port */
281: pset_reference(pset);
282: psets[i] = pset;
283: }
284: assert(queue_end(&all_psets, (queue_entry_t) pset));
285:
286: /* can unlock now that we've got the pset refs */
287: simple_unlock(&all_psets_lock);
288:
289: /*
290: * Always have default port.
291: */
292:
293: assert(actual > 0);
294:
295: /* if we allocated too much, must copy */
296:
297: if (size_needed < size) {
298: vm_offset_t newaddr;
299:
300: newaddr = kalloc(size_needed);
301: if (newaddr == 0) {
302: for (i = 0; i < actual; i++)
303: pset_deallocate(psets[i]);
304: kfree(addr, size);
305: return KERN_RESOURCE_SHORTAGE;
306: }
307:
308: bcopy((char *) addr, (char *) newaddr, size_needed);
309: kfree(addr, size);
310: psets = (processor_set_t *) newaddr;
311: }
312:
313: *pset_list = (mach_port_t *) psets;
314: *count = actual;
315:
316: /* do the conversion that Mig should handle */
317:
318: for (i = 0; i < actual; i++)
319: ((mach_port_t *) psets)[i] =
320: (mach_port_t)convert_pset_name_to_port(psets[i]);
321:
322: return KERN_SUCCESS;
323: }
324: #else /* MACH_HOST */
325: /*
326: * Only one processor set, the default processor set, in this case.
327: */
328: kern_return_t
329: host_processor_sets(
330: host_t host,
331: processor_set_name_array_t *pset_list,
332: natural_t *count)
333: {
334: vm_offset_t addr;
335:
336: if (host == HOST_NULL)
337: return KERN_INVALID_ARGUMENT;
338:
339: /*
340: * Allocate memory. Can be pageable because it won't be
341: * touched while holding a lock.
342: */
343:
344: addr = kalloc((vm_size_t) sizeof(mach_port_t));
345: if (addr == 0)
346: return KERN_RESOURCE_SHORTAGE;
347:
348: /* take for for convert_pset_name_to_port */
349: pset_reference(&default_pset);
350: /* do the conversion that Mig should handle */
351: *((mach_port_t *) addr) =
352: (mach_port_t) convert_pset_name_to_port(&default_pset);
353:
354: *pset_list = (mach_port_t *) addr;
355: *count = 1;
356:
357: return KERN_SUCCESS;
358: }
359: #endif /* MACH_HOST */
360:
361: /*
362: * host_processor_set_priv:
363: *
364: * Return control port for given processor set.
365: */
366: kern_return_t
367: host_processor_set_priv(
368: host_t host,
369: processor_set_t pset_name,
370: processor_set_t *pset)
371: {
372: if ((host == HOST_NULL) || (pset_name == PROCESSOR_SET_NULL)) {
373: *pset = PROCESSOR_SET_NULL;
374: return KERN_INVALID_ARGUMENT;
375: }
376:
377: *pset = pset_name;
378: pset_reference(*pset);
379: return KERN_SUCCESS;
380: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.