source: branches/portable/q.lisp@ 31

Last change on this file since 31 was 15, checked in by wws, 10 years ago

Compiles without warning. First try at vector subtype mapping.

  • Property svn:eol-style set to native
File size: 3.7 KB
Line 
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 and Anvita eReference (www.Anvita.info)
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 :wood)
29
30(export '(make-q enq deq q-empty-p))
31
32#+ccl
33(eval-when (:compile-toplevel :execute)
34 (require "LISPEQU")) ; ccl::%cons-pool, ccl::pool.data
35
36(defstruct q
37 start-buf
38 start-index
39 end-buf
40 end-index)
41
42(defmethod print-object ((q q) stream)
43 (print-unreadable-object (q stream :type t :identity t)
44 ))
45
46(defconstant $q-buf-size 512)
47#+Lispworks (defconstant $max-num-q-bufs 20)
48
49(defvar *q-bufs*
50 #+ccl (ccl::%cons-pool)
51 #+LispWorks (let ((arr (make-array $max-num-q-bufs)))
52 (hcl:set-array-weak arr t)
53 arr))
54
55(defvar *q-bufs-lock*
56 (bt:make-recursive-lock "*q-bufs*"))
57
58(defmacro with-qbufs-locked (() &body body)
59 `(bt:with-recursive-lock-held (*q-bufs-lock*)
60 ,@body))
61
62(defun make-q-buf ()
63 (with-qbufs-locked ()
64 #+ccl
65 (let ((buf (ccl::pool.data *q-bufs*)))
66 (if buf
67 (progn
68 (setf (ccl::pool.data *q-bufs*) (svref buf 0))
69 (dotimes (i $q-buf-size)
70 (setf (svref buf i) nil))
71 buf)
72 (make-array $q-buf-size)))
73 #+LispWorks
74 (let ((pos (position-if-not #'null *q-bufs*)))
75 (if pos
76 (let ((buf (aref *q-bufs* pos)))
77 (setf (aref *q-bufs* pos) nil)
78 (fill buf nil)
79 buf)
80 (make-array $q-buf-size)))))
81
82(defun free-q-buf (buf)
83 (with-qbufs-locked ()
84 #+ccl
85 (setf (svref buf 0) (ccl::pool.data *q-bufs*)
86 (ccl::pool.data *q-bufs*) buf)
87 #+LispWorks
88 (let ((pos (position-if #'null *q-bufs*)))
89 (when pos
90 (setf (aref *q-bufs* pos) buf)))
91 nil))
92
93(defun enq (q elt)
94 (setq q (require-type q 'q))
95 (let ((buf (q-end-buf q))
96 (index (q-end-index q)))
97 (if (null buf)
98 (setf buf (make-q-buf)
99 (q-start-buf q) buf
100 (q-start-index q) 1
101 (q-end-buf q) buf
102 (q-end-index q) (setq index 1))
103 (when (>= index $q-buf-size)
104 (setf (q-end-buf q)
105 (setf buf
106 (setf (svref buf 0) (make-q-buf)))
107 (q-end-index q) (setq index 1))))
108 (setf (svref buf index) elt)
109 (setf (q-end-index q) (1+ index)))
110 elt)
111
112(defun q-empty-p (q)
113 (setq q (require-type q 'q))
114 (let ((start-buf (q-start-buf q)))
115 (or (null start-buf)
116 (and (eq start-buf (q-end-buf q))
117 (eql (q-start-index q)
118 (q-end-index q))))))
119
120(defun deq (q &optional (error-if-empty t))
121 (when (q-empty-p q)
122 (if error-if-empty
123 (error "Empty q: ~s" q)
124 (return-from deq nil)))
125 (let ((buf (q-start-buf q))
126 (index (q-start-index q)))
127 (prog1
128 (svref buf index)
129 (when (eql (incf index) $q-buf-size)
130 (setq index 1)
131 (unless (setf (q-start-buf q) (svref buf 0))
132 (setf (q-end-buf q) nil))
133 (free-q-buf buf))
134 (setf (q-start-index q) index))))
135
136(provide "Q")
137;;; 1 3/10/94 bill 1.8d247
Note: See TracBrowser for help on using the repository browser.