|
|
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:
1.1.1.2 root 32: #include <string.h>
1.1 root 33:
34: #include <kern/assert.h>
1.1.1.2 root 35: #include <kern/debug.h>
1.1 root 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>
1.1.1.2 root 44: #include <kern/mach_clock.h>
1.1 root 45: #include <mach/vm_param.h>
46:
47: host_data_t realhost;
48:
49: kern_return_t host_processors(
1.1.1.3 ! root 50: const host_t host,
1.1 root 51: processor_array_t *processor_list,
52: natural_t *countp)
53: {
1.1.1.3 ! root 54: int i;
! 55: processor_t *tp;
1.1 root 56: vm_offset_t addr;
57: unsigned int count;
58:
59: if (host == HOST_NULL)
60: return KERN_INVALID_ARGUMENT;
61:
62: /*
63: * Determine how many processors we have.
64: * (This number shouldn't change.)
65: */
66:
67: count = 0;
68: for (i = 0; i < NCPUS; i++)
69: if (machine_slot[i].is_cpu)
70: count++;
71:
72: if (count == 0)
73: panic("host_processors");
74:
75: addr = kalloc((vm_size_t) (count * sizeof(mach_port_t)));
76: if (addr == 0)
77: return KERN_RESOURCE_SHORTAGE;
78:
79: tp = (processor_t *) addr;
80: for (i = 0; i < NCPUS; i++)
81: if (machine_slot[i].is_cpu)
82: *tp++ = cpu_to_processor(i);
83:
84: *countp = count;
85: *processor_list = (mach_port_t *) addr;
86:
87: /* do the conversion that Mig should handle */
88:
89: tp = (processor_t *) addr;
90: for (i = 0; i < count; i++)
91: ((mach_port_t *) tp)[i] =
92: (mach_port_t)convert_processor_to_port(tp[i]);
93:
94: return KERN_SUCCESS;
95: }
96:
97: kern_return_t host_info(
1.1.1.3 ! root 98: const host_t host,
1.1 root 99: int flavor,
100: host_info_t info,
101: natural_t *count)
102: {
1.1.1.3 ! root 103: integer_t i, *slot_ptr;
1.1 root 104:
105: if (host == HOST_NULL)
106: return KERN_INVALID_ARGUMENT;
107:
108: switch(flavor) {
109:
110: case HOST_BASIC_INFO:
111: {
1.1.1.3 ! root 112: host_basic_info_t basic_info;
1.1 root 113:
114: /*
115: * Basic information about this host.
116: */
117: if (*count < HOST_BASIC_INFO_COUNT)
118: return KERN_FAILURE;
119:
120: basic_info = (host_basic_info_t) info;
121:
122: basic_info->max_cpus = machine_info.max_cpus;
123: basic_info->avail_cpus = machine_info.avail_cpus;
124: basic_info->memory_size = machine_info.memory_size;
125: basic_info->cpu_type =
126: machine_slot[master_processor->slot_num].cpu_type;
127: basic_info->cpu_subtype =
128: machine_slot[master_processor->slot_num].cpu_subtype;
129:
130: *count = HOST_BASIC_INFO_COUNT;
131: return KERN_SUCCESS;
132: }
133:
134: case HOST_PROCESSOR_SLOTS:
135: /*
136: * Return numbers of slots with active processors
137: * in them.
138: */
139: if (*count < NCPUS)
140: return KERN_INVALID_ARGUMENT;
141:
142: slot_ptr = (integer_t *)info;
143: *count = 0;
144: for (i = 0; i < NCPUS; i++) {
145: if (machine_slot[i].is_cpu &&
146: machine_slot[i].running) {
147: *slot_ptr++ = i;
148: (*count)++;
149: }
150: }
151: return KERN_SUCCESS;
152:
153: case HOST_SCHED_INFO:
154: {
1.1.1.3 ! root 155: host_sched_info_t sched_info;
1.1 root 156: extern int min_quantum;
157: /* minimum quantum, in microseconds */
158:
159: /*
160: * Return scheduler information.
161: */
162: if (*count < HOST_SCHED_INFO_COUNT)
163: return(KERN_FAILURE);
164:
165: sched_info = (host_sched_info_t) info;
166:
167: sched_info->min_timeout = tick / 1000;
168: sched_info->min_quantum = min_quantum / 1000;
169: /* convert microseconds to milliseconds */
170:
171: *count = HOST_SCHED_INFO_COUNT;
172: return KERN_SUCCESS;
173: }
174:
175: case HOST_LOAD_INFO:
176: {
1.1.1.3 ! root 177: host_load_info_t load_info;
1.1 root 178: extern long avenrun[3], mach_factor[3];
179:
180: if (*count < HOST_LOAD_INFO_COUNT)
181: return KERN_FAILURE;
182:
183: load_info = (host_load_info_t) info;
184:
1.1.1.2 root 185: memcpy(load_info->avenrun,
186: avenrun,
187: sizeof avenrun);
188: memcpy(load_info->mach_factor,
189: mach_factor,
190: sizeof mach_factor);
1.1 root 191:
192: *count = HOST_LOAD_INFO_COUNT;
193: return KERN_SUCCESS;
194: }
195:
196: default:
197: return KERN_INVALID_ARGUMENT;
198: }
199: }
200:
201: /*
202: * Return kernel version string (more than you ever
203: * wanted to know about what version of the kernel this is).
204: */
205:
206: kern_return_t host_kernel_version(
1.1.1.3 ! root 207: const host_t host,
1.1 root 208: kernel_version_t out_version)
209: {
210: extern char version[];
211:
212: if (host == HOST_NULL)
213: return KERN_INVALID_ARGUMENT;
214:
215: (void) strncpy(out_version, version, sizeof(kernel_version_t));
216:
217: return KERN_SUCCESS;
218: }
219:
220: /*
221: * host_processor_sets:
222: *
223: * List all processor sets on the host.
224: */
225: #if MACH_HOST
226: kern_return_t
227: host_processor_sets(
1.1.1.3 ! root 228: const host_t host,
1.1 root 229: processor_set_name_array_t *pset_list,
230: natural_t *count)
231: {
232: unsigned int actual; /* this many psets */
233: processor_set_t pset;
234: processor_set_t *psets;
235: int i;
236:
237: vm_size_t size;
238: vm_size_t size_needed;
239: vm_offset_t addr;
240:
241: if (host == HOST_NULL)
242: return KERN_INVALID_ARGUMENT;
243:
244: size = 0; addr = 0;
245:
246: for (;;) {
247: simple_lock(&all_psets_lock);
248: actual = all_psets_count;
249:
250: /* do we have the memory we need? */
251:
252: size_needed = actual * sizeof(mach_port_t);
253: if (size_needed <= size)
254: break;
255:
256: /* unlock and allocate more memory */
257: simple_unlock(&all_psets_lock);
258:
259: if (size != 0)
260: kfree(addr, size);
261:
262: assert(size_needed > 0);
263: size = size_needed;
264:
265: addr = kalloc(size);
266: if (addr == 0)
267: return KERN_RESOURCE_SHORTAGE;
268: }
269:
270: /* OK, have memory and the all_psets_lock */
271:
272: psets = (processor_set_t *) addr;
273:
274: for (i = 0, pset = (processor_set_t) queue_first(&all_psets);
275: i < actual;
276: i++, pset = (processor_set_t) queue_next(&pset->all_psets)) {
277: /* take ref for convert_pset_name_to_port */
278: pset_reference(pset);
279: psets[i] = pset;
280: }
281: assert(queue_end(&all_psets, (queue_entry_t) pset));
282:
283: /* can unlock now that we've got the pset refs */
284: simple_unlock(&all_psets_lock);
285:
286: /*
287: * Always have default port.
288: */
289:
290: assert(actual > 0);
291:
292: /* if we allocated too much, must copy */
293:
294: if (size_needed < size) {
295: vm_offset_t newaddr;
296:
297: newaddr = kalloc(size_needed);
298: if (newaddr == 0) {
299: for (i = 0; i < actual; i++)
300: pset_deallocate(psets[i]);
301: kfree(addr, size);
302: return KERN_RESOURCE_SHORTAGE;
303: }
304:
1.1.1.3 ! root 305: memcpy((void *) newaddr, (void *) addr, size_needed);
1.1 root 306: kfree(addr, size);
307: psets = (processor_set_t *) newaddr;
308: }
309:
310: *pset_list = (mach_port_t *) psets;
311: *count = actual;
312:
313: /* do the conversion that Mig should handle */
314:
315: for (i = 0; i < actual; i++)
316: ((mach_port_t *) psets)[i] =
317: (mach_port_t)convert_pset_name_to_port(psets[i]);
318:
319: return KERN_SUCCESS;
320: }
321: #else /* MACH_HOST */
322: /*
323: * Only one processor set, the default processor set, in this case.
324: */
325: kern_return_t
326: host_processor_sets(
1.1.1.3 ! root 327: const host_t host,
1.1 root 328: processor_set_name_array_t *pset_list,
329: natural_t *count)
330: {
331: vm_offset_t addr;
332:
333: if (host == HOST_NULL)
334: return KERN_INVALID_ARGUMENT;
335:
336: /*
337: * Allocate memory. Can be pageable because it won't be
338: * touched while holding a lock.
339: */
340:
341: addr = kalloc((vm_size_t) sizeof(mach_port_t));
342: if (addr == 0)
343: return KERN_RESOURCE_SHORTAGE;
344:
345: /* take for for convert_pset_name_to_port */
346: pset_reference(&default_pset);
347: /* do the conversion that Mig should handle */
348: *((mach_port_t *) addr) =
349: (mach_port_t) convert_pset_name_to_port(&default_pset);
350:
351: *pset_list = (mach_port_t *) addr;
352: *count = 1;
353:
354: return KERN_SUCCESS;
355: }
356: #endif /* MACH_HOST */
357:
358: /*
359: * host_processor_set_priv:
360: *
361: * Return control port for given processor set.
362: */
363: kern_return_t
364: host_processor_set_priv(
1.1.1.3 ! root 365: const host_t host,
1.1 root 366: processor_set_t pset_name,
367: processor_set_t *pset)
368: {
369: if ((host == HOST_NULL) || (pset_name == PROCESSOR_SET_NULL)) {
370: *pset = PROCESSOR_SET_NULL;
371: return KERN_INVALID_ARGUMENT;
372: }
373:
374: *pset = pset_name;
375: pset_reference(*pset);
376: return KERN_SUCCESS;
377: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.