Annotation of kernel/kern/host.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.