Annotation of OSKit-Mach/kern/priority.c, revision 1.1.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.