(define make-buffer (lambda (_capacity) (let ((contents (make-vector _capacity)) (front 0) (back 0) (capacity _capacity) (size 0)) (lambda (command . params) (cond ((eq? command ':empty?) (<= size 0)) ((eq? command ':full?) (>= size capacity)) ((eq? command ':get!) (let ((tmp (vector-ref contents front))) (set! front (modulo (+ front 1) capacity)) (set! size (- size 1)) tmp)) ((eq? command ':put!) (vector-set! contents back (car params)) (set! back (modulo (+ back 1) capacity)) (set! size (+ size 1))) ((eq? command ':dump) (display "capacity: ") (display capacity) (newline) (display "size: ") (display size) (newline) (display "front: ") (display front) (newline) (display "back: ") (display back) (newline) (display "contents: ") (display contents) (newline)) (else (error "Undefined command"))))))) (define consumer (lambda (buffer done? suspend consume) (let kernel ((count 0)) (cond ((done? count)) ((buffer ':empty?) (suspend) (kernel count)) (else (consume count (buffer ':get!)) (kernel (+ count 1))))))) (define producer (lambda (buffer done? suspend create) (let kernel ((count 0)) (cond ((done? count)) ((buffer ':full?) (suspend) (kernel count)) (else (let ((v (create count))) (buffer ':put! v) (display (list 'producer v count)) (newline) (kernel (+ count 1)))))))) (define pc (lambda () (let ((buf (make-buffer 10)) (ck '*) (pk '*)) (call/cc (lambda (k) (set! pk k))) (call/cc (lambda (k) (producer buf (lambda (num) (= (random 20) 0)) (lambda () (call/cc (lambda (k1) (begin (set! pk k1) (if (equal? ck '*) (k) (ck)))))) (lambda (val) (random 100))))) (consumer buf (lambda (num) (= (random 20) 0)) (lambda () (call/cc (lambda (k) (begin (set! ck k) (pk))))) (lambda (count val) (display (list 'consume count val)) (newline))))))