1 /* -*-C-*- 2 3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 4 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 5 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts 6 Institute of Technology 7 8 This file is part of MIT/GNU Scheme. 9 10 MIT/GNU Scheme is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 2 of the License, or (at 13 your option) any later version. 14 15 MIT/GNU Scheme is distributed in the hope that it will be useful, but 16 WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with MIT/GNU Scheme; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 23 USA. 24 25 */ 26 27 /* Interrupt manipulation utilities. */ 28 29 /* Interrupt bits -- scanned from LSB (1) to MSB (16) */ 30 31 #define INT_Stack_Overflow 0x0001UL /* Local interrupt */ 32 #define INT_Global_GC 0x0002UL 33 #define INT_GC 0x0004UL /* Local interrupt */ 34 #define INT_Global_1 0x0008UL 35 #define INT_Character 0x0010UL /* Local interrupt */ 36 #define INT_AFTER_GC 0x0020UL /* Local interrupt */ 37 #define INT_Timer 0x0040UL /* Local interrupt */ 38 #define INT_Global_3 0x0080UL 39 #define INT_Suspend 0x0100UL /* Local interrupt */ 40 41 /* Descartes profiling interrupts */ 42 43 #define INT_IPPB_Flush 0x0200UL /* Local interrupt */ 44 #define INT_IPPB_Extend 0x0400UL /* Local interrupt */ 45 #define INT_PCBPB_Flush 0x0800UL /* Local interrupt */ 46 #define INT_PCBPB_Extend 0x1000UL /* Local interrupt */ 47 #define INT_HCBPB_Flush 0x2000UL /* Local interrupt */ 48 #define INT_HCBPB_Extend 0x4000UL /* Local interrupt */ 49 50 #define INT_Step_CC 0x8000UL 51 52 #define INT_Global_Mask (INT_Global_GC | INT_Global_1 | INT_Global_3) 53 54 #define Global_GC_Level 0x1UL 55 #define Global_1_Level 0x3UL 56 #define Global_3_Level 0x7UL 57 #define MAX_INTERRUPT_NUMBER 0xFUL /* 2^15 = INT_Step_CC */ 58 59 #define INT_Mask ((1UL << (MAX_INTERRUPT_NUMBER + 1)) - 1) 60 61 /* Utility macros. */ 62 63 #define PENDING_INTERRUPTS() (GET_INT_MASK & GET_INT_CODE) 64 #define PENDING_INTERRUPTS_P ((PENDING_INTERRUPTS ()) != 0) 65 #define INTERRUPT_QUEUED_P(mask) ((GET_INT_CODE & (mask)) != 0) 66 #define INTERRUPT_ENABLED_P(mask) ((GET_INT_MASK & (mask)) != 0) 67 #define INTERRUPT_PENDING_P(mask) (((PENDING_INTERRUPTS ()) & (mask)) != 0) 68 69 #define COMPILER_SETUP_INTERRUPT() do \ 70 { \ 71 SET_MEMTOP \ 72 (((PENDING_INTERRUPTS ()) != 0) \ 73 ? memory_block_start \ 74 : (GC_ENABLED_P ()) \ 75 ? heap_alloc_limit \ 76 : heap_end); \ 77 SET_STACK_GUARD \ 78 ((INTERRUPT_ENABLED_P (INT_Stack_Overflow)) \ 79 ? stack_guard \ 80 : STACK_TOP); \ 81 } while (0) 82 83 #define SET_INTERRUPT_MASK(mask) do \ 84 { \ 85 GRAB_INTERRUPT_REGISTERS (); \ 86 SET_INT_MASK (mask); \ 87 COMPILER_SETUP_INTERRUPT (); \ 88 RELEASE_INTERRUPT_REGISTERS (); \ 89 } while (0) 90 91 #define REQUEST_INTERRUPT(code) do \ 92 { \ 93 GRAB_INTERRUPT_REGISTERS (); \ 94 SET_INT_CODE (GET_INT_CODE | (code)); \ 95 COMPILER_SETUP_INTERRUPT (); \ 96 RELEASE_INTERRUPT_REGISTERS (); \ 97 } while (0) 98 99 #define CLEAR_INTERRUPT_NOLOCK(code) do \ 100 { \ 101 SET_INT_CODE (GET_INT_CODE &~ (code)); \ 102 COMPILER_SETUP_INTERRUPT (); \ 103 } while (0) 104 105 #define CLEAR_INTERRUPT(code) do \ 106 { \ 107 GRAB_INTERRUPT_REGISTERS (); \ 108 CLEAR_INTERRUPT_NOLOCK (code); \ 109 RELEASE_INTERRUPT_REGISTERS (); \ 110 } while (0) 111 112 #define INITIALIZE_INTERRUPTS(mask) do \ 113 { \ 114 GRAB_INTERRUPT_REGISTERS (); \ 115 SET_INT_MASK (mask); \ 116 SET_INT_CODE (0); \ 117 COMPILER_SETUP_INTERRUPT (); \ 118 RELEASE_INTERRUPT_REGISTERS (); \ 119 } while (0) 120 121 #if defined(__OS2__) || defined(__WIN32__) 122 extern void OS_grab_interrupt_registers (void); 123 extern void OS_release_interrupt_registers (void); 124 # define GRAB_INTERRUPT_REGISTERS() OS_grab_interrupt_registers () 125 # define RELEASE_INTERRUPT_REGISTERS() OS_release_interrupt_registers () 126 #else 127 # define GRAB_INTERRUPT_REGISTERS() 128 # define RELEASE_INTERRUPT_REGISTERS() 129 #endif 130