From af2008cbcf3207fdecb6c986cd67887b2abeb24a Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Tue, 25 Jun 2019 18:07:15 -0400 Subject: [PATCH] WIP --- libs/cyclone/shared-queue.sld | 48 +++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/libs/cyclone/shared-queue.sld b/libs/cyclone/shared-queue.sld index 46ea89a6..b0101ef5 100644 --- a/libs/cyclone/shared-queue.sld +++ b/libs/cyclone/shared-queue.sld @@ -18,13 +18,26 @@ ;- queue-capacity (max size until resize occurs) ;- queue-empty? +(define-library (shared-queue) + (import (scheme base) (cyclone test) (cyclone concurrent) (srfi 18) (scheme write)) -(define *default-table-size* 64) +(export + queue? + make-queue + queue + queue-add! + %queue-add! ;; DEBUG + %queue-remove! +) + +(begin + +(define *default-table-size* 4) ;; TODO: 64) ;TODO: how will data structure work? ;probably want a circular queue, add at end and remove from start @@ -58,14 +71,17 @@ (%queue-add! q elem)) (reverse elems)))) +(define (inc index capacity) + (if (= index (- capacity 1)) + 0 + (+ index 1))) + ;; Inner add, assumes we already have the lock (define (%queue-add! q obj) - (vector-set! (q:store q) (q:size q) (make-shared obj)) - (cond - ((= (q:size q) (vector-length (q:store))) + (vector-set! (q:store q) (q:end q) (make-shared obj)) + (q:set-end! q (inc (q:end q) (vector-length (q:store q)))) + (when (= (q:start q) (q:end q)) (%queue-resize! q)) - (else - (q:set-size! q (+ (q:size q) 1)))) ) (define (queue-add! q obj) @@ -74,7 +90,8 @@ (mutex-unlock! (q:lock q)) ) -;(define (%queue-resize! q) +(define (%queue-resize! q) + (write "TODO: resize the queue")(newline) ; ;; TODO: assumes we already have the lock ; ;; TODO: error if size is larger than fixnum?? ; (let ((old-store (q:store q)) @@ -84,12 +101,22 @@ ; (when (not (zero? i)) ; (%queue-add! q (vector-ref ; (loop (- i 1))))) -;) +) -;- (queue ...) constructor -;- queue-add! - add item to the queue ;- queue-remove! - remove item (when to block? would be nice if we can block until an item becomes available) ; maybe block by default, but have an optional timeout + +;; TODO: queue-remove! which locks and call this function +(define (%queue-remove! q) + (cond + ((= (q:start q) (q:end q)) + (write "queue is already empty")) + (else + (let ((result (vector-ref (q:store q) (q:start q)))) + (q:set-start! q (inc (q:start q) (vector-length (q:store q)))) + result))) +) + ;- queue-get - ?? ;- queue-clear! ;- queue->list @@ -100,3 +127,4 @@ ;(test-group "basic") ;(test #t (shared-queue? (make-queue))) ;(test-exit) +))