I would like to announce my first contribution to SBCL:
SB-TRANSACTION is a SBCL compiler plugin for the x86-64 family of CPUs
to access the new Restricted Transactional Memory (RTM) assembler
instructions dealing with hardware memory transactions (described for
introduced by Intel on Core i5 4570, Core i5 4670 and Core i7 4770.
The assembler instructions XBEGIN, XEND, XABORT and XTEST are wrapped
into regular Lisp functions:
* XBEGIN -> (transaction-begin)
* XEND -> (transaction-end)
* XABORT -> (transaction-abort)
* XTEST -> (transaction-running-p)
The additional function (transaction-supported-p) internally uses CPUID
to determine if RTM instructions are supported by the CPU.
SB-TRANSACTION is available from GitHub
https://github.com/cosmos72/stmx/tree/master/sb-transaction and is
currently packaged as a subfolder inside my library STMX
https://github.com/cosmos72/stmx - a high-performance implementation of
At the moment SB-TRANSACTION is hardware-only and STMX is software-only;
my objective is to integrate them.
Constructive feedback is welcome :)
Now, the questions:
1) where can I find some documentation about the differences between
calling (sb-c::%primitive SOME-VOP-WITH-ARGS) and calling a DEFKNOWN
I examined various online resources, including:
Paul Khuong blog
RAM’s "The Python Compiler for CMU Common Lisp"
SSE intrinsics implementation for ECL & SBCL
A relevant stackoverflow topic
And some very useful non-english pages defining simple VOPs
(russian) my-xor VOP http://lisper.ru/apps/format/138
(japanese) cpuid VOP http://kurohuku.blogspot.fi/2009/11/sbclcpuid.html
The canonical solution seems to define a function that calls a DEFKNOWN
function, and the two functions are typically the same, in an apparent
self-recursion. Unluckily, such solution seems quite fragile to me: a
simple C-c C-c on the function definition in SLIME is all it takes to
generate a real self-recursing function, bypassing the correct expansion.
On the other hand, calling (sb-c::%primitive ...) seems to generate less
optimized code with more type checks and register moves, and it does not
work for :conditional VOPs.
In any case, I found nowhere any explanation of the theorical difference
between the two.
2) I did not yet implement Hardware Lock Elision (HLE), an alternative
set of assembler instructions to use hardware transactional memory, and
it seems quite a more difficult task to me, as the relevant instructions
XACQUIRE and XRELEASE must be used as prefixes for other instructions as
MOV, LOCK XADD, and in general memory writes. In my ignorance I see no
other solution than duplicating a lot of existing VOPs as
compare-and-swap, regular memory writes... to add variants which insert
the prefixes XACQUIRE or XRELEASE. A lot of work, and a lot of
Any suggestion about a better way to implement them?