Annotation of Gnu-Mach/kern/priority.c, revision 1.1.1.3

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: /*
1.1.1.3 ! root       30:  *     File:   priority.c
1.1       root       31:  *     Author: Avadis Tevanian, Jr.
                     32:  *     Date:   1986
                     33:  *
                     34:  *     Clock primitives.
                     35:  */
                     36: 
                     37: #include <mach/boolean.h>
                     38: #include <mach/kern_return.h>
                     39: #include <mach/machine.h>
                     40: #include <kern/host.h>
1.1.1.2   root       41: #include <kern/mach_clock.h>
1.1       root       42: #include <kern/sched.h>
1.1.1.2   root       43: #include <kern/sched_prim.h>
1.1       root       44: #include <kern/thread.h>
                     45: #include <kern/processor.h>
                     46: #include <kern/timer.h>
                     47: #include <kern/time_stamp.h>
                     48: #include <machine/machspl.h>
                     49: 
                     50: 
                     51: 
                     52: /*
                     53:  *     USAGE_THRESHOLD is the amount by which usage must change to
                     54:  *     cause a priority shift that moves a thread between run queues.
                     55:  */
                     56: 
                     57: #ifdef PRI_SHIFT_2
                     58: #if    PRI_SHIFT_2 > 0
                     59: #define        USAGE_THRESHOLD (((1 << PRI_SHIFT) + (1 << PRI_SHIFT_2)) << (2 + SCHED_SHIFT))
                     60: #else  /* PRI_SHIFT_2 > 0 */
                     61: #define        USAGE_THRESHOLD (((1 << PRI_SHIFT) - (1 << -(PRI_SHIFT_2))) << (2 + SCHED_SHIFT))
                     62: #endif /* PRI_SHIFT_2 > 0 */
                     63: #else  /* PRI_SHIFT_2 */
                     64: #define USAGE_THRESHOLD        (1 << (PRI_SHIFT + 2 + SCHED_SHIFT))
                     65: #endif /* PRI_SHIFT_2 */
                     66: 
                     67: /*
                     68:  *     thread_quantum_update:
                     69:  *
                     70:  *     Recalculate the quantum and priority for a thread.
                     71:  *     The number of ticks that has elapsed since we were last called
                     72:  *     is passed as "nticks."
                     73:  *
                     74:  *     Called only from clock_interrupt().
                     75:  */
                     76: 
1.1.1.3 ! root       77: void thread_quantum_update(
        !            78:        int                     mycpu,
        !            79:        thread_t                thread,
        !            80:        int                     nticks,
        !            81:        int                     state)
