Changeset 10503
- Timestamp:
- 08/20/08 10:37:19 (3 months ago)
- Files:
-
- branches/working-0711/ccl/level-0/l0-aprims.lisp (modified) (1 diff)
- branches/working-0711/ccl/level-0/l0-misc.lisp (modified) (20 diffs)
- branches/working-0711/ccl/level-1/l1-aprims.lisp (modified) (1 diff)
- branches/working-0711/ccl/level-1/l1-lisp-threads.lisp (modified) (2 diffs)
- branches/working-0711/ccl/level-1/l1-processes.lisp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/working-0711/ccl/level-0/l0-aprims.lisp
r10391 r10503 133 133 (make-lock nil)) 134 134 135 (defun %make-lock (pointer name) 136 (gvector :lock pointer 'recursive-lock 0 name nil nil)) 137 135 138 (defun make-lock (&optional name) 136 139 "Create and return a lock object, which can be used for synchronization 137 140 between threads." 138 ( gvector :lock (%make-recursive-lock-ptr) 'recursive-lock 0 name nil nil))141 (%make-lock (%make-recursive-lock-ptr) name)) 139 142 140 143 (defun lock-name (lock) branches/working-0711/ccl/level-0/l0-misc.lisp
r9942 r10503 22 22 (defparameter *lock-conses* ()) 23 23 24 ;; Cold-load lossage. 25 #+lock-accounting 26 (setq *lock-conses* (make-list 20)) 27 28 ;;; Per-thread consing, for lock-ownership tracking. 29 #+lock-accounting 30 (defun %lock-cons (x y) 31 (let* ((cell (prog1 *lock-conses* 32 (setq *lock-conses* (cdr *lock-conses*))))) 33 (if cell 34 (progn 35 (rplaca cell x) 36 (rplacd cell y)) 37 (cons x y)))) 24 38 25 39 26 … … 529 516 (declaim (inline note-lock-wait note-lock-held note-lock-released))) 530 517 531 (defun note-lock-wait (lock) 532 #+lock-accounting 533 (setq *locks-pending* (%lock-cons lock *locks-pending*)) 534 #-lock-accounting (declare (ignore lock))) 535 536 (defun note-lock-held () 537 #+lock-accounting 538 (let* ((p *locks-pending*)) 539 (setq *locks-pending* (cdr *locks-pending*)) 540 (rplacd p *locks-held*) 541 (setq *locks-held* p))) 542 543 (defun note-lock-released () 544 #+lock-accounting 545 (setf (car *locks-held*) nil 546 *locks-held* (cdr *locks-held*))) 518 519 520 547 521 548 522 #-futex … … 557 531 (setf (lock-acquisition.status flag) nil) 558 532 (if flag (report-bad-arg flag 'lock-acquisition))) 559 (note-lock-wait lock)560 533 (loop 561 534 (without-interrupts 562 535 (when (eql p owner) 563 536 (incf (%get-natural ptr target::lockptr.count)) 564 (note-lock-held)565 537 (when flag 566 538 (setf (lock-acquisition.status flag) t)) … … 571 543 (%get-natural ptr target::lockptr.count) 1) 572 544 (setf (%get-natural spin 0) 0) 573 (note-lock-held)574 545 (if flag 575 546 (setf (lock-acquisition.status flag) t)) … … 635 606 (ptr (recursive-lock-ptr lock))) 636 607 (declare (fixnum self)) 637 (note-lock-wait lock)638 608 (without-interrupts 639 609 (cond ((eql self (%get-object ptr target::lockptr.owner)) … … 642 612 (%set-object ptr target::lockptr.owner self) 643 613 (setf (%get-natural ptr target::lockptr.count) 1))) 644 (note-lock-held)645 614 (when flag 646 615 (setf (lock-acquisition.status flag) t)) … … 723 692 (when (eql 0 (decf (the fixnum 724 693 (%get-natural ptr target::lockptr.count)))) 725 (note-lock-released)726 694 (%get-spin-lock spin) 727 695 (setf (%get-ptr ptr target::lockptr.owner) (%null-ptr)) … … 750 718 (when (eql 0 (decf (the fixnum 751 719 (%get-natural ptr target::lockptr.count)))) 752 (note-lock-released)753 720 (setf (%get-natural ptr target::lockptr.owner) 0) 754 721 (%unlock-futex ptr)))) … … 838 805 (tcr (%current-tcr))) 839 806 (declare (fixnum tcr)) 840 (note-lock-wait lock)841 807 (without-interrupts 842 808 (%get-spin-lock ptr) ;(%get-spin-lock (%inc-ptr ptr target::rwlock.spin)) … … 845 811 (incf (%get-signed-natural ptr target::rwlock.state)) 846 812 (setf (%get-natural ptr target::rwlock.spin) 0) 847 (note-lock-held)848 813 (if flag 849 814 (setf (lock-acquisition.status flag) t)) … … 852 817 ((eql 0 (%get-signed-natural ptr target::rwlock.state)) 853 818 ;; That wasn't so bad, was it ? We have the spinlock now. 854 (note-lock-held)855 819 (setf (%get-signed-natural ptr target::rwlock.state) 1 856 820 (%get-natural ptr target::rwlock.spin) 0) … … 873 837 (tcr (%current-tcr))) 874 838 (declare (fixnum tcr)) 875 (note-lock-wait lock)876 839 (without-interrupts 877 840 (%lock-futex ptr level lock nil) … … 880 843 (incf (%get-signed-natural ptr target::rwlock.state)) 881 844 (%unlock-futex ptr) 882 (note-lock-held)883 845 (if flag 884 846 (setf (lock-acquisition.status flag) t)) … … 887 849 ((eql 0 (%get-signed-natural ptr target::rwlock.state)) 888 850 ;; That wasn't so bad, was it ? We have the spinlock now. 889 (note-lock-held)890 851 (setf (%get-signed-natural ptr target::rwlock.state) 1) 891 852 (%unlock-futex ptr) … … 917 878 (tcr (%current-tcr))) 918 879 (declare (fixnum tcr)) 919 (note-lock-wait lock)920 880 (without-interrupts 921 881 (%get-spin-lock ptr) ;(%get-spin-lock (%inc-ptr ptr target::rwlock.spin)) … … 933 893 (the fixnum (1- state)) 934 894 (%get-natural ptr target::rwlock.spin) 0) 935 (note-lock-held)936 895 (if flag 937 896 (setf (lock-acquisition.status flag) t)) … … 953 912 (tcr (%current-tcr))) 954 913 (declare (fixnum tcr)) 955 (note-lock-wait lock)956 914 (without-interrupts 957 915 (%lock-futex ptr level lock nil) … … 968 926 (setf (%get-signed-natural ptr target::rwlock.state) 969 927 (the fixnum (1- state))) 970 (note-lock-held)971 928 (%unlock-futex ptr) 972 929 (if flag … … 1028 985 ;; are cleared here (they can't be changed from another thread 1029 986 ;; until this thread releases the spinlock.) 1030 (note-lock-released)1031 987 (setf (%get-signed-natural ptr target::rwlock.writer) 0) 1032 988 (let* ((nwriters (%get-natural ptr target::rwlock.blocked-writers)) … … 1065 1021 (setf (%get-signed-natural ptr target::rwlock.state) state) 1066 1022 (when (zerop state) 1067 (note-lock-released)1068 1023 (setf (%get-signed-natural ptr target::rwlock.writer) 0) 1069 1024 (let* ((nwriters (%get-natural ptr target::rwlock.blocked-writers)) branches/working-0711/ccl/level-1/l1-aprims.lisp
r9943 r10503 40 40 (record-source-file symbol 'variable) 41 41 symbol)) 42 43 (defstatic *kernel-tcr-area-lock* (%make-lock (%null-ptr) "Kernel tcr-area-lock")) 44 45 (defstatic *kernel-exception-lock* (%make-lock (%null-ptr) "Kernel exception-lock")) 46 47 (def-ccl-pointers kernel-locks () 48 (let* ((p (recursive-lock-ptr *kernel-tcr-area-lock*)) 49 (q (recursive-lock-ptr *kernel-exception-lock*))) 50 (%revive-macptr p) 51 (%revive-macptr q) 52 (%get-kernel-global-ptr area-lock p) 53 (%get-kernel-global-ptr exception-lock q))) 42 54 43 55 (def-standard-initial-binding *package*) branches/working-0711/ccl/level-1/l1-lisp-threads.lisp
r9947 r10503 35 35 36 36 (defun %nanosleep (seconds nanoseconds) 37 (rlet ((a :timespec) 38 (b :timespec)) 39 (setf (pref a :timespec.tv_sec) seconds 40 (pref a :timespec.tv_nsec) nanoseconds) 41 (let* ((aptr a) 42 (bptr b)) 43 (loop 44 (let* ((result 45 (external-call #+darwin-target "_nanosleep" 46 #-darwin-target "nanosleep" 47 :address aptr 48 :address bptr 49 :signed-fullword))) 50 (declare (type (signed-byte 32) result)) 51 (if (and (< result 0) 52 (eql (%get-errno) (- #$EINTR))) 53 ;; x86-64 Leopard bug. 54 (let* ((asec (pref aptr :timespec.tv_sec)) 55 (bsec (pref bptr :timespec.tv_sec))) 56 (if (and (>= bsec 0) 57 (or (< bsec asec) 58 (and (= bsec asec) 59 (< (pref bptr :timespec.tv_nsec) 60 (pref aptr :timespec.tv_nsec))))) 61 (psetq aptr bptr bptr aptr) 62 (return))) 63 (return))))))) 37 (with-process-whostate ("Sleep") 38 (rlet ((a :timespec) 39 (b :timespec)) 40 (setf (pref a :timespec.tv_sec) seconds 41 (pref a :timespec.tv_nsec) nanoseconds) 42 (let* ((aptr a) 43 (bptr b)) 44 (loop 45 (let* ((result 46 (external-call #+darwin-target "_nanosleep" 47 #-darwin-target "nanosleep" 48 :address aptr 49 :address bptr 50 :signed-fullword))) 51 (declare (type (signed-byte 32) result)) 52 (if (and (< result 0) 53 (eql (%get-errno) (- #$EINTR))) 54 ;; x86-64 Leopard bug. 55 (let* ((asec (pref aptr :timespec.tv_sec)) 56 (bsec (pref bptr :timespec.tv_sec))) 57 (if (and (>= bsec 0) 58 (or (< bsec asec) 59 (and (= bsec asec) 60 (< (pref bptr :timespec.tv_nsec) 61 (pref aptr :timespec.tv_nsec))))) 62 (psetq aptr bptr bptr aptr) 63 (return))) 64 (return)))))))) 64 65 65 66 … … 315 316 (%fixnum-ref tcr target::tcr.flags)) 316 317 317 (defun tcr-exhausted-p (tcr) 318 (or (null tcr) 319 (eql tcr 0) 320 (unless (logbitp arch::tcr-flag-bit-awaiting-preset 321 (the fixnum (tcr-flags tcr))) 322 (let* ((vs-area (%fixnum-ref tcr target::tcr.vs-area))) 323 (declare (fixnum vs-area)) 324 (or (zerop vs-area) 325 (eq (%fixnum-ref vs-area target::area.high) 326 (%fixnum-ref tcr target::tcr.save-vsp))))))) 318 327 319 328 320 (defun thread-exhausted-p (thread) 329 321 (or (null thread) 330 ( tcr-exhausted-p(lisp-thread.tcr thread))))322 (null (lisp-thread.tcr thread)))) 331 323 332 324 (defun thread-total-run-time (thread) branches/working-0711/ccl/level-1/l1-processes.lisp
r10393 r10503 211 211 (thread-exhausted-p thread)))) 212 212 213 213 ;;; This should be way more concerned about being correct and thread-safe 214 ;;; than about being quick: it's generally only called while printing 215 ;;; or debugging, and there are all kinds of subtle race conditions 216 ;;; here. 214 217 (defun process-whostate (p) 215 218 "Return a string which describes the status of a specified process." 216 (if (process-exhausted-p p) 217 "Exhausted" 218 (symbol-value-in-process '*whostate* p))) 219 (let* ((ip *initial-process*)) 220 (cond ((eq p *current-process*) 221 (if (%tcr-binding-location (%current-tcr) '*whostate*) 222 *whostate* 223 (if (eq p ip) 224 "Active" 225 "Reset"))) 226 (t 227 (without-interrupts 228 (with-lock-grabbed (*kernel-exception-lock*) 229 (with-lock-grabbed (*kernel-tcr-area-lock*) 230 (let* ((tcr (process-tcr p))) 231 (if tcr 232 (unwind-protect 233 (let* ((loc nil)) 234 (%suspend-tcr tcr) 235 (setq loc (%tcr-binding-location tcr '*whostate*)) 236 (if loc 237 (%fixnum-ref loc) 238 (if (eq p ip) 239 "Active" 240 "Reset"))) 241 (%resume-tcr tcr)) 242 "Exhausted"))))))))) 219 243 220 244 (defun (setf process-whostate) (new p) … … 243 267 (if (eq process *current-process*) 244 268 (symbol-value sym) 245 (symbol-value-in-tcr sym (process-tcr process)))) 269 (let* ((val 270 (without-interrupts 271 (with-lock-grabbed (*kernel-exception-lock*) 272 (with-lock-grabbed (*kernel-tcr-area-lock*) 273 (let* ((tcr (process-tcr process))) 274 (if tcr 275 (symbol-value-in-tcr sym tcr) 276 (%sym-global-value sym)))))))) 277 (if (eq val (%unbound-marker)) 278 ;; This might want to be a CELL-ERROR. 279 (error "~S is unbound in ~S." sym process) 280 val)))) 246 281 247 282 (defun (setf symbol-value-in-process) (value sym process) 248 283 (if (eq process *current-process*) 249 284 (setf (symbol-value sym) value) 250 (setf (symbol-value-in-tcr sym (process-tcr process)) value))) 285 (with-lock-grabbed (*kernel-exception-lock*) 286 (with-lock-grabbed (*kernel-tcr-area-lock*) 287 (let* ((tcr (process-tcr process))) 288 (if tcr 289 (setf (symbol-value-in-tcr sym tcr) value) 290 (%set-sym-global-value sym value))))))) 251 291 252 292
