|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.