123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- /*
- * Mach Operating System
- * Copyright (c) 1993,1992,1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
- /*
- * host.c
- *
- * Non-ipc host functions.
- */
- #include <string.h>
- #include <kern/assert.h>
- #include <kern/debug.h>
- #include <kern/kalloc.h>
- #include <kern/host.h>
- #include <mach/host_info.h>
- #include <mach/kern_return.h>
- #include <mach/machine.h>
- #include <mach/port.h>
- #include <kern/processor.h>
- #include <kern/ipc_host.h>
- #include <kern/mach_clock.h>
- #include <mach/vm_param.h>
- host_data_t realhost;
- kern_return_t host_processors(
- const host_t host,
- processor_array_t *processor_list,
- natural_t *countp)
- {
- unsigned i;
- processor_t *tp;
- vm_offset_t addr;
- unsigned int count;
- if (host == HOST_NULL)
- return KERN_INVALID_ARGUMENT;
- /*
- * Determine how many processors we have.
- * (This number shouldn't change.)
- */
- count = 0;
- for (i = 0; i < NCPUS; i++)
- if (machine_slot[i].is_cpu)
- count++;
- if (count == 0)
- panic("host_processors");
- addr = kalloc((vm_size_t) (count * sizeof(mach_port_t)));
- if (addr == 0)
- return KERN_RESOURCE_SHORTAGE;
- tp = (processor_t *) addr;
- for (i = 0; i < NCPUS; i++)
- if (machine_slot[i].is_cpu)
- *tp++ = cpu_to_processor(i);
- *countp = count;
- *processor_list = (mach_port_t *) addr;
- /* do the conversion that Mig should handle */
- tp = (processor_t *) addr;
- for (i = 0; i < count; i++)
- ((mach_port_t *) tp)[i] =
- (mach_port_t)convert_processor_to_port(tp[i]);
- return KERN_SUCCESS;
- }
- kern_return_t host_info(
- const host_t host,
- int flavor,
- host_info_t info,
- natural_t *count)
- {
- integer_t i, *slot_ptr;
- if (host == HOST_NULL)
- return KERN_INVALID_ARGUMENT;
-
- switch(flavor) {
- case HOST_BASIC_INFO:
- {
- host_basic_info_t basic_info;
- /*
- * Basic information about this host.
- */
- if (*count < HOST_BASIC_INFO_COUNT)
- return KERN_FAILURE;
- basic_info = (host_basic_info_t) info;
- basic_info->max_cpus = machine_info.max_cpus;
- basic_info->avail_cpus = machine_info.avail_cpus;
- basic_info->memory_size = machine_info.memory_size;
- basic_info->cpu_type =
- machine_slot[master_processor->slot_num].cpu_type;
- basic_info->cpu_subtype =
- machine_slot[master_processor->slot_num].cpu_subtype;
- *count = HOST_BASIC_INFO_COUNT;
- return KERN_SUCCESS;
- }
- case HOST_PROCESSOR_SLOTS:
- /*
- * Return numbers of slots with active processors
- * in them.
- */
- if (*count < NCPUS)
- return KERN_INVALID_ARGUMENT;
- slot_ptr = (integer_t *)info;
- *count = 0;
- for (i = 0; i < NCPUS; i++) {
- if (machine_slot[i].is_cpu &&
- machine_slot[i].running) {
- *slot_ptr++ = i;
- (*count)++;
- }
- }
- return KERN_SUCCESS;
- case HOST_SCHED_INFO:
- {
- host_sched_info_t sched_info;
- extern int min_quantum;
- /* minimum quantum, in ticks */
- /*
- * Return scheduler information.
- */
- if (*count < HOST_SCHED_INFO_COUNT)
- return(KERN_FAILURE);
- sched_info = (host_sched_info_t) info;
- sched_info->min_timeout = tick / 1000;
- /* convert microseconds to milliseconds */
- sched_info->min_quantum = min_quantum * tick / 1000;
- /* convert ticks to milliseconds */
- *count = HOST_SCHED_INFO_COUNT;
- return KERN_SUCCESS;
- }
- case HOST_LOAD_INFO:
- {
- host_load_info_t load_info;
- extern long avenrun[3], mach_factor[3];
- if (*count < HOST_LOAD_INFO_COUNT)
- return KERN_FAILURE;
- load_info = (host_load_info_t) info;
- memcpy(load_info->avenrun,
- avenrun,
- sizeof avenrun);
- memcpy(load_info->mach_factor,
- mach_factor,
- sizeof mach_factor);
- *count = HOST_LOAD_INFO_COUNT;
- return KERN_SUCCESS;
- }
- default:
- return KERN_INVALID_ARGUMENT;
- }
- }
- /*
- * Return kernel version string (more than you ever
- * wanted to know about what version of the kernel this is).
- */
- kern_return_t host_kernel_version(
- const host_t host,
- kernel_version_t out_version)
- {
- extern char version[];
- if (host == HOST_NULL)
- return KERN_INVALID_ARGUMENT;
- (void) strncpy(out_version, version, sizeof(kernel_version_t));
- return KERN_SUCCESS;
- }
- /*
- * host_processor_sets:
- *
- * List all processor sets on the host.
- */
- #if MACH_HOST
- kern_return_t
- host_processor_sets(
- const host_t host,
- processor_set_name_array_t *pset_list,
- natural_t *count)
- {
- unsigned int actual; /* this many psets */
- processor_set_t pset;
- processor_set_t *psets;
- int i;
- vm_size_t size;
- vm_size_t size_needed;
- vm_offset_t addr;
- if (host == HOST_NULL)
- return KERN_INVALID_ARGUMENT;
- size = 0; addr = 0;
- for (;;) {
- simple_lock(&all_psets_lock);
- actual = all_psets_count;
- /* do we have the memory we need? */
- size_needed = actual * sizeof(mach_port_t);
- if (size_needed <= size)
- break;
- /* unlock and allocate more memory */
- simple_unlock(&all_psets_lock);
- if (size != 0)
- kfree(addr, size);
- assert(size_needed > 0);
- size = size_needed;
- addr = kalloc(size);
- if (addr == 0)
- return KERN_RESOURCE_SHORTAGE;
- }
- /* OK, have memory and the all_psets_lock */
- psets = (processor_set_t *) addr;
- for (i = 0, pset = (processor_set_t) queue_first(&all_psets);
- i < actual;
- i++, pset = (processor_set_t) queue_next(&pset->all_psets)) {
- /* take ref for convert_pset_name_to_port */
- pset_reference(pset);
- psets[i] = pset;
- }
- assert(queue_end(&all_psets, (queue_entry_t) pset));
- /* can unlock now that we've got the pset refs */
- simple_unlock(&all_psets_lock);
- /*
- * Always have default port.
- */
- assert(actual > 0);
- /* if we allocated too much, must copy */
- if (size_needed < size) {
- vm_offset_t newaddr;
- newaddr = kalloc(size_needed);
- if (newaddr == 0) {
- for (i = 0; i < actual; i++)
- pset_deallocate(psets[i]);
- kfree(addr, size);
- return KERN_RESOURCE_SHORTAGE;
- }
- memcpy((void *) newaddr, (void *) addr, size_needed);
- kfree(addr, size);
- psets = (processor_set_t *) newaddr;
- }
- *pset_list = (mach_port_t *) psets;
- *count = actual;
- /* do the conversion that Mig should handle */
- for (i = 0; i < actual; i++)
- ((mach_port_t *) psets)[i] =
- (mach_port_t)convert_pset_name_to_port(psets[i]);
- return KERN_SUCCESS;
- }
- #else /* MACH_HOST */
- /*
- * Only one processor set, the default processor set, in this case.
- */
- kern_return_t
- host_processor_sets(
- const host_t host,
- processor_set_name_array_t *pset_list,
- natural_t *count)
- {
- vm_offset_t addr;
- if (host == HOST_NULL)
- return KERN_INVALID_ARGUMENT;
- /*
- * Allocate memory. Can be pageable because it won't be
- * touched while holding a lock.
- */
- addr = kalloc((vm_size_t) sizeof(mach_port_t));
- if (addr == 0)
- return KERN_RESOURCE_SHORTAGE;
- /* take for for convert_pset_name_to_port */
- pset_reference(&default_pset);
- /* do the conversion that Mig should handle */
- *((mach_port_t *) addr) =
- (mach_port_t) convert_pset_name_to_port(&default_pset);
- *pset_list = (mach_port_t *) addr;
- *count = 1;
- return KERN_SUCCESS;
- }
- #endif /* MACH_HOST */
- /*
- * host_processor_set_priv:
- *
- * Return control port for given processor set.
- */
- kern_return_t
- host_processor_set_priv(
- const host_t host,
- processor_set_t pset_name,
- processor_set_t *pset)
- {
- if ((host == HOST_NULL) || (pset_name == PROCESSOR_SET_NULL)) {
- *pset = PROCESSOR_SET_NULL;
- return KERN_INVALID_ARGUMENT;
- }
- *pset = pset_name;
- pset_reference(*pset);
- return KERN_SUCCESS;
- }
|