(module clojurian-atom (atom atom-value atom? atom-compare-and-set! atom-swap! atom-reset!) (import chicken scheme) (use srfi-18) (define-record atom mutex value) (define (atom value) (make-atom (make-mutex) value)) (define (atom-compare-and-set! atom old new) (and (eq? (atom-value atom) old) (dynamic-wind (lambda () (mutex-lock! (atom-mutex atom))) (lambda () (and (eq? (atom-value atom) old) (begin (atom-value-set! atom new) #t))) (lambda () (mutex-unlock! (atom-mutex atom)))))) (define (atom-swap! atom proc . args) (let loop () (let* ((old (atom-value atom)) (new (apply proc old args))) (if (atom-compare-and-set! atom old new) new (loop))))) (define (atom-reset! atom value) (dynamic-wind (lambda () (mutex-lock! (atom-mutex atom))) (lambda () (atom-value-set! atom value) value) (lambda () (mutex-unlock! (atom-mutex atom))))) )