1.1       root       82: {
1.1.1.3 ! root       83:        int                             quantum;
        !            84:        processor_t                     myprocessor;
1.1       root       85: #if    NCPUS > 1
1.1.1.3 ! root       86:        processor_set_t                 pset;
1.1       root       87: #endif
                     88:        spl_t                           s;
                     89: 
                     90:        myprocessor = cpu_to_processor(mycpu);
                     91: #if    NCPUS > 1
                     92:        pset = myprocessor->processor_set;
                     93:        if (pset == 0) {
                     94:            /*
                     95:             * Processor is being reassigned.
                     96:             * Should rewrite processor assignment code to
                     97:             * block clock interrupts.
                     98:             */
                     99:            return;
                    100:        }
                    101: #endif /* NCPUS > 1 */
                    102: 
                    103:        /*
                    104:         *      Account for thread's utilization of these ticks.
                    105:         *      This assumes that there is *always* a current thread.
                    106:         *      When the processor is idle, it should be the idle thread.
                    107:         */
                    108: 
                    109:        /*
                    110:         *      Update set_quantum and calculate the current quantum.
                    111:         */
                    112: #if    NCPUS > 1
                    113:        pset->set_quantum = pset->machine_quantum[
                    114:                ((pset->runq.count > pset->processor_count) ?
                    115:                  pset->processor_count : pset->runq.count)];
                    116: 
                    117:        if (myprocessor->runq.count != 0)
                    118:                quantum = min_quantum;
                    119:        else
                    120:                quantum = pset->set_quantum;
                    121: #else  /* NCPUS > 1 */
                    122:        quantum = min_quantum;
                    123:        default_pset.set_quantum = quantum;
                    124: #endif /* NCPUS > 1 */
                    125:                
                    126:        /*
                    127:         *      Now recompute the priority of the thread if appropriate.
                    128:         */
                    129: 
                    130:        if (state != CPU_STATE_IDLE) {
                    131:                myprocessor->quantum -= nticks;
                    132: #if    NCPUS > 1
                    133:                /*
                    134:                 *      Runtime quantum adjustment.  Use quantum_adj_index
                    135:                 *      to avoid synchronizing quantum expirations.
                    136:                 */
                    137:                if ((quantum != myprocessor->last_quantum) &&
                    138:                    (pset->processor_count > 1)) {
                    139:                        myprocessor->last_quantum = quantum;
                    140:                        simple_lock(&pset->quantum_adj_lock);
                    141:                        quantum = min_quantum + (pset->quantum_adj_index *
                    142:                                (quantum - min_quantum)) / 
                    143:                                        (pset->processor_count - 1);
                    144:                        if (++(pset->quantum_adj_index) >=
                    145:                            pset->processor_count)
                    146:                                pset->quantum_adj_index = 0;
                    147:                        simple_unlock(&pset->quantum_adj_lock);
                    148:                }
                    149: #endif /* NCPUS > 1 */
                    150:                if (myprocessor->quantum <= 0) {
                    151:                        s = splsched();
                    152:                        thread_lock(thread);
                    153:                        if (thread->sched_stamp != sched_tick) {
                    154:                                update_priority(thread);
                    155:                        }
                    156:                        else {
                    157:                            if (
                    158: #if    MACH_FIXPRI
                    159:                                (thread->policy == POLICY_TIMESHARE) &&
                    160: #endif /* MACH_FIXPRI */
                    161:                                (thread->depress_priority < 0)) {
                    162:                                    thread_timer_delta(thread);
                    163:                                    thread->sched_usage +=
                    164:                                        thread->sched_delta;
                    165:                                    thread->sched_delta = 0;
                    166:                                    compute_my_priority(thread);
                    167:                            }
                    168:                        }
                    169:                        thread_unlock(thread);
                    170:                        (void) splx(s);
                    171:                        /*
                    172:                         *      This quantum is up, give this thread another.
                    173:                         */
                    174:                        myprocessor->first_quantum = FALSE;
                    175: #if    MACH_FIXPRI
                    176:                        if (thread->policy == POLICY_TIMESHARE) {
                    177: #endif /* MACH_FIXPRI */
                    178:                                myprocessor->quantum += quantum;
                    179: #if    MACH_FIXPRI
                    180:                        }
                    181:                        else {
                    182:                                /*
                    183:                                 *    Fixed priority has per-thread quantum.
                    184:                                 *    
                    185:                                 */
                    186:                                myprocessor->quantum += thread->sched_data;
                    187:                        }
                    188: #endif /* MACH_FIXPRI */
                    189:                }
                    190:                /*
                    191:                 *      Recompute priority if appropriate.
                    192:                 */
                    193:                else {
                    194:                    s = splsched();
                    195:                    thread_lock(thread);
                    196:                    if (thread->sched_stamp != sched_tick) {
                    197:                        update_priority(thread);
                    198:                    }
                    199:                    else {
                    200:                        if (
                    201: #if    MACH_FIXPRI
                    202:                            (thread->policy == POLICY_TIMESHARE) &&
                    203: #endif /* MACH_FIXPRI */
                    204:                            (thread->depress_priority < 0)) {
                    205:                                thread_timer_delta(thread);
                    206:                                if (thread->sched_delta >= USAGE_THRESHOLD) {
                    207:                                    thread->sched_usage +=
                    208:                                        thread->sched_delta;
                    209:                                    thread->sched_delta = 0;
                    210:                                    compute_my_priority(thread);
                    211:                                }
                    212:                        }
                    213:                    }
                    214:                    thread_unlock(thread);
                    215:                    (void) splx(s);
                    216:                }
                    217:                /*
                    218:                 * Check for and schedule ast if needed.
                    219:                 */
                    220:                ast_check();
                    221:        }
                    222: }
                    223: 

unix.superglobalmegacorp.com

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