From: Gabor Melis Date: Mon, 16 Feb 2009 21:38:43 +0000 (+0000) Subject: 1.0.25.24: x86/x86-64 runtime pseudo atomic fixes X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=de0a47a2f2b165f34177669bd9499135847b4897;p=sbcl.git 1.0.25.24: x86/x86-64 runtime pseudo atomic fixes Make sure that {clear,set}_pseudo_atomic_{atomic,interrupted} boil down to a single assembly intruction. And that the compiler does not reorder them. I think the ppc bits in pseudo-atomic.h are still broken on both accounts. --- diff --git a/src/runtime/alloc.c b/src/runtime/alloc.c index 4f3be56..19518e4 100644 --- a/src/runtime/alloc.c +++ b/src/runtime/alloc.c @@ -24,6 +24,7 @@ #include "globals.h" #include "gc.h" #include "thread.h" +#include "pseudo-atomic.h" #include "genesis/vector.h" #include "genesis/cons.h" #include "genesis/bignum.h" diff --git a/src/runtime/gc.h b/src/runtime/gc.h index 35f9d12..ce1b925 100644 --- a/src/runtime/gc.h +++ b/src/runtime/gc.h @@ -40,8 +40,6 @@ extern void clear_auto_gc_trigger(void); #include "fixnump.h" -#include "pseudo-atomic.h" - extern boolean maybe_gc(os_context_t *context); extern unsigned long bytes_consed_between_gcs; diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 5d687f4..895ced2 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -41,6 +41,7 @@ #include "gc.h" #include "gc-internal.h" #include "thread.h" +#include "pseudo-atomic.h" #include "alloc.h" #include "genesis/vector.h" #include "genesis/weak-pointer.h" diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 74fd67b..4860be2 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -63,6 +63,7 @@ #include "alloc.h" #include "dynbind.h" #include "interr.h" +#include "pseudo-atomic.h" #include "genesis/fdefn.h" #include "genesis/simple-fun.h" #include "genesis/cons.h" diff --git a/src/runtime/parse.c b/src/runtime/parse.c index b4218e5..beedc29 100644 --- a/src/runtime/parse.c +++ b/src/runtime/parse.c @@ -32,6 +32,7 @@ #include "arch.h" #include "search.h" #include "thread.h" +#include "pseudo-atomic.h" #include "genesis/simple-fun.h" #include "genesis/fdefn.h" diff --git a/src/runtime/pseudo-atomic.h b/src/runtime/pseudo-atomic.h index df5e900..9636e5b 100644 --- a/src/runtime/pseudo-atomic.h +++ b/src/runtime/pseudo-atomic.h @@ -24,34 +24,77 @@ 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 fixnum_value(SymbolValue(PSEUDO_ATOMIC_BITS, thread) & + make_fixnum(1)); +} + +static inline void +set_pseudo_atomic_atomic(struct thread *thread) +{ + lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread); + __asm__ __volatile__ + ("or" LISPOBJ_ASM_SUFFIX " %0,%1" + : + : "g" (make_fixnum(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" (~make_fixnum(1)), "m" (*p) + : "memory"); +} + +static inline int +get_pseudo_atomic_interrupted(struct thread *thread) +{ + return fixnum_value(SymbolValue(PSEUDO_ATOMIC_BITS, thread) & + make_fixnum(2)); +} + +static inline void +set_pseudo_atomic_interrupted(struct thread *thread) +{ + lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread); + __asm__ __volatile__ + ("or" LISPOBJ_ASM_SUFFIX " %0,%1" + : + : "g" (make_fixnum(2)), "m" (*p) + : "memory"); +} + +static inline void +clear_pseudo_atomic_interrupted(struct thread *thread) +{ + lispobj *p = SymbolValueAddress(PSEUDO_ATOMIC_BITS, thread); + __asm__ __volatile__ + ("and" LISPOBJ_ASM_SUFFIX " %0,%1" + : + : "g" (~make_fixnum(2)), "m" (*p) + : "memory"); +} + +#undef LISPOBJ_SUFFIX #elif defined(LISP_FEATURE_PPC) && defined(LISP_FEATURE_GENCGC) +/* FIXME: Are these async signal safe? Compiler reordering? */ + #define set_alloc_pointer(value) \ (dynamic_space_free_pointer = \ ((lispobj *) \ diff --git a/src/runtime/thread.h b/src/runtime/thread.h index cf13ac9..074edec 100644 --- a/src/runtime/thread.h +++ b/src/runtime/thread.h @@ -51,6 +51,21 @@ extern int dynamic_values_bytes; #define for_each_thread(th) for(th=all_threads;th;th=0) #endif +static inline lispobj * +SymbolValueAddress(u64 tagged_symbol_pointer, void *thread) +{ + struct symbol *sym= (struct symbol *) + (pointer_sized_uint_t)(tagged_symbol_pointer-OTHER_POINTER_LOWTAG); +#ifdef LISP_FEATURE_SB_THREAD + if(thread && sym->tls_index) { + lispobj *r = &(((union per_thread_data *)thread) + ->dynamic_values[fixnum_value(sym->tls_index)]); + if((*r)!=NO_TLS_VALUE_MARKER_WIDETAG) return r; + } +#endif + return &sym->value; +} + static inline lispobj SymbolValue(u64 tagged_symbol_pointer, void *thread) { diff --git a/src/runtime/x86-64-arch.c b/src/runtime/x86-64-arch.c index a7f7354..d075ce6 100644 --- a/src/runtime/x86-64-arch.c +++ b/src/runtime/x86-64-arch.c @@ -25,6 +25,7 @@ #include "interr.h" #include "breakpoint.h" #include "thread.h" +#include "pseudo-atomic.h" #include "genesis/static-symbols.h" #include "genesis/symbol.h" diff --git a/src/runtime/x86-arch.c b/src/runtime/x86-arch.c index d6150dd..3ef4bec 100644 --- a/src/runtime/x86-arch.c +++ b/src/runtime/x86-arch.c @@ -24,6 +24,7 @@ #include "interr.h" #include "breakpoint.h" #include "thread.h" +#include "pseudo-atomic.h" #include "genesis/static-symbols.h" #include "genesis/symbol.h" diff --git a/version.lisp-expr b/version.lisp-expr index 7861267..36ac9e2 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.25.23" +"1.0.25.24"