X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fpseudo-atomic.h;h=0c2ea7f10ab9dc2e43dc630f1e0b3d97c0184b75;hb=f0cb0cf9c0fe1b6fce5d10dbd34a0b7b249c4ae8;hp=bd0cc55d4a756e00623ec070af5909e971094536;hpb=1600081cf1b71b3d0e2e40de1c1c124a3a4fd40c;p=sbcl.git diff --git a/src/runtime/pseudo-atomic.h b/src/runtime/pseudo-atomic.h index bd0cc55..0c2ea7f 100644 --- a/src/runtime/pseudo-atomic.h +++ b/src/runtime/pseudo-atomic.h @@ -22,60 +22,120 @@ SetSymbolValue(ALLOCATION_POINTER, value, 0) #define get_alloc_pointer() \ SymbolValue(ALLOCATION_POINTER, 0) -#define get_binding_stack_pointer(thread) \ - SymbolValue(BINDING_STACK_POINTER, thread) -#define get_pseudo_atomic_atomic(thread) \ - (fixnum_value(SymbolValue(PSEUDO_ATOMIC_BITS, thread) & make_fixnum(1))) -#define set_pseudo_atomic_atomic(thread) \ - { \ - lispobj bits = SymbolValue(PSEUDO_ATOMIC_BITS, thread); \ - SetSymbolValue(PSEUDO_ATOMIC_BITS, bits | make_fixnum(1), thread); \ - } -#define clear_pseudo_atomic_atomic(thread) \ - { \ - lispobj bits = SymbolValue(PSEUDO_ATOMIC_BITS, thread); \ - SetSymbolValue(PSEUDO_ATOMIC_BITS, bits & ~make_fixnum(1), thread); \ - } -#define get_pseudo_atomic_interrupted(thread) \ - (fixnum_value(SymbolValue(PSEUDO_ATOMIC_BITS, thread) & make_fixnum(2))) -#define clear_pseudo_atomic_interrupted(thread) \ - { \ - lispobj bits = SymbolValue(PSEUDO_ATOMIC_BITS, thread); \ - SetSymbolValue(PSEUDO_ATOMIC_BITS, bits & ~make_fixnum(2), thread); \ - } -#define set_pseudo_atomic_interrupted(thread) \ - { \ - lispobj bits = SymbolValue(PSEUDO_ATOMIC_BITS, thread); \ - SetSymbolValue(PSEUDO_ATOMIC_BITS, bits | make_fixnum(2), thread); \ - } +#if defined(LISP_FEATURE_X86) +#define LISPOBJ_ASM_SUFFIX "l" +#elif defined(LISP_FEATURE_X86_64) +#define LISPOBJ_ASM_SUFFIX "q" +#endif + +static inline int +get_pseudo_atomic_atomic(struct thread *thread) +{ + return SymbolValue(PSEUDO_ATOMIC_BITS, thread) & (~1); +} + +static inline void +set_pseudo_atomic_atomic(struct thread *thread) +{ + lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread); + if (*p) + lose("set_pseudo_atomic_atomic: pseudo atomic bits is %d.", *p); + __asm__ __volatile__ + ("or" LISPOBJ_ASM_SUFFIX " %0,%1" + : + : "g" (~1), "m" (*p) + : "memory"); +} + +static inline void +clear_pseudo_atomic_atomic(struct thread *thread) +{ + lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread); + __asm__ __volatile__ + ("and" LISPOBJ_ASM_SUFFIX " %0,%1" + : + : "g" (1), "m" (*p) + : "memory"); +} -#elif defined(LISP_FEATURE_PPC) && defined(LISP_FEATURE_GENCGC) +static inline int +get_pseudo_atomic_interrupted(struct thread *thread) +{ + return SymbolValue(PSEUDO_ATOMIC_BITS, thread) & 1; +} + +static inline void +set_pseudo_atomic_interrupted(struct thread *thread) +{ + if (!get_pseudo_atomic_atomic(thread)) + lose("set_pseudo_atomic_interrupted not in pseudo atomic"); + lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread); + __asm__ __volatile__ + ("or" LISPOBJ_ASM_SUFFIX " %0,%1" + : + : "g" (1), "m" (*p) + : "memory"); +} + +static inline void +clear_pseudo_atomic_interrupted(struct thread *thread) +{ + if (get_pseudo_atomic_atomic(thread)) + lose("clear_pseudo_atomic_interrupted in pseudo atomic"); + lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread); + __asm__ __volatile__ + ("and" LISPOBJ_ASM_SUFFIX " %0,%1" + : + : "g" (~1), "m" (*p) + : "memory"); +} + +#undef LISPOBJ_SUFFIX + +#elif defined(LISP_FEATURE_GENCGC) + +/* FIXME: Are these async signal safe? Compiler reordering? */ #define set_alloc_pointer(value) \ - (dynamic_space_free_pointer = \ - (value) | (((unsigned long)dynamic_space_free_pointer) & LOWTAG_MASK)) + (dynamic_space_free_pointer = \ + ((lispobj *) \ + ((value) | (((uword_t)dynamic_space_free_pointer) & LOWTAG_MASK)))) #define get_alloc_pointer() \ - ((unsigned long) dynamic_space_free_pointer & ~LOWTAG_MASK) -#define get_binding_stack_pointer(thread) \ - (current_binding_stack_pointer) + ((uword_t) dynamic_space_free_pointer & ~LOWTAG_MASK) + +#ifdef LISP_FEATURE_SB_THREAD +#define get_pseudo_atomic_atomic(thread) \ + ((thread)->pseudo_atomic_bits & flag_PseudoAtomic) +#define set_pseudo_atomic_atomic(thread) \ + ((thread)->pseudo_atomic_bits |= flag_PseudoAtomic) +#define clear_pseudo_atomic_atomic(thread) \ + ((thread)->pseudo_atomic_bits &= ~flag_PseudoAtomic) +#define get_pseudo_atomic_interrupted(thread) \ + ((thread)->pseudo_atomic_bits & flag_PseudoAtomicInterrupted) +#define set_pseudo_atomic_interrupted(thread) \ + ((thread)->pseudo_atomic_bits |= flag_PseudoAtomicInterrupted) +#define clear_pseudo_atomic_interrupted(thread) \ + ((thread)->pseudo_atomic_bits &= ~flag_PseudoAtomicInterrupted) +#else #define get_pseudo_atomic_atomic(thread) \ - ((unsigned long)dynamic_space_free_pointer & flag_PseudoAtomic) + ((uword_t)dynamic_space_free_pointer & flag_PseudoAtomic) #define set_pseudo_atomic_atomic(thread) \ (dynamic_space_free_pointer \ - = (lispobj*) ((unsigned long)dynamic_space_free_pointer | flag_PseudoAtomic)) + = (lispobj*) ((uword_t)dynamic_space_free_pointer | flag_PseudoAtomic)) #define clear_pseudo_atomic_atomic(thread) \ (dynamic_space_free_pointer \ - = (lispobj*) ((unsigned long) dynamic_space_free_pointer & ~flag_PseudoAtomic)) + = (lispobj*) ((uword_t) dynamic_space_free_pointer & ~flag_PseudoAtomic)) #define get_pseudo_atomic_interrupted(thread) \ - ((unsigned long) dynamic_space_free_pointer & flag_PseudoAtomicInterrupted) + ((uword_t) dynamic_space_free_pointer & flag_PseudoAtomicInterrupted) #define clear_pseudo_atomic_interrupted(thread) \ (dynamic_space_free_pointer \ - = (lispobj*) ((unsigned long) dynamic_space_free_pointer & ~flag_PseudoAtomicInterrupted)) + = (lispobj*) ((uword_t) dynamic_space_free_pointer & ~flag_PseudoAtomicInterrupted)) #define set_pseudo_atomic_interrupted(thread) \ (dynamic_space_free_pointer \ - = (lispobj*) ((unsigned long) dynamic_space_free_pointer | flag_PseudoAtomicInterrupted)) + = (lispobj*) ((uword_t) dynamic_space_free_pointer | flag_PseudoAtomicInterrupted)) +#endif #endif