(import scheme) (cond-expand (chicken-5 (import (chicken module))) (else)) (export atom atom-value atom? atom-compare-and-set! atom-swap! atom-reset!) (cond-expand (chicken-5 (import (except (chicken base) atom?) (srfi 18))) (else (import chicken) (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)))))