Changeset 5983


Ignore:
Timestamp:
Mar 7, 2007, 5:53:25 AM (18 years ago)
Author:
Gary Byers
Message:

Locks use spinlocks, try *spin-lock-tries* to obtain them before yielding.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/level-0/l0-misc.lisp

    r5956 r5983  
    466466           :void))
    467467
     468(defparameter *spin-lock-tries* 1)
     469
     470(defun %get-spin-lock (p)
     471  (let* ((self (%current-tcr))
     472         (n *spin-lock-tries*))
     473    (declare (fixnum n))
     474    (loop
     475      (dotimes (i n)
     476        (when (eql 0 (%ptr-store-conditional p 0 self))
     477          (return-from %get-spin-lock t)))
     478      (yield))))
     479
    468480(defun %lock-recursive-lock (lock &optional flag)
    469481  (with-macptrs ((p)
    470482                 (owner (%get-ptr lock target::lockptr.owner))
    471                  (signal (%get-ptr lock target::lockptr.signal)))
     483                 (signal (%get-ptr lock target::lockptr.signal))
     484                 (spin (%inc-ptr lock target::lockptr.spinlock)))
    472485    (%setf-macptr-to-object p (%current-tcr))
    473486    (if (istruct-typep flag 'lock-acquisition)
    474487      (setf (lock-acquisition.status flag) nil)
    475       (if (consp flag)
    476         (rplaca flag nil)
    477         (if flag (report-bad-arg flag '(or lock-acquisition cons)))))
     488      (if flag (report-bad-arg flag 'lock-acquisition)))
    478489    (loop
    479490      (without-interrupts
     
    481492         (incf (%get-natural lock target::lockptr.count))
    482493         (when flag
    483            (if (consp flag)
    484              (rplaca flag t)
    485              (setf (lock-acquisition.status flag) t)))
     494           (setf (lock-acquisition.status flag) t))
    486495         (return t))
    487        (when (eql 1 (%atomic-incf-ptr lock))
     496       (%get-spin-lock spin)
     497       (when (eql 1 (incf (%get-natural lock target::lockptr.avail)))
    488498         (setf (%get-ptr lock target::lockptr.owner) p
    489499               (%get-natural lock target::lockptr.count) 1)
     500         (setf (%get-ptr spin) (%null-ptr))
    490501         (if flag
    491            (if (consp flag)
    492              (rplaca flag t)
    493              (setf (lock-acquisition.status flag) t)))
     502           (setf (lock-acquisition.status flag) t))
    494503         (return t)))
     504      (setf (%get-ptr spin) (%null-ptr))
    495505      (%process-wait-on-semaphore-ptr signal 1 0 "waiting for lock"))))
    496506
    497507(defun %try-recursive-lock (lock &optional flag)
    498508  (with-macptrs ((p)
    499                  (owner (%get-ptr lock target::lockptr.owner)))
     509                 (owner (%get-ptr lock target::lockptr.owner))
     510                 (spin (%inc-ptr lock target::lockptr.spinlock)))
    500511    (%setf-macptr-to-object p (%current-tcr))
    501512    (if flag
     
    508519            (if flag (setf (lock-acquisition.status flag) t))
    509520            t)
    510            ((eql 0 (%ptr-store-conditional lock 0 1))
    511             (setf (%get-ptr lock target::lockptr.owner) p
    512                   (%get-natural lock target::lockptr.count) 1)
    513             (if flag (setf (lock-acquisition.status flag) t))
    514             t)
    515            (t nil)))))
     521           (t
     522            (let* ((win nil))
     523              (%get-spin-lock spin)
     524              (when (setq win (eql 1 (incf (%get-natural lock target::lockptr.avail))))
     525                (setf (%get-ptr lock target::lockptr.owner) p
     526                      (%get-natural lock target::lockptr.count) 1)
     527                (if flag (setf (lock-acquisition.status flag) t)))
     528              (setf (%get-ptr spin) (%null-ptr))
     529              win))))))
    516530
    517531
    518532(defun %unlock-recursive-lock (lock)
    519   (with-macptrs ((p)
    520                  (owner (%get-ptr lock target::lockptr.owner))
    521                  (signal (%get-ptr lock target::lockptr.signal)))
    522     (%setf-macptr-to-object p (%current-tcr))
    523     (unless (eql p owner)
     533  (with-macptrs ((signal (%get-ptr lock target::lockptr.signal))
     534                 (spin (%inc-ptr lock target::lockptr.spinlock)))
     535    (unless (eql (%get-object lock target::lockptr.owner) (%current-tcr))
    524536      (error 'not-lock-owner :lock lock))
    525537    (without-interrupts
    526538     (when (eql 0 (decf (the fixnum
    527539                          (%get-natural lock target::lockptr.count))))
     540       (%get-spin-lock spin)
    528541       (setf (%get-ptr lock target::lockptr.owner) (%null-ptr))
    529        (let* ((pending (1- (the fixnum (%atomic-swap-ptr lock 0)))))
     542       (let* ((pending (+ (the fixnum
     543                            (1- (the fixnum (%get-fixnum lock target::lockptr.avail))))
     544                          (the fixnum (%get-fixnum lock target::lockptr.waiting)))))
    530545         (declare (fixnum pending))
    531          (with-macptrs ((waiting (%inc-ptr lock target::lockptr.waiting)))
    532            (%atomic-incf-ptr-by waiting pending)
    533            (when (>= (the fixnum (%atomic-decf-ptr-if-positive waiting)) 0)
    534              (%signal-semaphore-ptr signal))))))
    535     nil))
     546         (setf (%get-natural lock target::lockptr.avail) 0
     547               (%get-natural lock target::lockptr.waiting) 0)
     548         (decf pending)
     549         (if (> pending 0)
     550           (setf (%get-natural lock target::lockptr.waiting) pending))
     551         (setf (%get-ptr spin) (%null-ptr))
     552         (if (>= pending 0)
     553           (%signal-semaphore-ptr signal))))))
     554    nil)
    536555
    537556
Note: See TracChangeset for help on using the changeset viewer.