Annotation of kernel/kern/priority.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.