X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..55e303ae13a4cf49d70f2294092726f2fffb9ef2:/osfmk/kern/mach_factor.c diff --git a/osfmk/kern/mach_factor.c b/osfmk/kern/mach_factor.c index 14eba5e2b..77671e043 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,8 +73,8 @@ #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 @@ -79,74 +82,61 @@ integer_t mach_factor[3] = {0, 0, 0}; #define base(n) ((n) << SCHED_TICK_SHIFT) #define frac(n) (((base(n) - 1) * LOAD_SCALE) / base(n)) -static long fract[3] = { +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 processor_set_t pset = &default_pset; register int ncpus; - register int nthreads; - register long factor_now = 0L; - register long average_now = 0L; - register long load_now = 0L; + register int nthreads, nshared; + 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. + * Retrieve thread counts. */ - 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); - } + nthreads = pset->run_count; + nshared = pset->share_count; /* - * account for threads on cpus. + * Don't include the current thread. */ - nthreads += ncpus - pset->idle_count; + nthreads -= 1; /* - * The current thread (running this calculation) - * doesn't count; it's always in the default pset. + * Load average and mach factor calculations for + * those which ask about these things. */ - if (pset == &default_pset) - nthreads -= 1; + average_now = nthreads * LOAD_SCALE; - 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; - - /* - * Load average and mach factor calculations for - * those that ask about these things. - */ - - average_now = (nthreads * LOAD_SCALE) / ncpus; - 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. + * Compute the load factor used by the timesharing + * algorithm. */ + if (nshared > nthreads) + nshared = nthreads; + + if (nshared > ncpus) + load_now = (nshared << SCHED_SHIFT) / ncpus; + pset->sched_load = (pset->sched_load + load_now) >> 1; } else { @@ -154,13 +144,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]) + @@ -170,4 +158,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; + } }