A very simple STM library for Common Lisp. Strictly proof of concept and useless for any purpose.
Common Lisp
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
tests
.gitignore
README.markdown
cl-transactional-tests.asd
cl-transactional.asd
package.lisp
transactions.lisp
tvars.lisp

README.markdown

cl-transactional

Initial notes

This is a proof of concept STM system implemented in a quite naive and likely buggy way. I wrote this mostly to get an idea how such things can be implemented, and have not used it since.

For any serious Common Lisp STM needs the cl-stm system is probably much better. That said, since I dropped it on GitHub I might just as well document it. I suppose there is a possibility that it might be informational to someone.

Basic ideas

This system is much simpler than aforementioned cl-stm because it puts more responsibility on the user. While cl-stm uses the code walker to capture side effects into transactions, this system assumes all information is shared through special references to immutable data, called tvars following Haskell example. Of course, unlike in Haskell it is not possible to enforce neither the immutability of referenced data or that tvars will be accessed though transaction logs.

Immutable datastructures are available though, for example, FSet library.

Transactions as implemented here are in principle composable.

Dependencies

  • SBCL

sb-thread is used directly. bordeaux-threads does not have non-waiting with-mutex.

  • Iterate
  • Alexandria

Tests (what few there are) require also:

  • stefil
  • fset

Reference

Note that transaction failure is communicated using signals. Creating a t condition handler will break them.

Function make-tvar &optional value

Create a transactional variable with an optional initial value.

Function get-tvar tvar &optional transaction-log wrapping-logs

Function tvar-ref tvar

Mostly synonymous. Optional arguments of the first form are used internally and default to thread-local special bindings. Access contents of a transactional variable. Can be used outside of transaction.

Function put-tvar tvar new-value &optional transaction-log wrapping-logs

Function (setf tvar-ref) new-value tvar

Mostly synonymous. Optional arguments of the first form are used internally and default to thread-local special bindings. Sets contents of a transactional variable. Can be used outside of transaction.

Function retry-transaction

Restart transaction. Will suspend the thread until one of the tvars which were accessed so far in the transaction is changed.

Function with-retry-transaction &body body

Execute body within transaction. It will be retried if any tvars which were read during it have been changed.

Function with-orelse-transaction &body (alternative-body)*

Execute bodies withing orelse transaction, ie. if the first fails, the second is immediately attempted and so on. If all fail and there was at least one explicit (retry-transaction) the thread will be suspended until some referenced tvar changes.