(make-fifo
fifo-push
fifo-pop
- fifo-empty?
fifo->list)
(import scheme
- (chicken base)
- srfi-18)
+ (chicken base))
(define (make-fifo)
(define (cell val prev next)
(set-car! (cddr cell) next-cell))
(let ((head '())
- (tail '())
- (pop-mutex (make-mutex)))
- (mutex-lock! pop-mutex #f #f)
+ (tail '()))
(lambda (cmd . args)
(case cmd
- ((empty?) (null? head))
((push)
(if (not (null? head))
(let ((old-head head))
(begin
;; Initialize list
(set! head (cell (car args) '() '()))
- (set! tail head)
- (mutex-unlock! pop-mutex))))
+ (set! tail head))))
((pop)
- (mutex-lock! pop-mutex #f #f)
- (if (null? head)
- (error "FIFO empty.")
- (let ((old-tail tail))
- (set! tail (cell-prev old-tail))
- (if (null? tail)
- (set! head '())
- (begin
- (set-cell-next! tail '())
- (mutex-unlock! pop-mutex #f #f)))
- (cell-val old-tail)))))
- ((->list) (if (not (= (length args) 0))
- (error "Wrong number of arguments to ->list.")
- (let loop ((this-cell head))
- (if (null? this-cell)
- '()
- (cons (cell-val this-cell)
- (loop (cell-next this-cell))))))))))
+ (let ((old-tail tail))
+ (set! tail (cell-prev old-tail))
+ (if (null? tail)
+ (set! head '())
+ (set-cell-next! tail '()))
+ (cell-val old-tail)))
+ ((->list)
+ (let loop ((this-cell head))
+ (if (null? this-cell)
+ '()
+ (cons (cell-val this-cell)
+ (loop (cell-next this-cell))))))))))
-
(define (fifo-push fifo x)
(fifo 'push x))
(define (fifo-pop fifo)
(fifo 'pop))
- (define (fifo-empty? fifo)
- (fifo 'empty?))
-
(define (fifo->list fifo)
(fifo '->list)))
matchable
srfi-18 ; threads
srfi-69 ; hashtable
- udp6
- uri-generic)
+ udp
+ fifo)
;; Actors
(define (deliver-message address . message)
(let ((id (address-id address)))
- (let ((behaviour (hash-table-ref/default actor-table id '()))))
- (if (null? behaviour)
- (print "Warning: discarded message" message " to unknown actor " address)
- (match (apply (hash-table-ref actor-table id) (cons address message))
- ('done (hash-table-delete! actor-table actor))
- ('sleep 'do-nothing)
- (new-beh (hash-table-put! actor new-beh))))))
+ (let ((behaviour (hash-table-ref/default actor-table id '())))
+ (if (null? behaviour)
+ (print "Warning: discarded message" message " to unknown actor " address)
+ (match (apply (hash-table-ref actor-table id) (cons address message))
+ ('done (hash-table-delete! actor-table actor))
+ ('sleep 'do-nothing)
+ (new-beh (hash-table-put! actor new-beh)))))))
;; Scheduler
(define local-queue-mutex (make-mutex "message queue"))
(define message-available-mutex (make-mutex "message available"))
+(mutex-lock! message-available-mutex #f #f)
(define local-queue (make-fifo))
(define (send-message address . message)
(define (send-local-message address . message)
(mutex-lock! local-queue-mutex)
(fifo-push local-queue (cons address message))
+ (mutex-unlock! message-available-mutex)
(mutex-unlock! local-queue-mutex))
(define (send-network-message address . message)
(define (next-local-message)
(let ((res #f))
+ (mutex-lock! message-available-mutex)
(mutex-lock! local-queue-mutex)
- (set! res (if (fifo-empty? local-queue)
- #f
- (fifo-pop local-queue)))
+ (set! res (fifo-pop local-queue))
+ (mutex-unlock! message-available-mutex)
(mutex-unlock! local-queue-mutex)
res))
(make-thread
(lambda ()
(let loop ((next-addressed-message (next-local-message)))
- (if next-addressed-message
- (apply deliver-message next-addressed-message)
- (begin
- (lo))))))
+ (apply deliver-message next-addressed-message)
+ (loop (next-local-message))))))
- (thread-start!))
+(thread-start! scheduler-thread)
+
+(thread-join! scheduler-thread)