Annotation of XNU/osfmk/kern/ast.c, revision 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: /*
        !            54:  *
        !            55:  *     This file contains routines to check whether an ast is needed.
        !            56:  *
        !            57:  *     ast_check() - check whether ast is needed for interrupt or context
        !            58:  *     switch.  Usually called by clock interrupt handler.
        !            59:  *
        !            60:  */
        !            61: 
        !            62: #include <cputypes.h>
        !            63: #include <cpus.h>
        !            64: #include <platforms.h>
        !            65: #include <dipc.h>
        !            66: #include <task_swapper.h>
        !            67: 
        !            68: #include <kern/ast.h>
        !            69: #include <kern/counters.h>
        !            70: #include <kern/cpu_number.h>
        !            71: #include <kern/misc_protos.h>
        !            72: #include <kern/queue.h>
        !            73: #include <kern/sched.h>
        !            74: #include <kern/sched_prim.h>
        !            75: #include <kern/thread.h>
        !            76: #include <kern/thread_act.h>
        !            77: #include <kern/thread_swap.h>
        !            78: #include <kern/processor.h>
        !            79: #include <kern/spl.h>
        !            80: #include <mach/policy.h>
        !            81: #if    DIPC
        !            82: #include <dipc/dipc_funcs.h>
        !            83: #endif /* DIPC */
        !            84: #if    TASK_SWAPPER
        !            85: #include <kern/task_swap.h>
        !            86: #endif /* TASK_SWAPPER */
        !            87: 
        !            88: volatile ast_t need_ast[NCPUS];
        !            89: 
        !            90: void
        !            91: ast_init(void)
        !            92: {
        !            93: #ifndef        MACHINE_AST
        !            94:        register int i;
        !            95: 
        !            96:        for (i=0; i<NCPUS; i++) {
        !            97:                need_ast[i] = AST_NONE;
        !            98:        }
        !            99: #endif /* MACHINE_AST */
        !           100: }
        !           101: 
        !           102: void
        !           103: ast_taken(
        !           104:        boolean_t               preemption,
        !           105:        ast_t                   mask,
        !           106:        boolean_t               interrupt
        !           107: )
        !           108: {
        !           109:        register thread_t       self = current_thread();
        !           110:        register processor_t    mypr;
        !           111:        register ast_t          reasons;
        !           112:        register int            mycpu;
        !           113:        thread_act_t            act = self->top_act;
        !           114: #ifdef MACH_BSD
        !           115:        extern void             bsd_ast(thread_act_t);
        !           116: #endif
        !           117: 
        !           118:        mp_disable_preemption();
        !           119:        mycpu = cpu_number();
        !           120:        reasons = need_ast[mycpu] & mask;
        !           121:        need_ast[mycpu] &= ~reasons;
        !           122:        mp_enable_preemption();
        !           123: 
        !           124:        ml_set_interrupts_enabled(interrupt);
        !           125: 
        !           126:        /*
        !           127:         *      These actions must not block.
        !           128:         */
        !           129: 
        !           130: #if    DIPC
        !           131:        if (reasons & AST_DIPC)
        !           132:                dipc_ast();
        !           133: #endif /* DIPC */
        !           134: 
        !           135: #ifdef MACH_BSD
        !           136:        if (reasons & AST_BSD)
        !           137:                bsd_ast(act);
        !           138:        if (reasons & AST_BSD_INIT) {
        !           139:                thread_ast_clear(act,AST_BSD_INIT);
        !           140:                bsdinit_task();
        !           141:        }
        !           142: #endif
        !           143: 
        !           144:        /*
        !           145:         *      Make darn sure that we don't call thread_halt_self
        !           146:         *      or thread_block from the idle thread.
        !           147:         */
        !           148: 
        !           149:        /* XXX - this isn't currently right for the HALT case... */
        !           150: 
        !           151:        mp_disable_preemption();
        !           152:        mypr = current_processor();
        !           153:        if (self == mypr->idle_thread) {
        !           154: #if    NCPUS == 1
        !           155:            if (reasons & AST_URGENT) {
        !           156:                if (!preemption)
        !           157:                    panic("ast_taken: AST_URGENT for idle_thr w/o preemption");
        !           158:            }
        !           159: #endif
        !           160:            mp_enable_preemption();
        !           161:            return;
        !           162:        }
        !           163:        mp_enable_preemption();
        !           164: 
        !           165: #if    TASK_SWAPPER
        !           166:        /* must be before AST_APC */
        !           167:        if (reasons & AST_SWAPOUT) {
        !           168:                spl_t s;
        !           169:                swapout_ast();
        !           170:                s = splsched();
        !           171:                mp_disable_preemption();
        !           172:                mycpu = cpu_number();
        !           173:                if (need_ast[mycpu] & AST_APC) {
        !           174:                        /* generated in swapout_ast() to get suspended */
        !           175:                        reasons |= AST_APC;             /* process now ... */
        !           176:                        need_ast[mycpu] &= ~AST_APC;    /* ... and not later */
        !           177:                }
        !           178:                mp_enable_preemption();
        !           179:                splx(s);
        !           180:        }
        !           181: #endif /* TASK_SWAPPER */
        !           182: 
        !           183:        /* migration APC hook */
        !           184:        if (reasons & AST_APC) {
        !           185:                act_execute_returnhandlers();
        !           186:                return; /* auto-retry will catch anything new */
        !           187:        }
        !           188: 
        !           189:        /* 
        !           190:         *      thread_block needs to know if the thread's quantum 
        !           191:         *      expired so the thread can be put on the tail of
        !           192:         *      run queue. One of the previous actions might well
        !           193:         *      have woken a high-priority thread, so we also use
        !           194:         *      csw_needed check.
        !           195:         */
        !           196:        {   
        !           197:            if ((reasons &= AST_PREEMPT) == 0) {
        !           198:                    mp_disable_preemption();
        !           199:                    mypr = current_processor();
        !           200:                    if (csw_needed(self, mypr)) {
        !           201:                            reasons = (mypr->first_quantum
        !           202:                                       ? AST_BLOCK
        !           203:                                       : AST_QUANTUM);
        !           204:                    }
        !           205:                    mp_enable_preemption();
        !           206:            }
        !           207:            if (reasons) {
        !           208:                    counter(c_ast_taken_block++);
        !           209:                    thread_block_reason((void (*)(void))0, reasons);
        !           210:            }
        !           211:        }
        !           212: }
        !           213: 
        !           214: void
        !           215: ast_check(void)
        !           216: {
        !           217:        register int            mycpu;
        !           218:        register processor_t    myprocessor;
        !           219:        register thread_t       thread = current_thread();
        !           220:        spl_t                   s = splsched();
        !           221: 
        !           222:        mp_disable_preemption();
        !           223:        mycpu = cpu_number();
        !           224: 
        !           225:        /*
        !           226:         *      Check processor state for ast conditions.
        !           227:         */
        !           228:        myprocessor = cpu_to_processor(mycpu);
        !           229:        switch(myprocessor->state) {
        !           230:            case PROCESSOR_OFF_LINE:
        !           231:            case PROCESSOR_IDLE:
        !           232:            case PROCESSOR_DISPATCHING:
        !           233:                /*
        !           234:                 *      No ast.
        !           235:                 */
        !           236:                break;
        !           237: 
        !           238: #if    NCPUS > 1
        !           239:            case PROCESSOR_ASSIGN:
        !           240:            case PROCESSOR_SHUTDOWN:
        !           241:                /*
        !           242:                 *      Need ast to force action thread onto processor.
        !           243:                 *
        !           244:                 * XXX  Should check if action thread is already there.
        !           245:                 */
        !           246:                ast_on(AST_BLOCK);
        !           247:                break;
        !           248: #endif /* NCPUS > 1 */
        !           249: 
        !           250:            case PROCESSOR_RUNNING:
        !           251:                /*
        !           252:                 *      Propagate thread ast to processor.  If we already
        !           253:                 *      need an ast, don't look for more reasons.
        !           254:                 */
        !           255:                ast_propagate(current_act()->ast);
        !           256:                if (ast_needed(mycpu))
        !           257:                        break;
        !           258: 
        !           259:                /*
        !           260:                 *      Context switch check.
        !           261:                 */
        !           262:                if (csw_needed(thread, myprocessor)) {
        !           263:                        ast_on((myprocessor->first_quantum ?
        !           264:                               AST_BLOCK : AST_QUANTUM));
        !           265:                }
        !           266:                break;
        !           267: 
        !           268:            default:
        !           269:                panic("ast_check: Bad processor state");
        !           270:        }
        !           271:        mp_enable_preemption();
        !           272:        splx(s);
        !           273: }
        !           274: 
        !           275: /*
        !           276:  * JMM - Temporary exports to other components
        !           277:  */
        !           278: #undef ast_on
        !           279: #undef ast_off
        !           280: 
        !           281: void
        !           282: ast_on(ast_t reason)
        !           283: {
        !           284:        ast_on_fast(reason);
        !           285: }
        !           286: 
        !           287: void
        !           288: ast_off(ast_t reason)
        !           289: {
        !           290:        ast_off_fast(reason);
        !           291: }

unix.superglobalmegacorp.com

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