123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- /*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988,1987 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.
- */
- /*
- * File: kern/mach_factor.c
- * Author: Avadis Tevanian, Jr.
- * Date: 1986
- *
- * Compute the Mach Factor.
- */
- #include <mach/machine.h>
- #include <mach/processor_info.h>
- #include <kern/mach_clock.h>
- #include <kern/sched.h>
- #include <kern/processor.h>
- #include <mach/kern_return.h>
- #include <mach/port.h>
- #include "mach_factor.h"
- long avenrun[3] = {0, 0, 0};
- long mach_factor[3] = {0, 0, 0};
- /*
- * Values are scaled by LOAD_SCALE, defined in processor_info.h
- */
- static long fract[3] = {
- 800, /* (4.0/5.0) 5 second average */
- 966, /* (29.0/30.0) 30 second average */
- 983, /* (59.0/60.) 1 minute average */
- };
- void compute_mach_factor(void)
- {
- processor_set_t pset;
- processor_t processor;
- int ncpus;
- int nthreads;
- long factor_now;
- long average_now;
- long load_now;
- simple_lock(&all_psets_lock);
- pset = (processor_set_t) queue_first(&all_psets);
- while (!queue_end(&all_psets, (queue_entry_t)pset)) {
- /*
- * If no processors, this pset is in suspended animation.
- * No load calculations are performed.
- */
- pset_lock(pset);
- if((ncpus = pset->processor_count) > 0) {
- /*
- * Count number of threads.
- */
- nthreads = pset->runq.count;
- processor = (processor_t) queue_first(&pset->processors);
- while (!queue_end(&pset->processors,
- (queue_entry_t)processor)) {
- nthreads += processor->runq.count;
- processor =
- (processor_t) queue_next(&processor->processors);
- }
- /*
- * account for threads on cpus.
- */
- nthreads += ncpus - pset->idle_count;
- /*
- * The current thread (running this calculation)
- * doesn't count; it's always in the default pset.
- */
- if (pset == &default_pset)
- nthreads -= 1;
- if (nthreads > ncpus) {
- factor_now = (ncpus * LOAD_SCALE) / (nthreads + 1);
- load_now = (nthreads << SCHED_SHIFT) / ncpus;
- }
- else {
- factor_now = (ncpus - nthreads) * LOAD_SCALE;
- load_now = SCHED_SCALE;
- }
- /*
- * Load average and mach factor calculations for
- * those that ask about these things.
- */
- average_now = nthreads * LOAD_SCALE;
- pset->mach_factor =
- ((pset->mach_factor << 2) + factor_now)/5;
- pset->load_average =
- ((pset->load_average << 2) + average_now)/5;
- /*
- * And some ugly stuff to keep w happy.
- */
- if (pset == &default_pset) {
- int i;
- for (i = 0; i < 3; i++) {
- mach_factor[i] = ( (mach_factor[i]*fract[i])
- + (factor_now*(LOAD_SCALE-fract[i])) )
- / LOAD_SCALE;
- avenrun[i] = ( (avenrun[i]*fract[i])
- + (average_now*(LOAD_SCALE-fract[i])) )
- / LOAD_SCALE;
- }
- }
- /*
- * sched_load is the only thing used by scheduler.
- * It is always at least 1 (i.e. SCHED_SCALE).
- */
- pset->sched_load = (pset->sched_load + load_now) >> 1;
- }
- pset_unlock(pset);
- pset = (processor_set_t) queue_next(&pset->all_psets);
- }
- simple_unlock(&all_psets_lock);
- }
|