X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..43866e378188c25dd1e2208016ab3cbeb086ae6c:/osfmk/kern/mach_factor.c diff --git a/osfmk/kern/mach_factor.c b/osfmk/kern/mach_factor.c index eca59d7c6..47a8b3e25 100644 --- a/osfmk/kern/mach_factor.c +++ b/osfmk/kern/mach_factor.c @@ -3,19 +3,22 @@ * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -70,47 +73,40 @@ #include #endif /* MACH_KERNEL */ -integer_t avenrun[3] = {0, 0, 0}; -integer_t mach_factor[3] = {0, 0, 0}; +uint32_t avenrun[3] = {0, 0, 0}; +uint32_t 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 */ +#define base(n) ((n) << SCHED_TICK_SHIFT) +#define frac(n) (((base(n) - 1) * LOAD_SCALE) / base(n)) + +static uint32_t fract[3] = { + frac(5), /* 5 second average */ + frac(30), /* 30 second average */ + frac(60), /* 1 minute average */ }; +#undef base +#undef frac + void compute_mach_factor(void) { register processor_set_t pset; - register processor_t processor; register int ncpus; register int nthreads; - register long factor_now = 0L; - register long average_now = 0L; - register long load_now = 0L; + register uint32_t factor_now = 0; + register uint32_t average_now = 0; + register uint32_t load_now = 0; pset = &default_pset; - simple_lock(&pset->processors_lock); if ((ncpus = pset->processor_count) > 0) { /* - * Count number of threads. + * Number of threads running in pset. */ - 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; + nthreads = pset->run_count; /* * The current thread (running this calculation) @@ -119,28 +115,24 @@ compute_mach_factor(void) if (pset == &default_pset) nthreads -= 1; - if (nthreads >= ncpus) + if (nthreads > ncpus) { factor_now = (ncpus * LOAD_SCALE) / (nthreads + 1); - else - factor_now = (ncpus - nthreads) * LOAD_SCALE; - - if (nthreads > ncpus) load_now = (nthreads << SCHED_SHIFT) / ncpus; + } else - load_now = 0; + factor_now = (ncpus - nthreads) * LOAD_SCALE; /* * Load average and mach factor calculations for * those that ask about these things. */ - - average_now = (nthreads * LOAD_SCALE) / ncpus; + 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; /* - * sched_load is the only thing used by scheduler. + * sched_load is used by the timesharing algorithm. */ pset->sched_load = (pset->sched_load + load_now) >> 1; } @@ -149,13 +141,11 @@ compute_mach_factor(void) pset->sched_load = 0; } - simple_unlock(&pset->processors_lock); - /* - * And some ugly stuff to keep w happy. + * Compute old-style Mach load averages. */ { - register int i; + register int i; for (i = 0; i < 3; i++) { mach_factor[i] = ((mach_factor[i] * fract[i]) + @@ -165,4 +155,20 @@ compute_mach_factor(void) (average_now * (LOAD_SCALE - fract[i]))) / LOAD_SCALE; } } + + /* + * Call out to BSD for averunnable. + */ + { +#define AVGTICK_PERIOD (5 << SCHED_TICK_SHIFT) + static uint32_t avgtick_count; + extern void compute_averunnable( + int nrun); + + if (++avgtick_count == 1) + compute_averunnable(nthreads); + else + if (avgtick_count >= AVGTICK_PERIOD) + avgtick_count = 0; + } }