Annotation of OSKit-Mach/kern/priority.c, revision 1.1

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

unix.superglobalmegacorp.com

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