|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1993,1991,1990,1989,1988,1987 Carnegie Mellon University ! 28: * All Rights Reserved. ! 29: * ! 30: * Permission to use, copy, modify and distribute this software and its ! 31: * documentation is hereby granted, provided that both the copyright ! 32: * notice and this permission notice appear in all copies of the ! 33: * software, derivative works or modified versions, and any portions ! 34: * thereof, and that both notices appear in supporting documentation. ! 35: * ! 36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 39: * ! 40: * Carnegie Mellon requests users of this software to return to ! 41: * ! 42: * Software Distribution Coordinator or [email protected] ! 43: * School of Computer Science ! 44: * Carnegie Mellon University ! 45: * Pittsburgh PA 15213-3890 ! 46: * ! 47: * any improvements or extensions that they make and grant Carnegie Mellon ! 48: * the rights to redistribute these changes. ! 49: */ ! 50: /* ! 51: * File: clock_prim.c ! 52: * Author: Avadis Tevanian, Jr. ! 53: * Date: 1986 ! 54: * ! 55: * Clock primitives. ! 56: */ ! 57: ! 58: #include <cpus.h> ! 59: ! 60: #include <mach/boolean.h> ! 61: #include <mach/kern_return.h> ! 62: #include <mach/machine.h> ! 63: #include <kern/host.h> ! 64: #include <kern/mach_param.h> ! 65: #include <kern/sched.h> ! 66: #include <kern/thread.h> ! 67: #include <kern/time_out.h> ! 68: #include <kern/time_stamp.h> ! 69: #include <machine/machspl.h> ! 70: ! 71: ! 72: ! 73: /* ! 74: * USAGE_THRESHOLD is the amount by which usage must change to ! 75: * cause a priority shift that moves a thread between run queues. ! 76: */ ! 77: ! 78: #ifdef PRI_SHIFT_2 ! 79: #if PRI_SHIFT_2 > 0 ! 80: #define USAGE_THRESHOLD (((1 << PRI_SHIFT) + (1 << PRI_SHIFT_2)) << (2 + SCHED_SHIFT)) ! 81: #else /* PRI_SHIFT_2 > 0 */ ! 82: #define USAGE_THRESHOLD (((1 << PRI_SHIFT) - (1 << -(PRI_SHIFT_2))) << (2 + SCHED_SHIFT)) ! 83: #endif /* PRI_SHIFT_2 > 0 */ ! 84: #else /* PRI_SHIFT_2 */ ! 85: #define USAGE_THRESHOLD (1 << (PRI_SHIFT + 2 + SCHED_SHIFT)) ! 86: #endif /* PRI_SHIFT_2 */ ! 87: ! 88: /* ! 89: * thread_quantum_update: ! 90: * ! 91: * Recalculate the quantum and priority for a thread. ! 92: * The number of ticks that has elapsed since we were last called ! 93: * is passed as "nticks." ! 94: */ ! 95: ! 96: void thread_quantum_update(mycpu, thread, nticks, state) ! 97: register int mycpu; ! 98: register thread_t thread; ! 99: int nticks; ! 100: int state; ! 101: { ! 102: register int quantum; ! 103: register processor_t myprocessor; ! 104: #if NCPUS > 1 ! 105: register processor_set_t pset; ! 106: #endif ! 107: spl_t s; ! 108: ! 109: myprocessor = cpu_to_processor(mycpu); ! 110: #if NCPUS > 1 ! 111: pset = myprocessor->processor_set; ! 112: if (pset == 0) { ! 113: /* ! 114: * Processor is being reassigned. ! 115: * Should rewrite processor assignment code to ! 116: * block clock interrupts. ! 117: */ ! 118: return; ! 119: } ! 120: #endif /* NCPUS > 1 */ ! 121: ! 122: /* ! 123: * Account for thread's utilization of these ticks. ! 124: * This assumes that there is *always* a current thread. ! 125: * When the processor is idle, it should be the idle thread. ! 126: */ ! 127: ! 128: /* ! 129: * Update set_quantum and calculate the current quantum. ! 130: */ ! 131: #if NCPUS > 1 ! 132: pset->set_quantum = pset->machine_quantum[ ! 133: ((pset->runq.count > pset->processor_count) ? ! 134: pset->processor_count : pset->runq.count)]; ! 135: ! 136: if (myprocessor->runq.count != 0) ! 137: quantum = min_quantum; ! 138: else ! 139: quantum = pset->set_quantum; ! 140: #else /* NCPUS > 1 */ ! 141: quantum = min_quantum; ! 142: default_pset.set_quantum = quantum; ! 143: #endif /* NCPUS > 1 */ ! 144: ! 145: /* ! 146: * Now recompute the priority of the thread if appropriate. ! 147: */ ! 148: ! 149: if (state != CPU_STATE_IDLE) { ! 150: myprocessor->quantum -= nticks; ! 151: #if NCPUS > 1 ! 152: /* ! 153: * Runtime quantum adjustment. Use quantum_adj_index ! 154: * to avoid synchronizing quantum expirations. ! 155: */ ! 156: if ((quantum != myprocessor->last_quantum) && ! 157: (pset->processor_count > 1)) { ! 158: myprocessor->last_quantum = quantum; ! 159: simple_lock(&pset->quantum_adj_lock); ! 160: quantum = min_quantum + (pset->quantum_adj_index * ! 161: (quantum - min_quantum)) / ! 162: (pset->processor_count - 1); ! 163: if (++(pset->quantum_adj_index) >= ! 164: pset->processor_count) ! 165: pset->quantum_adj_index = 0; ! 166: simple_unlock(&pset->quantum_adj_lock); ! 167: } ! 168: #endif /* NCPUS > 1 */ ! 169: if (myprocessor->quantum <= 0) { ! 170: s = splsched(); ! 171: thread_lock(thread); ! 172: if (thread->sched_stamp != sched_tick) { ! 173: #if NCPUS > 1 ! 174: update_priority(thread); ! 175: #endif /* NCPUS > 1 */ ! 176: } ! 177: else { ! 178: if ( ! 179: #if MACH_FIXPRI ! 180: (thread->policy != POLICY_FIXEDPRI) && ! 181: #endif /* MACH_FIXPRI */ ! 182: (thread->depress_priority < 0)) { ! 183: thread_timer_delta(thread); ! 184: thread->sched_usage += ! 185: thread->sched_delta; ! 186: thread->sched_delta = 0; ! 187: compute_my_priority(thread); ! 188: } ! 189: } ! 190: thread_unlock(thread); ! 191: (void) splx(s); ! 192: /* ! 193: * This quantum is up, give this thread another. ! 194: */ ! 195: myprocessor->first_quantum = FALSE; ! 196: #if MACH_FIXPRI ! 197: if (thread->policy != POLICY_FIXEDPRI) { ! 198: #endif /* MACH_FIXPRI */ ! 199: myprocessor->quantum += quantum; ! 200: #if MACH_FIXPRI ! 201: } ! 202: else { ! 203: /* ! 204: * Fixed priority has per-thread quantum. ! 205: * ! 206: */ ! 207: myprocessor->quantum += thread->sched_data; ! 208: } ! 209: #endif /* MACH_FIXPRI */ ! 210: } ! 211: /* ! 212: * Recompute priority if appropriate. ! 213: */ ! 214: else { ! 215: s = splsched(); ! 216: thread_lock(thread); ! 217: if (thread->sched_stamp != sched_tick) { ! 218: #if NCPUS > 1 ! 219: update_priority(thread); ! 220: #endif /* NCPUS > 1 */ ! 221: } ! 222: else { ! 223: if ( ! 224: #if MACH_FIXPRI ! 225: (thread->policy != POLICY_FIXEDPRI) && ! 226: #endif /* MACH_FIXPRI */ ! 227: (thread->depress_priority < 0)) { ! 228: thread_timer_delta(thread); ! 229: if (thread->sched_delta >= USAGE_THRESHOLD) { ! 230: thread->sched_usage += ! 231: thread->sched_delta; ! 232: thread->sched_delta = 0; ! 233: compute_my_priority(thread); ! 234: } ! 235: } ! 236: } ! 237: thread_unlock(thread); ! 238: (void) splx(s); ! 239: } ! 240: /* ! 241: * Check for and schedule ast if needed. ! 242: */ ! 243: ast_check(); ! 244: } ! 245: } ! 246:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.