Changeset 15500


Ignore:
Timestamp:
Nov 19, 2012, 5:41:59 PM (7 years ago)
Author:
gb
Message:

Try to clean up code which uses CMPXCHG: imm0 should contain the expected
value (which may or may not be the current value, as of a few cycles before
the CMPXCHG ...). In general, we don't need or want to repeat the CMPXCHG
in order to do a conditional store (failures aren't transient). In cases
where we repeat a CMPXCHG in a loop, ensure that the loop contains a PAUSE
instruction to work correctly with hyperthreading.

Change the x86 pc_luser_xp() to account for changes in
_SPstore_node_conditional and _SPset_hash_key_conditional.

Introduce a WITH-EXCEPTION-LOCK macro; refactor
%LOCK-RECURSIVE-LOCK-OBJECT and friends so that we can lock/unlock a
kernel lock (with no lisp LOCK object around it) without having to
call into the kernel. RECURSIVE-LOCK-WHOSTATE allows its argument to
be a string. (WITH-EXCEPTION-LOCK isn't used anywhere yet; it may be
a better alternative to things like WITHOUT-GCING, where (a) it's
preferable to delay exception handing in other threads than to let
the heap grow and (b) the body is short and doesn't try to grab other
locks.)

This is all intended to fix ticket:1030 in the trunk.

Location:
trunk/source
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/level-0/X86/X8632/x8632-misc.lisp

    r15226 r15500  
    454454    (sarl ($ x8632::fixnumshift) (% imm1))
    455455    (movl (@ object (% esp)) (% robject))
    456     @again
    457     (movl (@ (% robject) (% imm1)) (% eax))
    458     (cmpl (% eax) (% old))
    459     (jne @lose)
     456    (movl (% old) (% eax))
    460457    (lock)
    461458    (cmpxchgl (% new) (@ (% robject) (% imm1)))
    462     (jne @again)
     459    (jne @lose)
    463460    (movl ($ (target-t-value)) (% arg_z))
    464461    (mark-as-node temp0)
     
    470467
    471468(defx8632lapfunction set-%gcable-macptrs% ((ptr arg_z))
     469  (mark-as-node eax)
    472470  @again
    473471  (movl (@ (+ (target-nil-value) (x8632::kernel-global gcable-pointers))) (% eax))
     
    475473  (lock)
    476474  (cmpxchgl (% ptr) (@ (+ (target-nil-value) (x8632::kernel-global gcable-pointers))))
    477   (jne @again)
     475  (je @win)
     476  (pause)
     477  (jmp @again)
     478  @win
     479  (mark-as-imm eax)
    478480  (single-value-return))
    479481
     
    489491  (lock)
    490492  (cmpxchgl (% arg_z) (@ (+ (target-nil-value) (x8632::kernel-global gc-inhibit-count))))
    491   (jnz @again)
     493  (je @win)
     494  (pause)
     495  (jmp @again)
     496@win 
    492497  (single-value-return))
    493498
     
    527532    (lock)
    528533    (cmpxchgl (% arg_z) (@ (% node) (% imm1)))
    529     (jne @again))
     534    (je @win)
     535    (pause)
     536    (jmp @again)
     537    @win)
    530538  (mark-as-node temp0)
    531539  (single-value-return 3))
     
    542550    (lock)
    543551    (cmpxchgl (% imm1) (@ (% imm2)))
    544     (jne @again)
     552    (je @win)
     553    (pause)
     554    (jmp @again)
     555    @win
    545556    (box-fixnum imm1 arg_z))
    546557  (mark-as-node temp0)
     
    560571    (lock)
    561572    (cmpxchgl (% imm1) (@ (% imm2)))
    562     (jnz @again)
     573    (je @win)
     574    (pause)
     575    (jmp @again)
     576    @win
    563577    (box-fixnum imm1 arg_z))
    564578  (mark-as-node temp0)
     
    577591    (lock)
    578592    (cmpxchgl (% imm1) (@ (% imm2)))
    579     (jne @again)
     593    (je @win)
     594    (pause)
     595    (jmp @again)
     596    @win
    580597    (box-fixnum imm1 arg_z))
    581598  (mark-as-node temp0)
     
    596613    (lock)
    597614    (cmpxchgl (% imm1) (@ (% imm2)))
    598     (jnz @again)
     615    (jz @done)
     616    (pause)
     617    (jmp @again)
    599618    @done
    600619    (box-fixnum imm1 arg_z))
     
    623642    (mark-as-imm temp0)
    624643    (let ((imm1 temp0))
    625       @again
    626       (movl (@ (% imm2)) (% imm0))
    627       (box-fixnum imm0 imm0)
    628       (cmpl (% imm0) (% expected-oldval))
    629       (jne @done)
     644      (unbox-fixnum expected-oldval imm0)
    630645      (unbox-fixnum newval imm1)
    631646      (lock)
    632647      (cmpxchgl (% imm1) (@ (% imm2)))
    633       (jne @again)
    634       @done
    635       (movl (% imm0) (% arg_z)))
     648      (jne @lost)
     649      (movl (% expected-oldval) (% arg_z))
     650      (jmp @done)
     651      @lost
     652      (box-fixnum imm0 arg_z)
     653      @done)
    636654    (mark-as-node temp0))
    637655  (mark-as-node temp1)
     
    643661    (movl (@ ptr (% esp)) (% temp1))
    644662    (macptr-ptr temp1 address)
    645     @again
    646     (movl (@ (% address)) (% imm0))
    647     (cmpl (% imm0) (% expected-oldval))
    648     (jne @done)
     663    (movl (% expected-oldval) (% imm0))
    649664    (lock)
    650665    (cmpxchgl (% newval) (@ (% address)))
    651     (jne @again)
    652     @done
    653     (movl (% imm0) (% arg_z)))
     666    (cmovel (% expected-oldval) (% arg_z))
     667    (cmovnel (% imm0) (% arg_z)))
    654668  (mark-as-node temp0)
    655669  (single-value-return 3))
  • trunk/source/level-0/X86/x86-misc.lisp

    r15049 r15500  
    664664  (movq (@ offset (% rsp)) (% temp0))
    665665  (unbox-fixnum temp0 imm1)
    666   @again
    667   (movq (@ (% object) (% imm1)) (% rax))
    668   (cmpq (% rax) (% old))
     666  (movq (% old) (% rax))
     667  (lock)
     668  (cmpxchgq (% new) (@ (% object) (% imm1)))
    669669  (jne @lose)
    670   (lock)
    671   (cmpxchgq (% new) (@ (% object) (% imm1)))
    672   (jne @again)
    673670  (movl ($ (target-t-value)) (%l arg_z))
    674671  (single-value-return 3)
     
    677674  (single-value-return 3))
    678675
     676;;; AFAICT, this is GC-safe
    679677(defx86lapfunction set-%gcable-macptrs% ((ptr x8664::arg_z))
    680678  @again
     
    686684  (jne @again)
    687685  (single-value-return))
     686
     687#||
     688(defun set-%gcable-macptrs% (ptr)
     689  (with-exception-lock
     690      (%set-%gcable-macptrs% ptr)))
     691
     692(defx86lapfunction %set-%gcable-macptrs% ((ptr x8664::arg_z))
     693  ;; We must own the exception lock here.
     694  (movq (@ (+ (target-nil-value) (x8664::kernel-global gcable-pointers)))
     695        (% temp0))
     696  (movq (% temp0) (@ x8664::xmacptr.link (% ptr)))
     697  (movq (% ptr) (@ (+ (target-nil-value) (x8664::kernel-global gcable-pointers))))
     698  (single-value-return))
     699
     700||#
    688701
    689702;;; Atomically increment or decrement the gc-inhibit-count kernel-global
     
    698711  (lock)
    699712  (cmpxchgq (% arg_z) (@ (+ (target-nil-value) (x8664::kernel-global gc-inhibit-count))))
    700   (jnz @again)
     713  (jz @win)
     714  (pause)
     715  (jmp @again)
     716  @win
    701717  (single-value-return))
    702718
    703719;;; Atomically decrement or increment the gc-inhibit-count kernel-global
    704 ;;; (It's incremented if it's currently negative, incremented otherwise.)
     720;;; (It's incremented if it's currently negative, decremented otherwise.)
    705721;;; If it's incremented from -1 to 0, try to GC (maybe just a little.)
    706722(defx86lapfunction %unlock-gc-lock ()
     
    714730  (lock)
    715731  (cmpxchgq (% arg_z) (@ (+ (target-nil-value) (x8664::kernel-global gc-inhibit-count))))
    716   (jne @again)
     732  (je @win)
     733  (pause)
     734  (jmp @again)
     735  @win
    717736  (cmpq ($ '-1) (% rax))
    718737  (jne @done)
     
    727746;;; lock._value
    728747
    729 
    730 
    731 
    732748(defx86lapfunction %atomic-incf-node ((by arg_x) (node arg_y) (disp arg_z))
    733749  (check-nargs 3)
     
    748764  (lock)
    749765  (cmpxchgq (% imm1) (@ (% imm2)))
    750   (jne @again)
     766  (je @win)
     767  (pause)
     768  (jmp @again)
     769  @win
    751770  (box-fixnum imm1 arg_z)
    752771  (single-value-return))
     
    760779  (lock)
    761780  (cmpxchgq (% imm1) (@ (% imm2)))
    762   (jnz @again)
     781  (jz @win)
     782  (pause)
     783  (jmp @again)
     784  @win
    763785  (box-fixnum imm1 arg_z)
    764786  (single-value-return))
     
    772794  (lock)
    773795  (cmpxchgq (% imm1) (@ (% imm2)))
    774   (jnz @again)
     796  (jz @win)
     797  (pause)
     798  (jmp @again)
     799  @win
    775800  (box-fixnum imm1 arg_z)
    776801  (single-value-return))
     
    785810  (lock)
    786811  (cmpxchgq (% imm1) (@ (% imm2)))
    787   (jnz @again)
     812  (jz @done)
     813  (pause)
     814  (jmp @again)
    788815  @done
    789816  (box-fixnum imm1 arg_z)
     
    803830(defx86lapfunction %ptr-store-conditional ((ptr arg_x) (expected-oldval arg_y) (newval arg_z))
    804831  (macptr-ptr ptr imm2)
    805   @again
    806   (movq (@ (% imm2)) (% imm0))
    807   (box-fixnum imm0 temp0)
    808   (cmpq (% temp0) (% expected-oldval))
    809   (jne @done)
    810   (unbox-fixnum newval imm1)
     832  (unbox-fixnum expected-oldval imm0)
    811833  (lock)
    812834  (cmpxchgq (% imm1) (@ (% imm2)))
    813   (jne @again)
    814   @done
    815   (movq (% temp0) (% arg_z))
     835  (box-fixnum imm0 arg_z)
    816836  (single-value-return))
    817837
     
    819839  (let ((address imm1))
    820840    (macptr-ptr ptr address)
    821     @again
    822     (movq (@ (% address)) (% imm0))
    823     (cmpq (% imm0) (% expected-oldval))
    824     (jne @done)
     841    (movq (% expected-oldval) (% imm0))
    825842    (lock)
    826843    (cmpxchgq (% newval) (@ (% address)))
    827     (jne @again)
    828     @done
    829844    (movq (% imm0) (% arg_z))
    830845    (single-value-return)))
  • trunk/source/level-0/l0-aprims.lisp

    r14119 r15500  
    160160        (setf (%svref r target::lock.whostate-cell)
    161161              (%lock-whostate-string "Lock wait" r)))
    162     (report-bad-arg r 'recursive-lock)))
     162    (if (typep r 'string)
     163      r
     164      (report-bad-arg r 'recursive-lock))))
    163165
    164166
  • trunk/source/level-0/l0-misc.lisp

    r14619 r15500  
    572572
    573573
     574(eval-when (:compile-toplevel)
     575  (declaim (inline %lock-recursive-lock-ptr %unlock-recursive-lock-ptr)))
    574576
    575577#-futex
     578(defun %lock-recursive-lock-ptr (ptr lock flag)
     579  (with-macptrs ((p)
     580                 (owner (%get-ptr ptr target::lockptr.owner))
     581                 (signal (%get-ptr ptr target::lockptr.signal))
     582                 (spin (%inc-ptr ptr target::lockptr.spinlock)))
     583    (%setf-macptr-to-object p (%current-tcr))
     584    (if (istruct-typep flag 'lock-acquisition)
     585      (setf (lock-acquisition.status flag) nil)
     586      (if flag (report-bad-arg flag 'lock-acquisition)))
     587    (loop
     588      (without-interrupts
     589       (when (eql p owner)
     590         (incf (%get-natural ptr target::lockptr.count))
     591         (when flag
     592           (setf (lock-acquisition.status flag) t))
     593         (return t))
     594       (%get-spin-lock spin)
     595       (when (eql 1 (incf (%get-natural ptr target::lockptr.avail)))
     596         (setf (%get-ptr ptr target::lockptr.owner) p
     597               (%get-natural ptr target::lockptr.count) 1)
     598         (setf (%get-natural spin 0) 0)
     599         (if flag
     600           (setf (lock-acquisition.status flag) t))
     601         (return t))
     602       (setf (%get-natural spin 0) 0))
     603      (%process-wait-on-semaphore-ptr signal 1 0 (recursive-lock-whostate lock)))))
     604
     605#+futex
     606(defun %lock-recursive-lock-ptr (ptr lock flag)
     607  (if (istruct-typep flag 'lock-acquisition)
     608    (setf (lock-acquisition.status flag) nil)
     609    (if flag (report-bad-arg flag 'lock-acquisition)))
     610  (let* ((self (%current-tcr))
     611         (level *interrupt-level*))
     612    (declare (fixnum self))
     613    (without-interrupts
     614     (cond ((eql self (%get-object ptr target::lockptr.owner))
     615            (incf (%get-natural ptr target::lockptr.count)))
     616           (t (%lock-futex ptr level lock #'recursive-lock-whostate)
     617              (%set-object ptr target::lockptr.owner self)
     618              (setf (%get-natural ptr target::lockptr.count) 1)))
     619     (when flag
     620       (setf (lock-acquisition.status flag) t))
     621     t)))
     622 
     623
    576624(defun %lock-recursive-lock-object (lock &optional flag)
    577   (let* ((ptr (recursive-lock-ptr lock)))
    578     (with-macptrs ((p)
    579                    (owner (%get-ptr ptr target::lockptr.owner))
    580                    (signal (%get-ptr ptr target::lockptr.signal))
    581                    (spin (%inc-ptr ptr target::lockptr.spinlock)))
    582       (%setf-macptr-to-object p (%current-tcr))
    583       (if (istruct-typep flag 'lock-acquisition)
    584         (setf (lock-acquisition.status flag) nil)
    585         (if flag (report-bad-arg flag 'lock-acquisition)))
    586       (loop
    587         (without-interrupts
    588          (when (eql p owner)
    589            (incf (%get-natural ptr target::lockptr.count))
    590            (when flag
    591              (setf (lock-acquisition.status flag) t))
    592            (return t))
    593          (%get-spin-lock spin)
    594          (when (eql 1 (incf (%get-natural ptr target::lockptr.avail)))
    595            (setf (%get-ptr ptr target::lockptr.owner) p
    596                  (%get-natural ptr target::lockptr.count) 1)
    597            (setf (%get-natural spin 0) 0)
    598            (if flag
    599              (setf (lock-acquisition.status flag) t))
    600            (return t))
    601          (setf (%get-natural spin 0) 0))
    602         (%process-wait-on-semaphore-ptr signal 1 0 (recursive-lock-whostate lock))))))
     625  (%lock-recursive-lock-ptr (recursive-lock-ptr lock) lock flag))
     626
    603627
    604628
     
    655679
    656680
    657 #+futex
    658 (defun %lock-recursive-lock-object (lock &optional flag)
    659   (if (istruct-typep flag 'lock-acquisition)
    660     (setf (lock-acquisition.status flag) nil)
    661     (if flag (report-bad-arg flag 'lock-acquisition)))
    662   (let* ((self (%current-tcr))
    663          (level *interrupt-level*)
    664          (ptr (recursive-lock-ptr lock)))
    665     (declare (fixnum self))
    666     (without-interrupts
    667      (cond ((eql self (%get-object ptr target::lockptr.owner))
    668             (incf (%get-natural ptr target::lockptr.count)))
    669            (t (%lock-futex ptr level lock #'recursive-lock-whostate)
    670               (%set-object ptr target::lockptr.owner self)
    671               (setf (%get-natural ptr target::lockptr.count) 1)))
    672      (when flag
    673        (setf (lock-acquisition.status flag) t))
    674      t)))
     681
     682
     683
    675684
    676685         
     
    733742
    734743#-futex
    735 (defun %unlock-recursive-lock-object (lock)
    736   (let* ((ptr (%svref lock target::lock._value-cell)))
    737     (with-macptrs ((signal (%get-ptr ptr target::lockptr.signal))
    738                    (spin (%inc-ptr ptr target::lockptr.spinlock)))
    739       (unless (eql (%get-object ptr target::lockptr.owner) (%current-tcr))
    740         (error 'not-lock-owner :lock lock))
    741       (without-interrupts
    742        (when (eql 0 (decf (the fixnum
    743                             (%get-natural ptr target::lockptr.count))))
    744          (%get-spin-lock spin)
    745          (setf (%get-ptr ptr target::lockptr.owner) (%null-ptr))
    746          (let* ((pending (+ (the fixnum
    747                               (1- (the fixnum (%get-fixnum ptr target::lockptr.avail))))
    748                             (the fixnum (%get-fixnum ptr target::lockptr.waiting)))))
    749            (declare (fixnum pending))
    750            (setf (%get-natural ptr target::lockptr.avail) 0
    751                  (%get-natural ptr target::lockptr.waiting) 0)
    752            (decf pending)
    753            (if (> pending 0)
    754              (setf (%get-natural ptr target::lockptr.waiting) pending))
    755            (setf (%get-ptr spin) (%null-ptr))
    756            (if (>= pending 0)
    757              (%signal-semaphore-ptr signal)))))))
    758   nil)
    759 
    760 
    761 
    762 #+futex
    763 (defun %unlock-recursive-lock-object (lock)
    764   (let* ((ptr (%svref lock target::lock._value-cell)))
     744(defun %unlock-recursive-lock-ptr (ptr lock)
     745  (with-macptrs ((signal (%get-ptr ptr target::lockptr.signal))
     746                 (spin (%inc-ptr ptr target::lockptr.spinlock)))
    765747    (unless (eql (%get-object ptr target::lockptr.owner) (%current-tcr))
    766748      (error 'not-lock-owner :lock lock))
     
    768750     (when (eql 0 (decf (the fixnum
    769751                          (%get-natural ptr target::lockptr.count))))
    770     (setf (%get-natural ptr target::lockptr.owner) 0)
    771     (%unlock-futex ptr))))
     752       (%get-spin-lock spin)
     753       (setf (%get-ptr ptr target::lockptr.owner) (%null-ptr))
     754       (let* ((pending (+ (the fixnum
     755                            (1- (the fixnum (%get-fixnum ptr target::lockptr.avail))))
     756                          (the fixnum (%get-fixnum ptr target::lockptr.waiting)))))
     757         (declare (fixnum pending))
     758         (setf (%get-natural ptr target::lockptr.avail) 0
     759               (%get-natural ptr target::lockptr.waiting) 0)
     760         (decf pending)
     761         (if (> pending 0)
     762           (setf (%get-natural ptr target::lockptr.waiting) pending))
     763         (setf (%get-ptr spin) (%null-ptr))
     764         (if (>= pending 0)
     765           (%signal-semaphore-ptr signal)))))
     766    nil))
     767
     768
     769
     770
     771#+futex
     772(defun %unlock-recursive-lock-ptr (ptr lock)
     773  (unless (eql (%get-object ptr target::lockptr.owner) (%current-tcr))
     774    (error 'not-lock-owner :lock lock))
     775  (without-interrupts
     776   (when (eql 0 (decf (the fixnum
     777                        (%get-natural ptr target::lockptr.count))))
     778     (setf (%get-natural ptr target::lockptr.owner) 0)
     779     (%unlock-futex ptr)))
    772780  nil)
     781
     782(defun %unlock-recursive-lock-object (lock)
     783  (%unlock-recursive-lock-ptr (%svref lock target::lock._value-cell) lock))
    773784
    774785
  • trunk/source/lib/macros.lisp

    r15431 r15500  
    25362536the lock held."
    25372537  (declare (ignore whostate))
    2538     (let* ((locked (gensym))
    2539            (l (gensym)))
    2540       `  (with-lock-context
    2541            (let ((,locked (make-lock-acquisition))
    2542              (,l ,lock))
    2543         (declare (dynamic-extent ,locked))
    2544         (unwind-protect
    2545              (progn
    2546                (%lock-recursive-lock-object ,l ,locked )
    2547                ,@body)
    2548           (when (lock-acquisition.status ,locked) (%unlock-recursive-lock-object ,l)))))))
     2538  (let* ((locked (gensym))
     2539         (l (gensym)))
     2540    `  (with-lock-context
     2541         (let ((,locked (make-lock-acquisition))
     2542               (,l ,lock))
     2543           (declare (dynamic-extent ,locked))
     2544           (unwind-protect
     2545                (progn
     2546                  (%lock-recursive-lock-object ,l ,locked )
     2547                  ,@body)
     2548             (when (lock-acquisition.status ,locked) (%unlock-recursive-lock-object ,l)))))))
     2549
     2550 
     2551(defmacro with-exception-lock (&body body)
     2552  (let* ((p (gensym)))
     2553    `(with-macptrs (,p)     
     2554      (%get-kernel-global-ptr 'exception-lock ,p)
     2555      (%lock-recursive-lock-ptr ,p "global exception lock wait" nil)
     2556      ;; Among other things, we can't be interrupted by another
     2557      ;; thread now.
     2558      (unwind-protect
     2559           (progn
     2560             ,@body)
     2561        (%unlock-recursive-lock-ptr ,p "global exception lock")))))
     2562
    25492563
    25502564(defmacro with-lock-grabbed-maybe ((lock &optional
  • trunk/source/lisp-kernel/x86-asmutils32.s

    r15470 r15500  
    8888        __(lock)
    8989        __(cmpxchg %ecx,(%edx))
    90         __(jnz 0b)
    91         __(andl 8(%esp),%eax)
     90        __(jz 1f)
     91        __(pause)
     92        __(jmp 0b)
     931:      __(andl 8(%esp),%eax)
    9294        __(ret)
    9395_endfn
     
    104106        __(lock)
    105107        __(cmpxchg %ecx,(%edx))
    106         __(jnz 0b)
    107         __(movl %ecx,%eax)
     108        __(jz 1f)
     109        __(pause)
     110        __(jmp 0b)
     1111:      __(movl %ecx,%eax)
    108112        __(ret)
    109113_endfn
  • trunk/source/lisp-kernel/x86-asmutils64.s

    r15470 r15500  
    104104        __(lock)
    105105        __(cmpxchg %carg2,(%carg0))
    106         __(jnz 0b)
    107         __(andq %carg1,%cret)
     106        __(jz 1f)
     107        __(pause)
     108        __(jmp 0b)
     1091:      __(andq %carg1,%cret)
    108110        __(ret)
    109111_endfn
     
    119121        __(lock)
    120122        __(cmpxchg %carg2,(%carg0))
    121         __(jnz 0b)
    122         __(movq %carg2,%cret)
     123        __(jz 1f)
     124        __(pause)
     125        __(jmp 0b)
     1261:      __(movq %carg2,%cret)
    123127        __(ret)
    124128_endfn
  • trunk/source/lisp-kernel/x86-exceptions.c

    r15472 r15500  
    26102610        return;
    26112611      }
    2612       if ((program_counter < &egc_set_hash_key_conditional_success_test) ||
    2613           ((program_counter == &egc_set_hash_key_conditional_success_test) &&
    2614            !(eflags_register(xp) & (1 << X86_ZERO_FLAG_BIT)))) {
    2615         /* Back up the PC, try again */
     2612      if (program_counter < &egc_set_hash_key_conditional_success_test) {
     2613        /* Back up the PC, try again.  This is necessary since a pending
     2614           GC may cause the value in %eax/%rax to move and backing up
     2615           will reload %eax/%rax from a node register before trying the
     2616           cmpxchg.
     2617        */
    26162618        xpPC(xp) = (LispObj) &egc_set_hash_key_conditional_retry;
     2619        return;
     2620      }
     2621      if ((program_counter == &egc_set_hash_key_conditional_success_test) &&
     2622          !(eflags_register(xp) & (1 << X86_ZERO_FLAG_BIT))) {
     2623        /* Conditional store failed.  Return NIL. */
     2624        LispObj *sp = (LispObj *)xpGPR(xp,Isp), ra = *sp++;
     2625        xpGPR(xp,Iarg_z) = lisp_nil;
     2626        xpPC(xp) = ra;
     2627        xpGPR(xp,Isp)=(LispObj)sp;
    26172628        return;
    26182629      }
     
    26332644        return;
    26342645      }
    2635       if ((program_counter < &egc_store_node_conditional_success_test) ||
    2636           ((program_counter == &egc_store_node_conditional_success_test) &&
    2637            !(eflags_register(xp) & (1 << X86_ZERO_FLAG_BIT)))) {
    2638         /* Back up the PC, try again */
     2646      if (program_counter < &egc_store_node_conditional_success_test) {
     2647        /* Back up the PC, try again.  Again, this is necessary because
     2648           we're possibly keeping a node in %eax/%rax and haven't completed
     2649           the cmpxchg yet. */
    26392650        xpPC(xp) = (LispObj) &egc_store_node_conditional_retry;
    26402651        return;
    26412652      }
     2653      if ((program_counter == &egc_store_node_conditional_success_test) &&
     2654           !(eflags_register(xp) & (1 << X86_ZERO_FLAG_BIT))) {
     2655        /* cmpxchg failed.  Return NIL. */
     2656        LispObj *sp = (LispObj *)xpGPR(xp,Isp), ra = *sp++;
     2657        xpGPR(xp,Iarg_z) = lisp_nil;
     2658        xpPC(xp) = ra;
     2659        xpGPR(xp,Isp)=(LispObj)sp;
     2660        return;
     2661      }
     2662
    26422663      if (program_counter >= &egc_store_node_conditional_success_end) {
    26432664        return;
  • trunk/source/lisp-kernel/x86-spentry32.s

    r15433 r15500  
    18461846
    18471847/* This is a little trickier: if this is interrupted, we need to know  */
    1848 /* whether or not the STORE-CONDITIONAL (cmpxchgq) has won or not.    */
     1848/* whether or not the STORE-CONDITIONAL (cmpxchgl) has won or not.    */
    18491849/* If we're interrupted   before the PC has reached the "success_test" label, */
    18501850/* repeat (luser the PC back to store_node_conditional_retry.)  If
     
    18601860        .globl C(egc_store_node_conditional_retry)
    18611861C(egc_store_node_conditional_retry):     
    1862 0:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
    1863         __(movl misc_data_offset(%temp1,%temp0),%imm0)
    1864         __(jne 9f)
     18620:      __(movl %arg_y,%imm0)
    18651863        __(lock)
    18661864        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
    18671865        .globl C(egc_store_node_conditional_success_test)
    18681866C(egc_store_node_conditional_success_test):
    1869         __(jne 0b)
     1867        __(jne 9f)
    18701868        __(leal misc_data_offset(%temp1,%temp0),%imm0)
    18711869        __(subl lisp_global(ref_base),%imm0)
     
    19001898        .globl C(egc_set_hash_key_conditional_retry)
    19011899C(egc_set_hash_key_conditional_retry):         
    1902 0:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
    1903         __(movl misc_data_offset(%temp1,%temp0),%imm0)
    1904         __(jne 9f)
     19000:      __(movl %arg_y,%imm0)
    19051901        __(lock)
    19061902        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
    19071903        .globl C(egc_set_hash_key_conditional_success_test)
    19081904C(egc_set_hash_key_conditional_success_test):
    1909         __(jne 0b)
     1905        __(jne 9f)
    19101906        __(leal misc_data_offset(%temp1,%temp0),%imm0)
    19111907        __(subl lisp_global(ref_base),%imm0)
  • trunk/source/lisp-kernel/x86-spentry64.s

    r15458 r15500  
    18991899        .globl C(egc_store_node_conditional_retry)
    19001900C(egc_store_node_conditional_retry):     
    1901 0:      __(movq (%arg_x,%imm1),%temp1)
    1902         __(cmpq %arg_y,%temp1)
    1903         __(movq %temp1,%imm0)
    1904         __(jne 9f)
     19010:      __(movq %arg_y,%imm0)
    19051902        __(lock)
    19061903        __(cmpxchgq %arg_z,(%arg_x,%imm1))
    19071904        .globl C(egc_store_node_conditional_success_test)
    19081905C(egc_store_node_conditional_success_test):
    1909         __(jne 0b)
     1906        __(jne 9f)
    19101907        __(lea (%arg_x,%imm1),%imm0)
    19111908        __(subq lisp_global(ref_base),%imm0)
     
    19381935C(egc_set_hash_key_conditional_retry):         
    19391936        __(unbox_fixnum(%temp0,%imm1))
    1940 0:      __(movq (%arg_x,%imm1),%temp1)
    1941         __(cmpq %arg_y,%temp1)
    1942         __(movq %temp1,%imm0)
    1943         __(jne 9f)
     19370:      __(movq %arg_y,%imm0)
    19441938        __(lock)
    19451939        __(cmpxchgq %arg_z,(%arg_x,%imm1))
    19461940        .globl C(egc_set_hash_key_conditional_success_test)
    19471941C(egc_set_hash_key_conditional_success_test):
    1948         __(jne 0b)
     1942        __(jne 9f)
    19491943        __(lea (%arg_x,%imm1),%imm0)
    19501944        __(subq lisp_global(ref_base),%imm0)
Note: See TracChangeset for help on using the changeset viewer.