From 4c400df29038a283e6b4df2d835d5b9c5201d0dd Mon Sep 17 00:00:00 2001 From: Gabor Melis Date: Mon, 13 Apr 2009 20:00:21 +0000 Subject: [PATCH] 1.0.27.8: slightly faster x86oid pseudo atomic with {e,r}bp Trusting that within SBCL ebp is even and that it doesn't change within a pseudo atomic section it's possible to use it to set and clear pseudo atomic bits. It is ever so slightly faster (about 0.5% overall on cl-bench on a P4). --- src/compiler/x86-64/macros.lisp | 70 +++++++++++++++++++-------------------- src/compiler/x86/macros.lisp | 24 +++++++------- src/runtime/pseudo-atomic.h | 20 ++++++----- version.lisp-expr | 2 +- 4 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/compiler/x86-64/macros.lisp b/src/compiler/x86-64/macros.lisp index 03da6d7..7711130 100644 --- a/src/compiler/x86-64/macros.lisp +++ b/src/compiler/x86-64/macros.lisp @@ -294,48 +294,46 @@ (defmacro pseudo-atomic (&rest forms) (with-unique-names (label) `(let ((,label (gen-label))) - (inst or (make-ea :byte - :base thread-base-tn - :disp (* 8 thread-pseudo-atomic-bits-slot)) - (fixnumize 1)) - ,@forms - (inst xor (make-ea :byte - :base thread-base-tn - :disp (* 8 thread-pseudo-atomic-bits-slot)) - (fixnumize 1)) - (inst jmp :z ,label) - ;; if PAI was set, interrupts were disabled at the same - ;; time using the process signal mask. - (inst break pending-interrupt-trap) - (emit-label ,label)))) + (inst mov (make-ea :qword + :base thread-base-tn + :disp (* 8 thread-pseudo-atomic-bits-slot)) + rbp-tn) + ,@forms + (inst xor (make-ea :qword + :base thread-base-tn + :disp (* 8 thread-pseudo-atomic-bits-slot)) + rbp-tn) + (inst jmp :z ,label) + ;; if PAI was set, interrupts were disabled at the same time + ;; using the process signal mask. + (inst break pending-interrupt-trap) + (emit-label ,label)))) #!-sb-thread (defmacro pseudo-atomic (&rest forms) (with-unique-names (label) `(let ((,label (gen-label))) - ;; FIXME: The MAKE-EA noise should become a MACROLET macro or - ;; something. (perhaps SVLB, for static variable low byte) - (inst or (make-ea :byte :disp (+ nil-value - (static-symbol-offset - '*pseudo-atomic-bits*) - (ash symbol-value-slot word-shift) - (- other-pointer-lowtag))) - (fixnumize 1)) - ,@forms - (inst xor (make-ea :byte :disp (+ nil-value - (static-symbol-offset - '*pseudo-atomic-bits*) - (ash symbol-value-slot word-shift) - (- other-pointer-lowtag))) - (fixnumize 1)) - (inst jmp :z ,label) - ;; if PAI was set, interrupts were disabled at the same time - ;; using the process signal mask. - (inst break pending-interrupt-trap) - (emit-label ,label)))) - - + ;; FIXME: The MAKE-EA noise should become a MACROLET macro or + ;; something. (perhaps SVLB, for static variable low byte) + (inst mov (make-ea :qword :disp (+ nil-value + (static-symbol-offset + '*pseudo-atomic-bits*) + (ash symbol-value-slot word-shift) + (- other-pointer-lowtag))) + rbp-tn) + ,@forms + (inst xor (make-ea :qword :disp (+ nil-value + (static-symbol-offset + '*pseudo-atomic-bits*) + (ash symbol-value-slot word-shift) + (- other-pointer-lowtag))) + rbp-tn) + (inst jmp :z ,label) + ;; if PAI was set, interrupts were disabled at the same time + ;; using the process signal mask. + (inst break pending-interrupt-trap) + (emit-label ,label)))) ;;;; indexed references diff --git a/src/compiler/x86/macros.lisp b/src/compiler/x86/macros.lisp index 9789ec2..aa6f1e7 100644 --- a/src/compiler/x86/macros.lisp +++ b/src/compiler/x86/macros.lisp @@ -354,14 +354,14 @@ (defmacro pseudo-atomic (&rest forms) (with-unique-names (label) `(let ((,label (gen-label))) - (inst or (make-ea :byte :disp (* 4 thread-pseudo-atomic-bits-slot)) - (fixnumize 1) :fs) + (inst mov (make-ea :dword :disp (* 4 thread-pseudo-atomic-bits-slot)) + ebp-tn :fs) ,@forms - (inst xor (make-ea :byte :disp (* 4 thread-pseudo-atomic-bits-slot)) - (fixnumize 1) :fs) + (inst xor (make-ea :dword :disp (* 4 thread-pseudo-atomic-bits-slot)) + ebp-tn :fs) (inst jmp :z ,label) - ;; if PAI was set, interrupts were disabled at the same - ;; time using the process signal mask. + ;; if PAI was set, interrupts were disabled at the same time + ;; using the process signal mask. (inst break pending-interrupt-trap) (emit-label ,label)))) @@ -369,14 +369,14 @@ (defmacro pseudo-atomic (&rest forms) (with-unique-names (label) `(let ((,label (gen-label))) - (inst or (make-ea-for-symbol-value *pseudo-atomic-bits* :byte) - (fixnumize 1)) + (inst mov (make-ea-for-symbol-value *pseudo-atomic-bits* :dword) + ebp-tn) ,@forms - (inst xor (make-ea-for-symbol-value *pseudo-atomic-bits* :byte) - (fixnumize 1)) + (inst xor (make-ea-for-symbol-value *pseudo-atomic-bits* :dword) + ebp-tn) (inst jmp :z ,label) - ;; if PAI was set, interrupts were disabled at the same - ;; time using the process signal mask. + ;; if PAI was set, interrupts were disabled at the same time + ;; using the process signal mask. (inst break pending-interrupt-trap) (emit-label ,label)))) diff --git a/src/runtime/pseudo-atomic.h b/src/runtime/pseudo-atomic.h index 9636e5b..40898c7 100644 --- a/src/runtime/pseudo-atomic.h +++ b/src/runtime/pseudo-atomic.h @@ -34,18 +34,19 @@ static inline int get_pseudo_atomic_atomic(struct thread *thread) { - return fixnum_value(SymbolValue(PSEUDO_ATOMIC_BITS, thread) & - make_fixnum(1)); + 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" (make_fixnum(1)), "m" (*p) + : "g" (~1), "m" (*p) : "memory"); } @@ -56,36 +57,39 @@ clear_pseudo_atomic_atomic(struct thread *thread) __asm__ __volatile__ ("and" LISPOBJ_ASM_SUFFIX " %0,%1" : - : "g" (~make_fixnum(1)), "m" (*p) + : "g" (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)); + 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" (make_fixnum(2)), "m" (*p) + : "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" (~make_fixnum(2)), "m" (*p) + : "g" (~1), "m" (*p) : "memory"); } diff --git a/version.lisp-expr b/version.lisp-expr index 5d1a5e3..ee218e0 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.27.7" +"1.0.27.8" -- 1.7.10.4