1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University.
* Copyright (c) 1993,1994 The University of Utah and
* the Computer Systems Laboratory (CSL).
* All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
* THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
* OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
* THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* kern/ast.h: Definitions for Asynchronous System Traps.
*/
#ifndef _KERN_AST_H_
#define _KERN_AST_H_
/*
* A CPU takes an AST when it is about to return to user code.
* Instead of going back to user code, it calls ast_taken.
* Machine-dependent code is responsible for maintaining
* a set of reasons for an AST, and passing this set to ast_taken.
*/
#include "cpu_number.h"
#include <kern/kern_types.h>
#include <kern/macros.h>
#include <machine/ast.h>
/*
* Bits for reasons
*/
#define AST_ZILCH 0x0
#define AST_HALT 0x1
#define AST_TERMINATE 0x2
#define AST_BLOCK 0x4
#define AST_NETWORK 0x8
#define AST_NETIPC 0x10
#define AST_SCHEDULING (AST_HALT|AST_TERMINATE|AST_BLOCK)
/*
* Per-thread ASTs are reset at context-switch time.
* machine/ast.h can define MACHINE_AST_PER_THREAD.
*/
#ifndef MACHINE_AST_PER_THREAD
#define MACHINE_AST_PER_THREAD 0
#endif
#define AST_PER_THREAD (AST_HALT | AST_TERMINATE | MACHINE_AST_PER_THREAD)
typedef unsigned long ast_t;
extern volatile ast_t need_ast[NCPUS];
#ifdef MACHINE_AST
/*
* machine/ast.h is responsible for defining aston and astoff.
*/
#else /* MACHINE_AST */
#define aston(mycpu)
#define astoff(mycpu)
#endif /* MACHINE_AST */
extern void ast_taken(void);
/*
* ast_needed, ast_on, ast_off, ast_context, and ast_propagate
* assume splsched. mycpu is always cpu_number(). It is an
* argument in case cpu_number() is expensive.
*/
#define ast_needed(mycpu) need_ast[mycpu]
#define ast_on(mycpu, reasons) \
MACRO_BEGIN \
if ((need_ast[mycpu] |= (reasons)) != AST_ZILCH) \
{ aston(mycpu); } \
MACRO_END
#define ast_off(mycpu, reasons) \
MACRO_BEGIN \
if ((need_ast[mycpu] &= ~(reasons)) == AST_ZILCH) \
{ astoff(mycpu); } \
MACRO_END
#define ast_propagate(thread, mycpu) ast_on((mycpu), (thread)->ast)
#define ast_context(thread, mycpu) \
MACRO_BEGIN \
if ((need_ast[mycpu] = \
(need_ast[mycpu] &~ AST_PER_THREAD) | (thread)->ast) \
!= AST_ZILCH) \
{ aston(mycpu); } \
else \
{ astoff(mycpu); } \
MACRO_END
#define thread_ast_set(thread, reason) (thread)->ast |= (reason)
#define thread_ast_clear(thread, reason) (thread)->ast &= ~(reason)
#define thread_ast_clear_all(thread) (thread)->ast = AST_ZILCH
/*
* NOTE: if thread is the current thread, thread_ast_set should
* be followed by ast_propagate().
*/
extern void ast_init (void);
extern void ast_check (void);
#if NCPUS > 1
extern void cause_ast_check(const processor_t processor);
#endif
#endif /* _KERN_AST_H_ */
|