Annotation of XNU/osfmk/kern/priority.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 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:  */
                     52: /*
                     53:  *     File:   clock_prim.c
                     54:  *     Author: Avadis Tevanian, Jr.
                     55:  *     Date:   1986
                     56:  *
                     57:  *     Clock primitives.
                     58:  */
                     59: 
                     60: #include <cpus.h>
                     61: 
                     62: #include <mach/boolean.h>
                     63: #include <mach/kern_return.h>
                     64: #include <mach/machine.h>
                     65: #include <kern/host.h>
                     66: #include <kern/mach_param.h>
                     67: #include <kern/sched.h>
                     68: #include <kern/spl.h>
                     69: #include <kern/thread.h>
                     70: #include <kern/processor.h>
                     71: #include <machine/machparam.h>
                     72: #include <kern/sf.h>
                     73: #include <kern/mk_sp.h>        /*** ??? fix so this can be removed ***/
                     74: /*** ??? Should this file be MK SP-specific?  Or is it more general purpose? ***/
                     75: 
                     76: 
                     77: 
                     78: /*
                     79:  *     USAGE_THRESHOLD is the amount by which usage must change to
                     80:  *     cause a priority shift that moves a thread between run queues.
                     81:  */
                     82: 
                     83: #ifdef PRI_SHIFT_2
                     84: #if    PRI_SHIFT_2 > 0
                     85: #define        USAGE_THRESHOLD (((1 << PRI_SHIFT) + (1 << PRI_SHIFT_2)) << (2 + SCHED_SHIFT))
                     86: #else  /* PRI_SHIFT_2 > 0 */
                     87: #define        USAGE_THRESHOLD (((1 << PRI_SHIFT) - (1 << -(PRI_SHIFT_2))) << (2 + SCHED_SHIFT))
                     88: #endif /* PRI_SHIFT_2 > 0 */
                     89: #else  /* PRI_SHIFT_2 */
                     90: #define USAGE_THRESHOLD        (1 << (PRI_SHIFT + 2 + SCHED_SHIFT))
                     91: #endif /* PRI_SHIFT_2 */
                     92: 
                     93: /*
                     94:  *     thread_quantum_update:
                     95:  *
                     96:  *     Recalculate the quantum and priority for a thread.
                     97:  *     The number of ticks that has elapsed since we were last called
                     98:  *     is passed as "nticks."
                     99:  */
                    100: 
                    101: void
                    102: thread_quantum_update(
                    103:        register int            mycpu,
                    104:        register thread_t       thread,
                    105:        int                                     nticks,
                    106:        int                                     state)
                    107: {
                    108:        register int                            quantum;
                    109:        register processor_t            myprocessor;
                    110: #if    NCPUS > 1
                    111:        register processor_set_t        pset;
                    112: #endif /* NCPUS > 1 */
                    113:        spl_t                                           s;
                    114: 
                    115:        myprocessor = cpu_to_processor(mycpu);
                    116: #if    NCPUS > 1
                    117:        pset = myprocessor->processor_set;
                    118: #endif /* NCPUS > 1 */
                    119: 
                    120:        /*
                    121:         *      Account for thread's utilization of these ticks.
                    122:         *      This assumes that there is *always* a current thread.
                    123:         *      When the processor is idle, it should be the idle thread.
                    124:         */
                    125: 
                    126:        /*
                    127:         *      Update set_quantum and calculate the current quantum.
                    128:         */
                    129: #if    NCPUS > 1
                    130:        pset->set_quantum = pset->machine_quantum[
                    131:                                                        (pset->runq.count > pset->processor_count) ?
                    132:                                                                  pset->processor_count : pset->runq.count];
                    133: 
                    134:        if (myprocessor->runq.count != 0)
                    135:                quantum = min_quantum;
                    136:        else
                    137:                quantum = pset->set_quantum;
                    138: #else  /* NCPUS > 1 */
                    139:        quantum = min_quantum;
                    140:        default_pset.set_quantum = quantum;
                    141: #endif /* NCPUS > 1 */
                    142:                
                    143:        /*
                    144:         *      Now recompute the priority of the thread if appropriate.
                    145:         */
                    146: 
                    147:        {
                    148:                mk_sp_info_t                            sp_info;
                    149: 
                    150:                s = splsched();
                    151:                thread_lock(thread);
                    152: 
                    153:                if (!(thread->policy & (POLICY_TIMESHARE|POLICY_RR|POLICY_FIFO))) {
                    154:                        thread_unlock(thread);
                    155:                        splx(s);
                    156:                        return;
                    157:                }
                    158: 
                    159:                sp_info = (mk_sp_info_t)thread->sp_info; 
                    160:                assert(sp_info != SP_INFO_NULL);
                    161: 
                    162:                if (thread->policy == POLICY_FIFO) {
                    163:                        /* FIFO always has an infinite quantum */
                    164:                        myprocessor->first_quantum = TRUE;
                    165:                        /*** ??? fix me ***/
                    166:                        if (sp_info->sched_stamp != sched_tick)
                    167:                                update_priority(thread);
                    168:                        thread_unlock(thread);
                    169:                        splx(s);
                    170:                        ast_check();
                    171:                        return;
                    172:                }
                    173: 
                    174:                myprocessor->quantum -= nticks;
                    175: #if    NCPUS > 1
                    176:                /*
                    177:                 *      Runtime quantum adjustment.  Use quantum_adj_index
                    178:                 *      to avoid synchronizing quantum expirations.
                    179:                 */
                    180:                if (    quantum != myprocessor->last_quantum    &&
                    181:                                        pset->processor_count > 1                                       ) {
                    182:                        myprocessor->last_quantum = quantum;
                    183:                        simple_lock(&pset->quantum_adj_lock);
                    184:                        quantum = min_quantum + (pset->quantum_adj_index *
                    185:                                                                                        (quantum - min_quantum)) / 
                    186:                                                                                                (pset->processor_count - 1);
                    187:                        if (++(pset->quantum_adj_index) >= pset->processor_count)
                    188:                                pset->quantum_adj_index = 0;
                    189:                        simple_unlock(&pset->quantum_adj_lock);
                    190:                }
                    191: #endif /* NCPUS > 1 */
                    192:                if (myprocessor->quantum <= 0) {
                    193:                        /*** ??? fix me ***/
                    194:                        if (sp_info->sched_stamp != sched_tick) {
                    195:                                update_priority(thread);
                    196:                        }
                    197:                        else
                    198:                        if (    thread->policy == POLICY_TIMESHARE              &&
                    199:                                        /*** ??? fix me ***/
                    200:                                        sp_info->depress_priority < 0                           ) {
                    201:                                thread_timer_delta(thread);
                    202:                                /*** ??? fix me ***/
                    203:                                sp_info->sched_usage += thread->sched_delta;
                    204:                                thread->sched_delta = 0;
                    205:                                compute_my_priority(thread);
                    206:                        }
                    207: 
                    208:                        /*
                    209:                         *      This quantum is up, give this thread another.
                    210:                         */
                    211:                        myprocessor->first_quantum = FALSE;
                    212:                        if (thread->policy == POLICY_TIMESHARE)
                    213:                                myprocessor->quantum += quantum;
                    214:                        else {
                    215:                                /*
                    216:                                 *    RR policy has per-thread quantum.
                    217:                                 *    
                    218:                                 */
                    219:                                /*** ??? fix me ***/
                    220:                                myprocessor->quantum += sp_info->sched_data;
                    221:                        }
                    222:                }
                    223:                /*
                    224:                 *      Recompute priority if appropriate.
                    225:                 */
                    226:                else {
                    227:                    /*** ??? fix me ***/
                    228:                    if (sp_info->sched_stamp != sched_tick) {
                    229:                                update_priority(thread);
                    230:                        }
                    231:                    else
                    232:                        if (    thread->policy == POLICY_TIMESHARE              &&
                    233:                                        /*** ??? fix me ***/
                    234:                                        sp_info->depress_priority < 0                           ) {
                    235:                                thread_timer_delta(thread);
                    236:                                if (thread->sched_delta >= USAGE_THRESHOLD) {
                    237:                                    /*** ??? fix me ***/
                    238:                                    sp_info->sched_usage +=     thread->sched_delta;
                    239:                                    thread->sched_delta = 0;
                    240:                                    compute_my_priority(thread);
                    241:                                }
                    242:                        }
                    243:                }
                    244: 
                    245:                thread_unlock(thread);
                    246:                splx(s);
                    247: 
                    248:                /*
                    249:                 * Check for and schedule ast if needed.
                    250:                 */
                    251:                ast_check();
                    252:        }
                    253: }

unix.superglobalmegacorp.com

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