Better checking of package locks when declaring variables.
[sbcl.git] / src / runtime / pseudo-atomic.h
blob63de18d38f7dcb378a03d79647a29e9665b80bf9
1 /*
2 * macros for manipulating pseudo-atomic flags (per thread)
3 */
5 /*
6 * This software is part of the SBCL system. See the README file for
7 * more information.
9 * This software is derived from the CMU CL system, which was
10 * written at Carnegie Mellon University and released into the
11 * public domain. The software is in the public domain and is
12 * provided with absolutely no warranty. See the COPYING and CREDITS
13 * files for more information.
16 #ifndef PSEUDO_ATOMIC_H
17 #define PSEUDO_ATOMIC_H
19 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
21 #define set_alloc_pointer(value) \
22 SetSymbolValue(ALLOCATION_POINTER, value, 0)
23 #define get_alloc_pointer() \
24 SymbolValue(ALLOCATION_POINTER, 0)
26 #if defined(LISP_FEATURE_X86)
27 #define LISPOBJ_ASM_SUFFIX "l"
28 #elif defined(LISP_FEATURE_X86_64)
29 #define LISPOBJ_ASM_SUFFIX "q"
30 #endif
32 static inline int
33 get_pseudo_atomic_atomic(struct thread *thread)
35 return SymbolValue(PSEUDO_ATOMIC_BITS, thread) & (~1);
38 static inline void
39 set_pseudo_atomic_atomic(struct thread *thread)
41 lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread);
42 if (*p)
43 lose("set_pseudo_atomic_atomic: pseudo atomic bits is %d.", *p);
44 __asm__ __volatile__
45 ("or" LISPOBJ_ASM_SUFFIX " %0,%1"
47 : "g" (~1), "m" (*p)
48 : "memory");
51 static inline void
52 clear_pseudo_atomic_atomic(struct thread *thread)
54 lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread);
55 __asm__ __volatile__
56 ("and" LISPOBJ_ASM_SUFFIX " %0,%1"
58 : "g" (1), "m" (*p)
59 : "memory");
62 static inline int
63 get_pseudo_atomic_interrupted(struct thread *thread)
65 return SymbolValue(PSEUDO_ATOMIC_BITS, thread) & 1;
68 static inline void
69 set_pseudo_atomic_interrupted(struct thread *thread)
71 if (!get_pseudo_atomic_atomic(thread))
72 lose("set_pseudo_atomic_interrupted not in pseudo atomic");
73 lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread);
74 __asm__ __volatile__
75 ("or" LISPOBJ_ASM_SUFFIX " %0,%1"
77 : "g" (1), "m" (*p)
78 : "memory");
81 static inline void
82 clear_pseudo_atomic_interrupted(struct thread *thread)
84 if (get_pseudo_atomic_atomic(thread))
85 lose("clear_pseudo_atomic_interrupted in pseudo atomic");
86 lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread);
87 __asm__ __volatile__
88 ("and" LISPOBJ_ASM_SUFFIX " %0,%1"
90 : "g" (~1), "m" (*p)
91 : "memory");
94 #undef LISPOBJ_ASM_SUFFIX
96 #elif (defined(LISP_FEATURE_ARM) || defined LISP_FEATURE_ARM64) && !defined LISP_FEATURE_SB_THREAD
97 static inline int
98 get_pseudo_atomic_atomic(struct thread *thread)
100 return SymbolValue(PSEUDO_ATOMIC_ATOMIC, thread) != NIL;
103 static inline void
104 set_pseudo_atomic_atomic(struct thread *thread)
106 SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, PSEUDO_ATOMIC_ATOMIC, thread);
109 static inline void
110 clear_pseudo_atomic_atomic(struct thread *thread)
112 SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, NIL, thread);
115 static inline int
116 get_pseudo_atomic_interrupted(struct thread *thread)
118 return SymbolValue(PSEUDO_ATOMIC_INTERRUPTED, thread) != 0;
121 static inline void
122 set_pseudo_atomic_interrupted(struct thread *thread)
124 SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, do_pending_interrupt, thread);
127 static inline void
128 clear_pseudo_atomic_interrupted(struct thread *thread)
130 SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, 0, 0);
133 #elif defined(LISP_FEATURE_GENCGC)
135 /* FIXME: Are these async signal safe? Compiler reordering? */
137 #if !defined LISP_FEATURE_ARM && !defined LISP_FEATURE_ARM64
138 #define set_alloc_pointer(value) \
139 (dynamic_space_free_pointer = \
140 ((lispobj *) \
141 ((value) | (((uword_t)dynamic_space_free_pointer) & LOWTAG_MASK))))
143 #define get_alloc_pointer() \
144 ((uword_t) dynamic_space_free_pointer & ~LOWTAG_MASK)
145 #endif
147 #ifdef LISP_FEATURE_SB_THREAD
148 #define get_pseudo_atomic_atomic(thread) \
149 ((thread)->pseudo_atomic_bits & flag_PseudoAtomic)
150 #define set_pseudo_atomic_atomic(thread) \
151 ((thread)->pseudo_atomic_bits |= flag_PseudoAtomic)
152 #define clear_pseudo_atomic_atomic(thread) \
153 ((thread)->pseudo_atomic_bits &= ~flag_PseudoAtomic)
154 #define get_pseudo_atomic_interrupted(thread) \
155 ((thread)->pseudo_atomic_bits & flag_PseudoAtomicInterrupted)
156 #define set_pseudo_atomic_interrupted(thread) \
157 ((thread)->pseudo_atomic_bits |= flag_PseudoAtomicInterrupted)
158 #define clear_pseudo_atomic_interrupted(thread) \
159 ((thread)->pseudo_atomic_bits &= ~flag_PseudoAtomicInterrupted)
160 #else
161 #define get_pseudo_atomic_atomic(thread) \
162 ((uword_t)dynamic_space_free_pointer & flag_PseudoAtomic)
163 #define set_pseudo_atomic_atomic(thread) \
164 (dynamic_space_free_pointer \
165 = (lispobj*) ((uword_t)dynamic_space_free_pointer | flag_PseudoAtomic))
166 #define clear_pseudo_atomic_atomic(thread) \
167 (dynamic_space_free_pointer \
168 = (lispobj*) ((uword_t) dynamic_space_free_pointer & ~flag_PseudoAtomic))
169 #define get_pseudo_atomic_interrupted(thread) \
170 ((uword_t) dynamic_space_free_pointer & flag_PseudoAtomicInterrupted)
171 #define clear_pseudo_atomic_interrupted(thread) \
172 (dynamic_space_free_pointer \
173 = (lispobj*) ((uword_t) dynamic_space_free_pointer & ~flag_PseudoAtomicInterrupted))
174 #define set_pseudo_atomic_interrupted(thread) \
175 (dynamic_space_free_pointer \
176 = (lispobj*) ((uword_t) dynamic_space_free_pointer | flag_PseudoAtomicInterrupted))
177 #endif
179 #endif
181 #if defined LISP_FEATURE_ARM || defined LISP_FEATURE_ARM64
182 #define set_alloc_pointer(value) \
183 SetSymbolValue(ALLOCATION_POINTER, value, 0)
184 #define get_alloc_pointer() \
185 SymbolValue(ALLOCATION_POINTER, 0)
186 #endif
187 #endif /* PSEUDO_ATOMIC_H */