Use defglobal less
[sbcl.git] / src / runtime / pseudo-atomic.h
bloba275820993feb819f5479df6bbe078560cfbf958
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) dynamic_space_free_pointer = (lispobj*)(value)
22 #define get_alloc_pointer() (dynamic_space_free_pointer)
24 #if defined(LISP_FEATURE_X86)
25 #define LISPOBJ_ASM_SUFFIX "l"
26 #elif defined(LISP_FEATURE_X86_64)
27 #define LISPOBJ_ASM_SUFFIX "q"
28 #endif
30 static inline int
31 get_pseudo_atomic_atomic(struct thread *thread)
33 return (SymbolValue(PSEUDO_ATOMIC_BITS, thread) & (~1)) != 0;
36 static inline void
37 set_pseudo_atomic_atomic(struct thread *thread)
39 lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread);
40 if (*p)
41 lose("set_pseudo_atomic_atomic: pseudo atomic bits is %d.", *p);
42 __asm__ __volatile__
43 ("or" LISPOBJ_ASM_SUFFIX " %0,%1"
45 : "g" (~1), "m" (*p)
46 : "memory");
49 static inline void
50 clear_pseudo_atomic_atomic(struct thread *thread)
52 lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread);
53 __asm__ __volatile__
54 ("and" LISPOBJ_ASM_SUFFIX " %0,%1"
56 : "g" (1), "m" (*p)
57 : "memory");
60 static inline int
61 get_pseudo_atomic_interrupted(struct thread *thread)
63 return SymbolValue(PSEUDO_ATOMIC_BITS, thread) & 1;
66 static inline void
67 set_pseudo_atomic_interrupted(struct thread *thread)
69 if (!get_pseudo_atomic_atomic(thread))
70 lose("set_pseudo_atomic_interrupted not in pseudo atomic");
71 lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread);
72 __asm__ __volatile__
73 ("or" LISPOBJ_ASM_SUFFIX " %0,%1"
75 : "g" (1), "m" (*p)
76 : "memory");
79 static inline void
80 clear_pseudo_atomic_interrupted(struct thread *thread)
82 if (get_pseudo_atomic_atomic(thread))
83 lose("clear_pseudo_atomic_interrupted in pseudo atomic");
84 lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread);
85 __asm__ __volatile__
86 ("and" LISPOBJ_ASM_SUFFIX " %0,%1"
88 : "g" (~1), "m" (*p)
89 : "memory");
92 #undef LISPOBJ_ASM_SUFFIX
94 #elif (defined(LISP_FEATURE_ARM) || defined LISP_FEATURE_ARM64) && !defined LISP_FEATURE_SB_THREAD
95 static inline int
96 get_pseudo_atomic_atomic(struct thread *thread)
98 return SymbolValue(PSEUDO_ATOMIC_ATOMIC, thread) != NIL;
101 static inline void
102 set_pseudo_atomic_atomic(struct thread *thread)
104 SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, PSEUDO_ATOMIC_ATOMIC, thread);
107 static inline void
108 clear_pseudo_atomic_atomic(struct thread *thread)
110 SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, NIL, thread);
113 static inline int
114 get_pseudo_atomic_interrupted(struct thread *thread)
116 return SymbolValue(PSEUDO_ATOMIC_INTERRUPTED, thread) != 0;
119 static inline void
120 set_pseudo_atomic_interrupted(struct thread *thread)
122 SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, do_pending_interrupt, thread);
125 static inline void
126 clear_pseudo_atomic_interrupted(struct thread *thread)
128 SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, 0, 0);
131 #elif defined(LISP_FEATURE_GENCGC)
133 /* FIXME: Are these async signal safe? Compiler reordering? */
135 #if !defined LISP_FEATURE_ARM && !defined LISP_FEATURE_ARM64
136 #define set_alloc_pointer(value) \
137 (dynamic_space_free_pointer = \
138 ((lispobj *) \
139 ((value) | (((uword_t)dynamic_space_free_pointer) & LOWTAG_MASK))))
141 #define get_alloc_pointer() \
142 ((uword_t) dynamic_space_free_pointer & ~LOWTAG_MASK)
143 #endif
145 #ifdef LISP_FEATURE_SB_THREAD
146 #define get_pseudo_atomic_atomic(thread) \
147 ((thread)->pseudo_atomic_bits & flag_PseudoAtomic)
148 #define set_pseudo_atomic_atomic(thread) \
149 ((thread)->pseudo_atomic_bits |= flag_PseudoAtomic)
150 #define clear_pseudo_atomic_atomic(thread) \
151 ((thread)->pseudo_atomic_bits &= ~flag_PseudoAtomic)
152 #define get_pseudo_atomic_interrupted(thread) \
153 ((thread)->pseudo_atomic_bits & flag_PseudoAtomicInterrupted)
154 #define set_pseudo_atomic_interrupted(thread) \
155 ((thread)->pseudo_atomic_bits |= flag_PseudoAtomicInterrupted)
156 #define clear_pseudo_atomic_interrupted(thread) \
157 ((thread)->pseudo_atomic_bits &= ~flag_PseudoAtomicInterrupted)
158 #else
159 #define get_pseudo_atomic_atomic(thread) \
160 ((uword_t)dynamic_space_free_pointer & flag_PseudoAtomic)
161 #define set_pseudo_atomic_atomic(thread) \
162 (dynamic_space_free_pointer \
163 = (lispobj*) ((uword_t)dynamic_space_free_pointer | flag_PseudoAtomic))
164 #define clear_pseudo_atomic_atomic(thread) \
165 (dynamic_space_free_pointer \
166 = (lispobj*) ((uword_t) dynamic_space_free_pointer & ~flag_PseudoAtomic))
167 #define get_pseudo_atomic_interrupted(thread) \
168 ((uword_t) dynamic_space_free_pointer & flag_PseudoAtomicInterrupted)
169 #define clear_pseudo_atomic_interrupted(thread) \
170 (dynamic_space_free_pointer \
171 = (lispobj*) ((uword_t) dynamic_space_free_pointer & ~flag_PseudoAtomicInterrupted))
172 #define set_pseudo_atomic_interrupted(thread) \
173 (dynamic_space_free_pointer \
174 = (lispobj*) ((uword_t) dynamic_space_free_pointer | flag_PseudoAtomicInterrupted))
175 #endif
177 #endif
179 #if defined LISP_FEATURE_ARM || defined LISP_FEATURE_ARM64
180 #define set_alloc_pointer(value) \
181 SetSymbolValue(ALLOCATION_POINTER, value, 0)
182 #define get_alloc_pointer() \
183 SymbolValue(ALLOCATION_POINTER, 0)
184 #endif
185 #endif /* PSEUDO_ATOMIC_H */