mach_factor.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 Software.Distribution@CS.CMU.EDU
  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. #include <mach/machine.h>
  34. #include <mach/processor_info.h>
  35. #include <kern/mach_clock.h>
  36. #include <kern/sched.h>
  37. #include <kern/processor.h>
  38. #include <mach/kern_return.h>
  39. #include <mach/port.h>
  40. #include "mach_factor.h"
  41. long avenrun[3] = {0, 0, 0};
  42. long mach_factor[3] = {0, 0, 0};
  43. /*
  44. * Values are scaled by LOAD_SCALE, defined in processor_info.h
  45. */
  46. static long fract[3] = {
  47. 800, /* (4.0/5.0) 5 second average */
  48. 966, /* (29.0/30.0) 30 second average */
  49. 983, /* (59.0/60.) 1 minute average */
  50. };
  51. void compute_mach_factor(void)
  52. {
  53. processor_set_t pset;
  54. processor_t processor;
  55. int ncpus;
  56. int nthreads;
  57. long factor_now;
  58. long average_now;
  59. long load_now;
  60. simple_lock(&all_psets_lock);
  61. pset = (processor_set_t) queue_first(&all_psets);
  62. while (!queue_end(&all_psets, (queue_entry_t)pset)) {
  63. /*
  64. * If no processors, this pset is in suspended animation.
  65. * No load calculations are performed.
  66. */
  67. pset_lock(pset);
  68. if((ncpus = pset->processor_count) > 0) {
  69. /*
  70. * Count number of threads.
  71. */
  72. nthreads = pset->runq.count;
  73. processor = (processor_t) queue_first(&pset->processors);
  74. while (!queue_end(&pset->processors,
  75. (queue_entry_t)processor)) {
  76. nthreads += processor->runq.count;
  77. processor =
  78. (processor_t) queue_next(&processor->processors);
  79. }
  80. /*
  81. * account for threads on cpus.
  82. */
  83. nthreads += ncpus - pset->idle_count;
  84. /*
  85. * The current thread (running this calculation)
  86. * doesn't count; it's always in the default pset.
  87. */
  88. if (pset == &default_pset)
  89. nthreads -= 1;
  90. if (nthreads > ncpus) {
  91. factor_now = (ncpus * LOAD_SCALE) / (nthreads + 1);
  92. load_now = (nthreads << SCHED_SHIFT) / ncpus;
  93. }
  94. else {
  95. factor_now = (ncpus - nthreads) * LOAD_SCALE;
  96. load_now = SCHED_SCALE;
  97. }
  98. /*
  99. * Load average and mach factor calculations for
  100. * those that ask about these things.
  101. */
  102. average_now = nthreads * LOAD_SCALE;
  103. pset->mach_factor =
  104. ((pset->mach_factor << 2) + factor_now)/5;
  105. pset->load_average =
  106. ((pset->load_average << 2) + average_now)/5;
  107. /*
  108. * And some ugly stuff to keep w happy.
  109. */
  110. if (pset == &default_pset) {
  111. int i;
  112. for (i = 0; i < 3; i++) {
  113. mach_factor[i] = ( (mach_factor[i]*fract[i])
  114. + (factor_now*(LOAD_SCALE-fract[i])) )
  115. / LOAD_SCALE;
  116. avenrun[i] = ( (avenrun[i]*fract[i])
  117. + (average_now*(LOAD_SCALE-fract[i])) )
  118. / LOAD_SCALE;
  119. }
  120. }
  121. /*
  122. * sched_load is the only thing used by scheduler.
  123. * It is always at least 1 (i.e. SCHED_SCALE).
  124. */
  125. pset->sched_load = (pset->sched_load + load_now) >> 1;
  126. }
  127. pset_unlock(pset);
  128. pset = (processor_set_t) queue_next(&pset->all_psets);
  129. }
  130. simple_unlock(&all_psets_lock);
  131. }