Changeset 7723
- Timestamp:
- Nov 24, 2007, 6:26:27 PM (17 years ago)
- File:
-
- 1 edited
-
branches/working-0711/ccl/level-0/l0-misc.lisp (modified) (31 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/working-0711/ccl/level-0/l0-misc.lisp
r7675 r7723 53 53 (declaim (inline %lock-futex %unlock-futex))) 54 54 55 ; Miscellany.55 ;;; Miscellany. 56 56 57 57 (defun memq (item list) … … 529 529 (yield)))) 530 530 531 (eval-when (:compile-toplevel :execute) 532 (declaim (inline note-lock-wait note-lock-held note-lock-released))) 533 534 (defun note-lock-wait (lock) 535 (setq *locks-pending* (%lock-cons lock *locks-pending*))) 536 537 (defun note-lock-held () 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 (setf (car *locks-held*) nil 545 *locks-held* (cdr *locks-held*))) 546 531 547 #-futex 532 (defun %lock-recursive-lock (lock &optional flag) 533 (with-macptrs ((p) 534 (owner (%get-ptr lock target::lockptr.owner)) 535 (signal (%get-ptr lock target::lockptr.signal)) 536 (spin (%inc-ptr lock target::lockptr.spinlock))) 537 (%setf-macptr-to-object p (%current-tcr)) 538 (if (istruct-typep flag 'lock-acquisition) 539 (setf (lock-acquisition.status flag) nil) 540 (if flag (report-bad-arg flag 'lock-acquisition))) 541 (loop 542 (without-interrupts 543 (when (eql p owner) 544 (incf (%get-natural lock target::lockptr.count)) 545 (when flag 546 (setf (lock-acquisition.status flag) t)) 547 (return t)) 548 (%get-spin-lock spin) 549 (when (eql 1 (incf (%get-natural lock target::lockptr.avail))) 550 (setf (%get-ptr lock target::lockptr.owner) p 551 (%get-natural lock target::lockptr.count) 1) 552 (setf (%get-natural spin 0) 0) 553 (if flag 554 (setf (lock-acquisition.status flag) t)) 555 (return t)) 556 (setf (%get-natural spin 0) 0)) 557 (%process-wait-on-semaphore-ptr signal 1 0 "waiting for lock")))) 548 (defun %lock-recursive-lock-object (lock &optional flag) 549 (let* ((ptr (recursive-lock-ptr lock))) 550 (with-macptrs ((p) 551 (owner (%get-ptr ptr target::lockptr.owner)) 552 (signal (%get-ptr ptr target::lockptr.signal)) 553 (spin (%inc-ptr ptr target::lockptr.spinlock))) 554 (%setf-macptr-to-object p (%current-tcr)) 555 (if (istruct-typep flag 'lock-acquisition) 556 (setf (lock-acquisition.status flag) nil) 557 (if flag (report-bad-arg flag 'lock-acquisition))) 558 (note-lock-wait lock) 559 (loop 560 (without-interrupts 561 (when (eql p owner) 562 (incf (%get-natural ptr target::lockptr.count)) 563 (note-lock-held) 564 (when flag 565 (setf (lock-acquisition.status flag) t)) 566 (return t)) 567 (%get-spin-lock spin) 568 (when (eql 1 (incf (%get-natural ptr target::lockptr.avail))) 569 (setf (%get-ptr ptr target::lockptr.owner) p 570 (%get-natural ptr target::lockptr.count) 1) 571 (setf (%get-natural spin 0) 0) 572 (note-lock-held) 573 (if flag 574 (setf (lock-acquisition.status flag) t)) 575 (return t)) 576 (setf (%get-natural spin 0) 0)) 577 (%process-wait-on-semaphore-ptr signal 1 0 (recursive-lock-whostate lock)))))) 578 579 558 580 559 581 #+futex 560 (defun futex-wait (p val) 561 (syscall syscalls::futex p FUTEX-WAIT val (%null-ptr) (%null-ptr) 0)) 582 (defun futex-wait (p val whostate) 583 (with-process-whostate (whostate) 584 (syscall syscalls::futex p FUTEX-WAIT val (%null-ptr) (%null-ptr) 0))) 562 585 563 586 #+futex … … 566 589 567 590 #+futex 568 (defun %lock-futex (p wait-level )591 (defun %lock-futex (p wait-level whostate) 569 592 (let* ((val (%ptr-store-conditional p futex-avail futex-locked))) 570 593 (declare (fixnum val)) … … 573 596 (if (eql val futex-contended) 574 597 (let* ((*interrupt-level* wait-level)) 575 (futex-wait p val ))598 (futex-wait p val whostate)) 576 599 (setq val futex-contended)) 577 600 (when (eql futex-avail (xchgl val p)) … … 585 608 586 609 610 611 587 612 #+futex 588 (defun %lock-recursive-lock (lock &optional flag)613 (defun %lock-recursive-lock-object (lock &optional flag) 589 614 (if (istruct-typep flag 'lock-acquisition) 590 615 (setf (lock-acquisition.status flag) nil) 591 616 (if flag (report-bad-arg flag 'lock-acquisition))) 592 617 (let* ((self (%current-tcr)) 593 (level *interrupt-level*)) 618 (level *interrupt-level*) 619 (ptr (recursive-lock-ptr lock))) 594 620 (declare (fixnum self val)) 621 (note-lock-wait lock) 595 622 (without-interrupts 596 (cond ((eql self (%get-object lock target::lockptr.owner)) 597 (incf (%get-natural lock target::lockptr.count))) 598 (t (%lock-futex lock level) 599 (%set-object lock target::lockptr.owner self) 600 (setf (%get-natural lock target::lockptr.count) 1))) 623 (cond ((eql self (%get-object ptr target::lockptr.owner)) 624 (incf (%get-natural ptr target::lockptr.count))) 625 (t (%lock-futex ptr level (recursive-lock-whostate lock)) 626 (%set-object ptr target::lockptr.owner self) 627 (setf (%get-natural ptr target::lockptr.count) 1))) 628 (note-lock-held) 601 629 (when flag 602 630 (setf (lock-acquisition.status flag) t)) … … 605 633 606 634 607 ;;; Locking the exception lock to inhibit GC (from other threads) 608 ;;; is probably a bad idea, though it does simplify some issues. 609 ;;; (One bad consequence is that it means that only one hash table 610 ;;; can be accessed at a time.) 611 #+bad-idea 612 (defun %lock-gc-lock () 613 (with-macptrs ((lock)) 614 (%get-kernel-global-ptr exception-lock lock) 615 (%lock-recursive-lock lock))) 616 617 #+bad-idea 618 (defun %unlock-gc-lock () 619 (with-macptrs ((lock)) 620 (%get-kernel-global-ptr exception-lock lock) 621 (%unlock-recursive-lock lock))) 635 636 622 637 623 638 #-futex 624 (defun %try-recursive-lock (lock &optional flag)639 (defun %try-recursive-lock-object (lock &optional flag) 625 640 (with-macptrs ((p) 626 (owner (%get-ptr locktarget::lockptr.owner))627 (spin (%inc-ptr locktarget::lockptr.spinlock)))641 (owner (%get-ptr ptr target::lockptr.owner)) 642 (spin (%inc-ptr ptr target::lockptr.spinlock))) 628 643 (%setf-macptr-to-object p (%current-tcr)) 629 644 (if flag … … 633 648 (without-interrupts 634 649 (cond ((eql p owner) 635 (incf (%get-natural lock target::lockptr.count)) 650 (incf (%get-natural ptr target::lockptr.count)) 651 (setq *locks-held* (%lock-cons lock *locks-held*)) 636 652 (if flag (setf (lock-acquisition.status flag) t)) 637 653 t) … … 639 655 (let* ((win nil)) 640 656 (%get-spin-lock spin) 641 (when (setq win (eql 1 (incf (%get-natural lock target::lockptr.avail)))) 642 (setf (%get-ptr lock target::lockptr.owner) p 643 (%get-natural lock target::lockptr.count) 1) 657 (when (setq win (eql 1 (incf (%get-natural ptr target::lockptr.avail)))) 658 (setf (%get-ptr ptr target::lockptr.owner) p 659 (%get-natural ptr target::lockptr.count) 1) 660 (setq *locks-held* (%lock-cons lock *locks-held*)) 644 661 (if flag (setf (lock-acquisition.status flag) t))) 645 662 (setf (%get-ptr spin) (%null-ptr)) 646 663 win)))))) 647 664 665 666 648 667 #+futex 649 (defun %try-recursive-lock (lock &optional flag) 650 (let* ((self (%current-tcr))) 668 (defun %try-recursive-lock-object (lock &optional flag) 669 (let* ((self (%current-tcr)) 670 (ptr (recursive-lock-ptr lock))) 651 671 (declare (fixnum self)) 652 672 (if flag … … 655 675 (report-bad-arg flag 'lock-acquisition))) 656 676 (without-interrupts 657 (cond ((eql (%get-object lock target::lockptr.owner) self) 658 (incf (%get-natural lock target::lockptr.count)) 677 (cond ((eql (%get-object ptr target::lockptr.owner) self) 678 (incf (%get-natural ptr target::lockptr.count)) 679 (setq *locks-held* (%lock-cons lock *locks-held*)) 659 680 (if flag (setf (lock-acquisition.status flag) t)) 660 681 t) 661 682 (t 662 (when (eql 0 (%ptr-store-conditional lock futex-avail futex-locked)) 663 (%set-object lock target::lockptr.owner self) 664 (setf (%get-natural lock target::lockptr.count) 1) 683 (when (eql 0 (%ptr-store-conditional ptr futex-avail futex-locked)) 684 (%set-object ptr target::lockptr.owner self) 685 (setf (%get-natural ptr target::lockptr.count) 1) 686 (setq *locks-held* (%lock-cons lock *locks-held*)) 665 687 (if flag (setf (lock-acquisition.status flag) t)) 666 688 t)))))) … … 668 690 669 691 692 693 670 694 #-futex 671 (defun %unlock-recursive-lock (lock) 672 (with-macptrs ((signal (%get-ptr lock target::lockptr.signal)) 673 (spin (%inc-ptr lock target::lockptr.spinlock))) 674 (unless (eql (%get-object lock target::lockptr.owner) (%current-tcr)) 695 (defun %unlock-recursive-lock-object (lock) 696 (let* ((ptr (%svref lock target::lock._value-cell))) 697 (with-macptrs ((signal (%get-ptr ptr target::lockptr.signal)) 698 (spin (%inc-ptr ptr target::lockptr.spinlock))) 699 (unless (eql (%get-object ptr target::lockptr.owner) (%current-tcr)) 700 (error 'not-lock-owner :lock lock)) 701 (without-interrupts 702 (when (eql 0 (decf (the fixnum 703 (%get-natural ptr target::lockptr.count)))) 704 (note-lock-released) 705 (%get-spin-lock spin) 706 (setf (%get-ptr ptr target::lockptr.owner) (%null-ptr)) 707 (let* ((pending (+ (the fixnum 708 (1- (the fixnum (%get-fixnum ptr target::lockptr.avail)))) 709 (the fixnum (%get-fixnum ptr target::lockptr.waiting))))) 710 (declare (fixnum pending)) 711 (setf (%get-natural ptr target::lockptr.avail) 0 712 (%get-natural ptr target::lockptr.waiting) 0) 713 (decf pending) 714 (if (> pending 0) 715 (setf (%get-natural ptr target::lockptr.waiting) pending)) 716 (setf (%get-ptr spin) (%null-ptr)) 717 (if (>= pending 0) 718 (%signal-semaphore-ptr signal))))))) 719 nil) 720 721 722 723 #+futex 724 (defun %unlock-recursive-lock-object (lock) 725 (let* ((ptr (%svref lock target::lock._value-cell))) 726 (unless (eql (%get-object ptr target::lockptr.owner) (%current-tcr)) 675 727 (error 'not-lock-owner :lock lock)) 676 728 (without-interrupts 677 729 (when (eql 0 (decf (the fixnum 678 (%get-natural lock target::lockptr.count)))) 679 (%get-spin-lock spin) 680 (setf (%get-ptr lock target::lockptr.owner) (%null-ptr)) 681 (let* ((pending (+ (the fixnum 682 (1- (the fixnum (%get-fixnum lock target::lockptr.avail)))) 683 (the fixnum (%get-fixnum lock target::lockptr.waiting))))) 684 (declare (fixnum pending)) 685 (setf (%get-natural lock target::lockptr.avail) 0 686 (%get-natural lock target::lockptr.waiting) 0) 687 (decf pending) 688 (if (> pending 0) 689 (setf (%get-natural lock target::lockptr.waiting) pending)) 690 (setf (%get-ptr spin) (%null-ptr)) 691 (if (>= pending 0) 692 (%signal-semaphore-ptr signal)))))) 693 nil) 694 695 #+futex 696 (defun %unlock-recursive-lock (lock) 697 (unless (eql (%get-object lock target::lockptr.owner) (%current-tcr)) 698 (error 'not-lock-owner :lock lock)) 699 (without-interrupts 700 (when (eql 0 (decf (the fixnum 701 (%get-natural lock target::lockptr.count)))) 702 (setf (%get-natural lock target::lockptr.owner) 0) 703 (%unlock-futex lock))) 704 nil) 730 (%get-natural ptr target::lockptr.count)))) 731 (note-lock-released) 732 (setf (%get-natural ptr target::lockptr.owner) 0) 733 (%unlock-futex ptr)))) 734 nil) 705 735 706 736 … … 793 823 ;;; signaled before we abandon interest in it 794 824 #-futex 795 (defun %write-lock-rwlock-ptr (ptr &optional flag)825 (defun %write-lock-rwlock-ptr (ptr lock &optional flag) 796 826 (with-macptrs ((write-signal (%get-ptr ptr target::rwlock.writer-signal)) ) 797 827 (if (istruct-typep flag 'lock-acquisition) … … 801 831 (tcr (%current-tcr))) 802 832 (declare (fixnum tcr)) 833 (note-lock-wait lock) 803 834 (without-interrupts 804 835 (%get-spin-lock ptr) ;(%get-spin-lock (%inc-ptr ptr target::rwlock.spin)) … … 807 838 (incf (%get-signed-natural ptr target::rwlock.state)) 808 839 (setf (%get-natural ptr target::rwlock.spin) 0) 840 (note-lock-held) 809 841 (if flag 810 842 (setf (lock-acquisition.status flag) t)) … … 813 845 ((eql 0 (%get-signed-natural ptr target::rwlock.state)) 814 846 ;; That wasn't so bad, was it ? We have the spinlock now. 847 (note-lock-held) 815 848 (setf (%get-signed-natural ptr target::rwlock.state) 1 816 849 (%get-natural ptr target::rwlock.spin) 0) … … 822 855 (setf (%get-natural ptr target::rwlock.spin) 0) 823 856 (let* ((*interrupt-level* level)) 824 (%process-wait-on-semaphore-ptr write-signal 1 0 "write lock wait"))857 (%process-wait-on-semaphore-ptr write-signal 1 0 (rwlock-write-whostate lock))) 825 858 (%get-spin-lock ptr))))))) 826 859 #+futex 827 (defun %write-lock-rwlock-ptr (ptr &optional flag)860 (defun %write-lock-rwlock-ptr (ptr lock &optional flag) 828 861 (with-macptrs ((write-signal (%INC-ptr ptr target::rwlock.writer-signal)) ) 829 862 (if (istruct-typep flag 'lock-acquisition) … … 833 866 (tcr (%current-tcr))) 834 867 (declare (fixnum tcr)) 868 (note-lock-wait lock) 835 869 (without-interrupts 836 (%lock-futex ptr level ) ;(%get-spin-lock (%inc-ptr ptr target::rwlock.spin))870 (%lock-futex ptr level "futex wait") ;(%get-spin-lock (%inc-ptr ptr target::rwlock.spin)) 837 871 (if (eq (%get-object ptr target::rwlock.writer) tcr) 838 872 (progn 839 873 (incf (%get-signed-natural ptr target::rwlock.state)) 840 874 (%unlock-futex ptr) 875 (note-lock-held) 841 876 (if flag 842 877 (setf (lock-acquisition.status flag) t)) … … 845 880 ((eql 0 (%get-signed-natural ptr target::rwlock.state)) 846 881 ;; That wasn't so bad, was it ? We have the spinlock now. 882 (note-lock-held) 847 883 (setf (%get-signed-natural ptr target::rwlock.state) 1) 848 884 (%unlock-futex ptr) … … 854 890 (let* ((waitval (%get-natural write-signal 0))) 855 891 (%unlock-futex ptr) 856 (let* ((*interrupt-level* level)) 857 (futex-wait write-signal waitval))) 858 (%lock-futex ptr level) 892 (with-process-whostate ((rwlock-write-whostate lock)) 893 (let* ((*interrupt-level* level)) 894 (futex-wait write-signal waitval (rwlock-write-whostate lock))))) 895 (%lock-futex ptr level "futex wait") 859 896 (decf (%get-natural ptr target::rwlock.blocked-writers)))))))) 860 897 … … 862 899 863 900 (defun write-lock-rwlock (lock &optional flag) 864 (%write-lock-rwlock-ptr (read-write-lock-ptr lock) flag))901 (%write-lock-rwlock-ptr (read-write-lock-ptr lock) lock flag)) 865 902 866 903 #-futex … … 873 910 (tcr (%current-tcr))) 874 911 (declare (fixnum tcr)) 912 (note-lock-wait lock) 875 913 (without-interrupts 876 914 (%get-spin-lock ptr) ;(%get-spin-lock (%inc-ptr ptr target::rwlock.spin)) … … 878 916 (progn 879 917 (setf (%get-natural ptr target::rwlock.spin) 0) 918 (setq *locks-pending* (cdr *locks-pending*)) 880 919 (error 'deadlock :lock lock)) 881 920 (do* ((state … … 887 926 (the fixnum (1- state)) 888 927 (%get-natural ptr target::rwlock.spin) 0) 928 (note-lock-held) 889 929 (if flag 890 930 (setf (lock-acquisition.status flag) t)) … … 894 934 (setf (%get-natural ptr target::rwlock.spin) 0) 895 935 (let* ((*interrupt-level* level)) 896 (%process-wait-on-semaphore-ptr read-signal 1 0 "read lock wait"))936 (%process-wait-on-semaphore-ptr read-signal 1 0 (rwlock-read-whostate lock))) 897 937 (%get-spin-lock ptr))))))) 898 938 … … 906 946 (tcr (%current-tcr))) 907 947 (declare (fixnum tcr)) 948 (note-lock-wait lock) 908 949 (without-interrupts 909 (%lock-futex ptr level )950 (%lock-futex ptr level "futex wait") 910 951 (if (eq (%get-object ptr target::rwlock.writer) tcr) 911 952 (progn 912 953 (%unlock-futex ptr) 954 (setq *locks-pending* (cdr *locks-pending*)) 913 955 (error 'deadlock :lock lock)) 914 956 (do* ((state … … 919 961 (setf (%get-signed-natural ptr target::rwlock.state) 920 962 (the fixnum (1- state))) 963 (note-lock-held) 921 964 (%unlock-futex ptr) 922 965 (if flag … … 928 971 (%unlock-futex ptr) 929 972 (let* ((*interrupt-level* level)) 930 (futex-wait reader-signal waitval )))931 (%lock-futex ptr level )973 (futex-wait reader-signal waitval (rwlock-read-whostate lock)))) 974 (%lock-futex ptr level "futex wait") 932 975 (decf (%get-natural ptr target::rwlock.blocked-readers)))))))) 933 976 … … 937 980 (%read-lock-rwlock-ptr (read-write-lock-ptr lock) lock flag)) 938 981 939 ;;; If the current thread already owns the lock for writing, increment 940 ;;; the lock's state. Otherwise, try to lock the lock for reading. 941 (defun %ensure-at-least-read-locked (lock &optional flag) 942 (if (istruct-typep flag 'lock-acquisition) 943 (setf (lock-acquisition.status flag) nil) 944 (if flag (report-bad-arg flag 'lock-acquisition))) 945 (let* ((ptr (read-write-lock-ptr lock)) 946 (tcr (%current-tcr)) 947 #+futex (level *interrupt-level*)) 948 (declare (fixnum tcr)) 949 (or 950 (without-interrupts 951 #+futex 952 (%lock-futex ptr level) 953 #-futex 954 (%get-spin-lock ptr) 955 (let* ((state (%get-signed-natural ptr target::rwlock.state))) 956 (declare (fixnum state)) 957 (let ((win 958 (cond ((<= state 0) 959 (setf (%get-signed-natural ptr target::rwlock.state) 960 (the fixnum (1- state))) 961 t) 962 ((%ptr-eql (%get-ptr ptr target::rwlock.writer) tcr) 963 (setf (%get-signed-natural ptr target::rwlock.state) 964 (the fixnum (1+ state))) 965 t)))) 966 #+futex 967 (%unlock-futex ptr) 968 #-futex 969 (setf (%get-natural ptr target::rwlock.spin) 0) 970 (when win 971 (if flag 972 (setf (lock-acquisition.status flag) t)) 973 t)))) 974 (%read-lock-rwlock-ptr ptr lock flag)))) 982 975 983 976 984 #-futex … … 1013 1021 ;; are cleared here (they can't be changed from another thread 1014 1022 ;; until this thread releases the spinlock.) 1023 (note-lock-released) 1015 1024 (setf (%get-signed-natural ptr target::rwlock.writer) 0) 1016 1025 (let* ((nwriters (%get-natural ptr target::rwlock.blocked-writers)) … … 1035 1044 (wakeup 0)) 1036 1045 (without-interrupts 1037 (%lock-futex ptr -1 )1046 (%lock-futex ptr -1 "futex wait") 1038 1047 (let* ((state (%get-signed-natural ptr target::rwlock.state)) 1039 1048 (tcr (%current-tcr))) … … 1049 1058 (setf (%get-signed-natural ptr target::rwlock.state) state) 1050 1059 (when (zerop state) 1060 (note-lock-released) 1051 1061 (setf (%get-signed-natural ptr target::rwlock.writer) 0) 1052 1062 (let* ((nwriters (%get-natural ptr target::rwlock.blocked-writers)) … … 1085 1095 (without-interrupts 1086 1096 #+futex 1087 (%lock-futex ptr level )1097 (%lock-futex ptr level "futex wait") 1088 1098 #-futex 1089 1099 (%get-spin-lock ptr)
Note:
See TracChangeset
for help on using the changeset viewer.
