[[tags: egg]]
== hopefully
Simple composable transactional memory.
The API is similar to Clojure and STMX. However (currently) limited, focused on a low level, procedural interface.
[[toc:]]
=== Overview
This egg provides two modules: {{hopefully}} and
{{hopefully-current}}.
Module {{hopefully}} contains bindings recommended to use. These
transactions are roughly as fast as normal locking. (Depending more
on compiler optimizations and usage szenarios.)
Module {{hopefully-current}} adds support for the concept of an
implicit current transaction, which is nice but and order of magnitude
more expensive at runtime.
=== Issues
{{define-a-record}} and {{define-ac-record}} both define a
{{TYPE-FIELD}} accessor, though with incompatible semantics. While
the AC-variant is changes meaning depending on whether or not there is
a {{current-transaction}} on the thread. The A-variant always returns
the external value. The former is OK, since the whole purpose is to
be downward compatible to {{define-record}}-based code not aware of
transactions. But once most of a code base is converted to use
references, once only wants to replace {{define-ac-record}} with
{{define-a-record}}. At that time those field readers should not
suddenly change meaning anymore. The old "global" accessors should
become inaccessible. The "alway-return-global-value"
accessors need to be renamed (and the renamed value defined by {{define-ac-record}} as
well to aid the transition). Just how rename it? Append "{{@}}"?
=== Modules
==== hopefully
define-a-record
Like define-record, defines procedures according to the following
pattern.
(make-TYPE FIELDS ...) -> AREC
(TYPE-FIELD-ref AREC TNX) => REF
Return a reference for use with CELL-REF (alias "@") and ALTER!.
Note: Try to use this accessor just once per object+field. Multiple
calls (within a lightweight transaction) will produce independent
references. (If these become inconsistent, the commit will fail
nevertheless.) Only those references used to {{(set! (@ REF) val)}}
will return the in-transaction value.
(TYPE-FIELD AREC)
Return the FIELD value visible without transactions in effect.
(TYPE-tag AREC)
Purely for debugging. Mayb e removed. Return the internal version tag
of the slot.
(cell-ref REF)
Retrieve the in-transaction value from the {{REF}}erence (and add it
to the transactions dependencies).
(@ REF)
Alias to cell-ref. With generalized setter.
(alter! REF val)
Alter a {{REF}}erence (produced by the {{type}}-{{field}}-ref
accessors to hold the new value {{val}}. This also adds the cell to
the dependencies of the transaction associated with the {{REF}}.
(call-with-transaction PROC)
(call-with-transaction/values PROC)
Call PROC with one argument, a fresh (lightweight) transaction.
PROC may be called multiple times in case of a conflict.
(See hopefully-current for the difference to heavy transactions).
Returns whatever PROC returns. Use {{call-with-transaction}} for
multiple value returns {{call-with-transaction/values}} returns all
values.
Note: One {{should not}} pass the transaction argument around among
threads or capture it. Most (if not all) resulting conditions should
be handled. But it is no good idea.
==== hopefully-current
This module introduces the concept of a default
{{current-transaction}} and heavy transactions.
When a reference is added to a heavy transaction, the transactions
dependencies are searched and if a reference to the same object+slot
is found, it is returned.
define-ac-record
Like {{define-a-record}}.
{{define-ac-record}} is provided for maximum compatibility with
{{define-record}}. Just changing the record definition should make
code aware of the current transaction.
(make-TYPE FIELDS..) -> ACREC
Accessors:
(TYPE-FIELD-ref ACREC TNX) => REF
Return a reference to the in-transaction value of {{field}} in
{{ACREC}} for use with CELL-REF (alias "@") and ALTER!. See sibling
definition in {{hopefully}}.
(TYPE-FIELD ACREC)
Return the value of {{field}} in ACREC. Returns the in-transaction
value with respect to the {{current-transaction}} or the outside value
if there is no {{current-transaction}} in the {{current-thread}}.
Note: this is roughly an order of magnitude slower than the
corresponding accessor from {{define-a-record}}
(TYPE-FIELD-set! ACREC val) -> undefined
Set the value of {{field}} to {{val}}. Changes the in-transaction
value respect to the {{current-transaction}} or the outside value if
there is no {{current-transaction}} in the {{current-thread}}.
Note: this is roughly an order of magnitude slower than the
corresponding accessor from {{define-a-record}}
(with-current-transaction THUNK)
Establish a new {{current-transaction}} and call {{THUNK}}.
After thunk completed, commit the current transaction.
If that failes, THUNK is called again.
Returns whatever THUNK returns.
=== Examples
(define-a-record gbox v)
(define b1 (make-gbox 0))
(define b2 (make-gbox 1))
(call-with-transaction
(lambda (tnx)
(let ((x (gbox-v-ref b1 tnx))
(i (gbox-v-ref b2 tnx)))
(let ((ni (@ i)))
(alter! x (+ (@ x) ni))
(alter! i (add1 ni))))))
See also tests/run.scm.
=== Compile time options
-D with-disable-interrupts: disable-interrupts
-D no-dirty-tagging : save some internal consitency checks, requires -D with-disable-interrupts
-D debug: add additional consitency checks
-D warn-duplicate-ref: Issue runtime warnings about multiple
references taken (except when used with {{current-transaction}}).
Intented as debug tool only to aid transition to lightweight
transactions. (Expensive at runtime. Do not use for production
code.)
=== About this egg
==== Source
Latest version: [[http://askemos.org/chicken-eggs/hopefully/hopefully.tar.gz|hopefully from askemos.org]]
==== Authors
Jörg F. Wittenberger
==== Version History
0.2.3: 2015-12-28 -- Modified tests/run.scm as it did work on some, but not all platforms.
0.2.2: 2015-12-21 -- Bugfix: use of ##sys#setislot with non-immediate objects. Some more tweaks.
0.2.1: 2015-12-19 -- Some tweaks.
0.2: 2015-12-18 -- Replacing chicken hash tables with llrb trees made
ac-records about 4x faster.
0.1.1: 2015-12-18 -- Fix missing unquote.
0.1: 2015-12-16 -- Initial Release