|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990,1989,1988,1987 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: * File: kern/mach_factor.c ! 28: * Author: Avadis Tevanian, Jr. ! 29: * Date: 1986 ! 30: * ! 31: * Compute the Mach Factor. ! 32: */ ! 33: ! 34: #include <cpus.h> ! 35: ! 36: #include <mach/machine.h> ! 37: #include <mach/processor_info.h> ! 38: #include <kern/sched.h> ! 39: #include <kern/processor.h> ! 40: #include <kern/time_out.h> ! 41: #if MACH_KERNEL ! 42: #include <mach/kern_return.h> ! 43: #include <mach/port.h> ! 44: #endif MACH_KERNEL ! 45: ! 46: ! 47: long avenrun[3] = {0, 0, 0}; ! 48: long mach_factor[3] = {0, 0, 0}; ! 49: ! 50: /* ! 51: * Values are scaled by LOAD_SCALE, defined in processor_info.h ! 52: */ ! 53: static long fract[3] = { ! 54: 800, /* (4.0/5.0) 5 second average */ ! 55: 966, /* (29.0/30.0) 30 second average */ ! 56: 983, /* (59.0/60.) 1 minute average */ ! 57: }; ! 58: ! 59: void compute_mach_factor() ! 60: { ! 61: register processor_set_t pset; ! 62: register processor_t processor; ! 63: register int ncpus; ! 64: register int nthreads; ! 65: register long factor_now; ! 66: register long average_now; ! 67: register long load_now; ! 68: ! 69: simple_lock(&all_psets_lock); ! 70: pset = (processor_set_t) queue_first(&all_psets); ! 71: while (!queue_end(&all_psets, (queue_entry_t)pset)) { ! 72: ! 73: /* ! 74: * If no processors, this pset is in suspended animation. ! 75: * No load calculations are performed. ! 76: */ ! 77: pset_lock(pset); ! 78: if((ncpus = pset->processor_count) > 0) { ! 79: ! 80: /* ! 81: * Count number of threads. ! 82: */ ! 83: nthreads = pset->runq.count; ! 84: processor = (processor_t) queue_first(&pset->processors); ! 85: while (!queue_end(&pset->processors, ! 86: (queue_entry_t)processor)) { ! 87: nthreads += processor->runq.count; ! 88: processor = ! 89: (processor_t) queue_next(&processor->processors); ! 90: } ! 91: ! 92: /* ! 93: * account for threads on cpus. ! 94: */ ! 95: nthreads += ncpus - pset->idle_count; ! 96: ! 97: /* ! 98: * The current thread (running this calculation) ! 99: * doesn't count; it's always in the default pset. ! 100: */ ! 101: if (pset == &default_pset) ! 102: nthreads -= 1; ! 103: ! 104: if (nthreads > ncpus) { ! 105: factor_now = (ncpus * LOAD_SCALE) / (nthreads + 1); ! 106: load_now = (nthreads << SCHED_SHIFT) / ncpus; ! 107: } ! 108: else { ! 109: factor_now = (ncpus - nthreads) * LOAD_SCALE; ! 110: load_now = SCHED_SCALE; ! 111: } ! 112: ! 113: /* ! 114: * Load average and mach factor calculations for ! 115: * those that ask about these things. ! 116: */ ! 117: ! 118: average_now = nthreads * LOAD_SCALE; ! 119: ! 120: pset->mach_factor = ! 121: ((pset->mach_factor << 2) + factor_now)/5; ! 122: pset->load_average = ! 123: ((pset->load_average << 2) + average_now)/5; ! 124: ! 125: /* ! 126: * And some ugly stuff to keep w happy. ! 127: */ ! 128: if (pset == &default_pset) { ! 129: register int i; ! 130: ! 131: for (i = 0; i < 3; i++) { ! 132: mach_factor[i] = ( (mach_factor[i]*fract[i]) ! 133: + (factor_now*(LOAD_SCALE-fract[i])) ) ! 134: / LOAD_SCALE; ! 135: avenrun[i] = ( (avenrun[i]*fract[i]) ! 136: + (average_now*(LOAD_SCALE-fract[i])) ) ! 137: / LOAD_SCALE; ! 138: } ! 139: } ! 140: ! 141: /* ! 142: * sched_load is the only thing used by scheduler. ! 143: * It is always at least 1 (i.e. SCHED_SCALE). ! 144: */ ! 145: pset->sched_load = (pset->sched_load + load_now) >> 1; ! 146: } ! 147: ! 148: pset_unlock(pset); ! 149: pset = (processor_set_t) queue_next(&pset->all_psets); ! 150: } ! 151: ! 152: simple_unlock(&all_psets_lock); ! 153: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.