[nio-cvs] r38 - branches/home/psmith/restructure/src/compat
psmith at common-lisp.net
psmith at common-lisp.net
Wed Jan 17 01:34:39 UTC 2007
Author: psmith
Date: Tue Jan 16 20:34:39 2007
New Revision: 38
Added:
branches/home/psmith/restructure/src/compat/concurrent-queue.lisp
Log:
Added concurrent queue
inter thread communication via a FIFO queue
Added: branches/home/psmith/restructure/src/compat/concurrent-queue.lisp
==============================================================================
--- (empty file)
+++ branches/home/psmith/restructure/src/compat/concurrent-queue.lisp Tue Jan 16 20:34:39 2007
@@ -0,0 +1,85 @@
+#|
+Copyright (c) 2007
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+|#
+
+(in-package :nio-compat)
+
+(declaim (optimize (debug 3) (speed 3) (space 0)))
+
+;Implements a threadsafe queue where readers wait for elements of a FIFO queue to appear using a waitqueue
+;Modified from sbcl manual example
+
+(defclass concurrent-queue()
+ ((buffer-queue :initform (sb-thread:make-waitqueue)
+ :reader buffer-queue)
+ (buffer-lock :initform (sb-thread:make-mutex :name "buffer lock")
+ :reader buffer-lock)
+ (buffer :initform nil
+ :accessor buffer)))
+
+(defmacro pop-elt(a-buffer loc)
+ `(if ,a-buffer
+ (let ((head (car ,a-buffer)))
+ (setf ,a-buffer (cdr ,a-buffer))
+#+nio-debug (format t "reader ~A woke, read ~A as ~A~%" sb-thread:*current-thread* head ,loc)
+ head)
+ nil))
+
+
+(defmethod take ((queue concurrent-queue))
+ (sb-thread:with-mutex ((buffer-lock queue))
+ ;if its there, pop it
+ (let ((ret (pop-elt (buffer queue) "1sttry")))
+ (if ret
+ ret
+ (progn
+ (sb-thread:condition-wait (buffer-queue queue) (buffer-lock queue))
+ (pop-elt (buffer queue) "2ndtry"))))))
+
+
+(defmethod add ((queue concurrent-queue) elt)
+ (sb-thread:with-mutex ((buffer-lock queue))
+ (setf (buffer queue) (append (buffer queue) (list elt)) )
+ (sb-thread:condition-notify (buffer-queue queue))))
+
+
+
+(defun test-writer(queue)
+ (loop for i from 0 to 999 do
+ (sleep 0.1)
+ (add queue i)))
+
+(defun test-reader(queue)
+ (loop
+ (format t "reader on ~A got elt ~A~%"
+ sb-thread:*current-thread* (take queue))))
+
+(defun test-queue()
+ (let ((queue (make-instance 'concurrent-queue)))
+ (sb-thread:make-thread #'(lambda()(test-writer queue)))
+ (sleep 10)
+ (sb-thread:make-thread #'(lambda()(test-reader queue)))
+ (sb-thread:make-thread #'(lambda()(test-reader queue)))))
More information about the Nio-cvs
mailing list