| 1 | ;;;-*- Mode: Lisp; Package: Wood -*-
|
|---|
| 2 |
|
|---|
| 3 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|---|
| 4 | ;;
|
|---|
| 5 | ;; q.lisp
|
|---|
| 6 | ;; A simple fifo queue. Why isn't this part of Common Lisp
|
|---|
| 7 | ;;
|
|---|
| 8 | ;; Portions Copyright ᅵ 2006 Clozure Associates
|
|---|
| 9 | ;; Copyright ᅵ 1996 Digitool, Inc.
|
|---|
| 10 | ;; Copyright ᅵ 1992-1995 Apple Computer, Inc.
|
|---|
| 11 | ;; All rights reserved.
|
|---|
| 12 | ;; Permission is given to use, copy, and modify this software provided
|
|---|
| 13 | ;; that Digitool is given credit in all derivative works.
|
|---|
| 14 | ;; This software is provided "as is". Digitool makes no warranty or
|
|---|
| 15 | ;; representation, either express or implied, with respect to this software,
|
|---|
| 16 | ;; its quality, accuracy, merchantability, or fitness for a particular
|
|---|
| 17 | ;; purpose.
|
|---|
| 18 |
|
|---|
| 19 | ;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|---|
| 20 | ;;
|
|---|
| 21 | ;; Modification History
|
|---|
| 22 | ;;
|
|---|
| 23 | ;; 02/01/06 gz LispWorks port
|
|---|
| 24 | ;; ------------- 0.96
|
|---|
| 25 | ;; 08/27/96 bill Added copyright and mod history comments
|
|---|
| 26 | ;;
|
|---|
| 27 |
|
|---|
| 28 | (in-package #+ccl :ccl #-ccl :wood)
|
|---|
| 29 |
|
|---|
| 30 | (export '(make-q enq deq q-empty-p))
|
|---|
| 31 |
|
|---|
| 32 | #+ccl (require "LISPEQU") ; %cons-pool, pool.data
|
|---|
| 33 |
|
|---|
| 34 | (defstruct q
|
|---|
| 35 | start-buf
|
|---|
| 36 | start-index
|
|---|
| 37 | end-buf
|
|---|
| 38 | end-index)
|
|---|
| 39 |
|
|---|
| 40 | (defmethod print-object ((q q) stream)
|
|---|
| 41 | (print-unreadable-object (q stream :type t :identity t)
|
|---|
| 42 | ))
|
|---|
| 43 |
|
|---|
| 44 | (defconstant $q-buf-size 512)
|
|---|
| 45 | #+Lispworks (defconstant $max-num-q-bufs 20)
|
|---|
| 46 |
|
|---|
| 47 | (defvar *q-bufs*
|
|---|
| 48 | #+ccl (%cons-pool)
|
|---|
| 49 | #+LispWorks (let ((arr (make-array $max-num-q-bufs :adjustable T)))
|
|---|
| 50 | (hcl:set-array-weak arr t)
|
|---|
| 51 | arr))
|
|---|
| 52 |
|
|---|
| 53 | (defun make-q-buf ()
|
|---|
| 54 | #+ccl
|
|---|
| 55 | (without-interrupts
|
|---|
| 56 | (let ((buf (pool.data *q-bufs*)))
|
|---|
| 57 | (if buf
|
|---|
| 58 | (progn
|
|---|
| 59 | (setf (pool.data *q-bufs*) (svref buf 0))
|
|---|
| 60 | (dotimes (i $q-buf-size)
|
|---|
| 61 | (setf (svref buf i) nil))
|
|---|
| 62 | buf)
|
|---|
| 63 | (make-array $q-buf-size))))
|
|---|
| 64 | #+LispWorks
|
|---|
| 65 | (mp:with-interrupts-blocked
|
|---|
| 66 | (let ((pos (position-if-not #'null *q-bufs*)))
|
|---|
| 67 | (if pos
|
|---|
| 68 | (let ((buf (aref *q-bufs* pos)))
|
|---|
| 69 | (setf (aref *q-bufs* pos) nil)
|
|---|
| 70 | (fill buf nil)
|
|---|
| 71 | buf)
|
|---|
| 72 | (make-array $q-buf-size))))
|
|---|
| 73 | )
|
|---|
| 74 |
|
|---|
| 75 | (defun free-q-buf (buf)
|
|---|
| 76 | #+ccl
|
|---|
| 77 | (without-interrupts
|
|---|
| 78 | (setf (svref buf 0) (pool.data *q-bufs*)
|
|---|
| 79 | (pool.data *q-bufs*) buf))
|
|---|
| 80 | #+LispWorks
|
|---|
| 81 | (mp:with-interrupts-blocked
|
|---|
| 82 | (let ((pos (position-if #'null *q-bufs*)))
|
|---|
| 83 | (when pos
|
|---|
| 84 | (setf (aref *q-bufs* pos) buf))))
|
|---|
| 85 | nil)
|
|---|
| 86 |
|
|---|
| 87 | (defun enq (q elt)
|
|---|
| 88 | (setq q (require-type q 'q))
|
|---|
| 89 | (let ((buf (q-end-buf q))
|
|---|
| 90 | (index (q-end-index q)))
|
|---|
| 91 | (if (null buf)
|
|---|
| 92 | (setf buf (make-q-buf)
|
|---|
| 93 | (q-start-buf q) buf
|
|---|
| 94 | (q-start-index q) 1
|
|---|
| 95 | (q-end-buf q) buf
|
|---|
| 96 | (q-end-index q) (setq index 1))
|
|---|
| 97 | (when (>= index $q-buf-size)
|
|---|
| 98 | (setf (q-end-buf q)
|
|---|
| 99 | (setf buf
|
|---|
| 100 | (setf (svref buf 0) (make-q-buf)))
|
|---|
| 101 | (q-end-index q) (setq index 1))))
|
|---|
| 102 | (setf (svref buf index) elt)
|
|---|
| 103 | (setf (q-end-index q) (1+ index)))
|
|---|
| 104 | elt)
|
|---|
| 105 |
|
|---|
| 106 | (defun q-empty-p (q)
|
|---|
| 107 | (setq q (require-type q 'q))
|
|---|
| 108 | (let ((start-buf (q-start-buf q)))
|
|---|
| 109 | (or (null start-buf)
|
|---|
| 110 | (and (eq start-buf (q-end-buf q))
|
|---|
| 111 | (eql (q-start-index q)
|
|---|
| 112 | (q-end-index q))))))
|
|---|
| 113 |
|
|---|
| 114 | (defun deq (q &optional (error-if-empty t))
|
|---|
| 115 | (when (q-empty-p q)
|
|---|
| 116 | (if error-if-empty
|
|---|
| 117 | (error "Empty q: ~s" q)
|
|---|
| 118 | (return-from deq nil)))
|
|---|
| 119 | (let ((buf (q-start-buf q))
|
|---|
| 120 | (index (q-start-index q)))
|
|---|
| 121 | (prog1
|
|---|
| 122 | (svref buf index)
|
|---|
| 123 | (when (eql (incf index) $q-buf-size)
|
|---|
| 124 | (setq index 1)
|
|---|
| 125 | (unless (setf (q-start-buf q) (svref buf 0))
|
|---|
| 126 | (setf (q-end-buf q) nil))
|
|---|
| 127 | (free-q-buf buf))
|
|---|
| 128 | (setf (q-start-index q) index))))
|
|---|
| 129 |
|
|---|
| 130 | (provide "Q")
|
|---|
| 131 | ;;; 1 3/10/94 bill 1.8d247
|
|---|