|
|
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.