Changeset 475


Ignore:
Timestamp:
Feb 6, 2004, 11:30:14 AM (21 years ago)
Author:
Gary Byers
Message:

SHARED-RESOURCEs, mostly for arbitrating access to CCL::*TERMINAL-INPUT*.
(May not work well, but neither did the old scheme.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/level-1/linux-files.lisp

    r400 r475  
    879879    (:tty t)
    880880    (t nil)))
     881
     882
     883(defstruct (shared-resource (:constructor make-shared-resource (name)))
     884  (name)
     885  (lock (make-lock))
     886  (primary-owner *current-process*)
     887  (primary-owner-notify (make-semaphore))
     888  (current-owner nil)
     889  (requestors (make-dll-header)))
     890
     891(defstruct (shared-resource-request
     892             (:constructor make-shared-resource-request (process))
     893             (:include dll-node))
     894  process
     895  (signal (make-semaphore)))
     896             
     897
     898;; Returns NIL if already owned by calling thread, T otherwise
     899(defun %acquire-shared-resource (resource  &optional verbose)
     900  (let* ((current *current-process*))
     901    (with-lock-grabbed ((shared-resource-lock resource))
     902      (let* ((secondary (shared-resource-current-owner resource)))
     903        (if (or (eq current secondary)
     904                (and (null secondary)
     905                     (eq current (shared-resource-primary-owner resource))))
     906          (return-from %acquire-shared-resource nil))))
     907    (let* ((request (make-shared-resource-request *current-process*)))
     908      (when verbose
     909        (format t "~%~%;;;~%;;; ~a requires access to ~a~%;;;~%~%"
     910                *current-process* (shared-resource-name resource)))
     911      (with-lock-grabbed ((shared-resource-lock resource))
     912        (append-dll-node request (shared-resource-requestors resource)))
     913      (wait-on-semaphore (shared-resource-request-signal request))
     914      #+debug
     915      (assert (eq current (shared-resource-current-owner request)))
     916      (when verbose
     917        (format t "~%~%;;;~%;;; ~a is now owned by ~a~%;;;~%~%"
     918                (shared-resource-name resource) current))
     919      t)))
     920
     921;;; If we're the primary owner and there is no secondary owner, do nothing.
     922;;; If we're the secondary owner, cease being the secondary owner.
     923(defun %release-shared-resource (r)
     924  (let* ((not-any-owner ()))
     925    (with-lock-grabbed ((shared-resource-lock r))
     926      (let* ((current *current-process*)
     927             (primary (shared-resource-primary-owner r))
     928             (secondary (shared-resource-current-owner r)))
     929        (unless (setq not-any-owner
     930                      (or (eq current secondary)
     931                          (and (null secondary)
     932                               (eq current primary))))
     933          (when secondary
     934            (setf (shared-resource-current-owner r) nil)
     935            (signal-semaphore (shared-resource-primary-owner-notify r))))))
     936    (when not-any-owner
     937      (signal-program-error "Process ~a does not own ~a" *current-process*
     938                            (shared-resource-name r)))))
     939
     940;;; The current thread should be the primary owner; there should be
     941;;; no secondary owner.  Wakeup the specified (or first) requesting
     942;;; process, then block on our semaphore
     943(defun %yield-shared-resource (r &optional to)
     944  (let* ((request nil))
     945    (with-lock-grabbed ((shared-resource-lock r))
     946      (let* ((current *current-process*)
     947             (primary (shared-resource-primary-owner r)))
     948        (when (and (eq current primary)
     949                   (null (shared-resource-current-owner r)))
     950          (setq request
     951                (let* ((header (shared-resource-requestors r)))
     952                  (if to
     953                    (do-dll-nodes (node header)
     954                      (when (eq to (shared-resource-request-process node))
     955                        (return node)))
     956                    (let* ((first (dll-header-first header)))
     957                      (unless (eq first header)
     958                        first)))))
     959          (when request
     960            (remove-dll-node request)
     961            (signal-semaphore (shared-resource-request-signal request))))))
     962    (when request
     963      (wait-on-semaphore (shared-resource-primary-owner-notify r))
     964      (format t "~&;;;~%;;;control of ~a restored to ~a~%;;;~&"
     965              (shared-resource-name r)
     966              *current-process*))))
     967
     968
     969     
     970
     971(defun %shared-resource-requestor-p (r proc)
     972  (with-lock-grabbed ((shared-resource-lock r))
     973    (do-dll-nodes (node (shared-resource-requestors r))
     974      (when (eq proc (shared-resource-request-process node))
     975        (return t)))))
     976
Note: See TracChangeset for help on using the changeset viewer.