STM Revisited...
FWIW, most (or all) of my code has now been converted to this super-simple STM variant...;; ---------------------------------------------------------------------------------
;; -------------------------------
(in-package #:simple-vstm)
;; -------------------------------
;; -------------------------
;; concurrent access and read-modify-write
(defstruct var
val)
(defmacro rmw ((val v) &body body)
`(do-rmw ,v (lambda (,val) ,@body)))
#+:LISPWORKS
(editor:setup-indent "rmw" 1)
(defun do-rmw (v fn)
(loop for prev = (var-val v)
for new = (funcall fn prev)
until (mp:compare-and-swap (var-val v) prev new)))
;; -------------------------------------------------------------------------------
Basically, it consists of making a boxed mutable value. RMW is read-modify-write, and that happens via the new LW 6.x COMPARE-AND-SWAP primitive. No need for anything much more complicated than this. Fast, simple, effective...
What it cannot handle properly are coordinated changes involving multiple values, unless those are combined into a box'able entity for use with this variant of STM. But it turns out that, thanks largely to FPL style programming, this simple variant handles just about all my needs for STM at considerably lower cost than any other STM implementation.
Example of use: a mutable linked list of processes
;; -------------------------------------------------
;; -------------------------------------------------
(defun make-links-list ()
"Make an instance of a lockable list of links."
(svstm:make-var :val nil))
(defmethod bftypes:add-link ((list svstm:var) to-pid)
"Link a process identified by to-pid to the process indicated by
pid."
(svstm:rmw (lst list)
(adjoin to-pid lst :test #'bftypes:compare=)))
(defmethod bftypes:remove-link ((list svstm:var) to-pid)
"Remove the process link pointing to to-pid from the links owned by
process pid."
(svstm:rmw (lst list)
(remove to-pid lst :test #'bftypes:compare=)))
(defmethod bftypes:pid-links ((list svstm:var))
"Return a read-only copy of the links belonging to the PID."
(svstm:var-val list))
;; -------------------------------------------------
;; -------------------------------------------------