There are 9 instructions in the RSTM API:
stm_init()
- must be called in each thread before any
transactions are issued
stm_dest()
- call once a thread shuts downopen_RO()
- open an object for readingopen_RW()
- open an object for writingshared()
- get a transactional wrapper for an open objectrelease()
- "close" an object opened with open_RO()
tx_alloc()
- get memory from the transaction heaptx_free()
- free memory allocated with tx_allocBEGIN_TRANSACTION
- begin a transactionEND_TRANSACTION
- end a transaction (must be at same nesting
level as BEGIN_TRANSACTION
)
To create a shared object, you need only make three changes to your existing object:
Object<T>
- this will ensure your objects
have the required additional metadata fields
T
with Shared<T>
- this will give
you access to the RSTM API
T.clone()
method - this will let RSTM copy your object
for easy rollback.
RSTM uses the following metadata organization, which is created automatically
when you inherit from Object<T>
:
It is safe to call new
and delete
on
Shared
objects from inside and outside of a transaction. It is
never safe to access pointers to the inside of Shared
objects from
outside of a transaction, as RSTM can change the internal copy of your object at
any time and garbage collect the old version.
The following example demonstrates a simple shared counter in RSTM:
class Counter : public Object<Counter> { int value; public: Counter(int startingValue) : value(startingValue) { } // clone method for use in RSTM virtual Counter* clone() { return new (stm::tx_alloc(sizeof(Counter))) Counter(value); } // increment the counter void increment() { value++; } // get the current value of the counter int getValue() { return value; } };To use this counter in a transaction, simply type:
BEGIN_TRANSACTION(counter_tx); C->open_RW(counter_tx)->increment(); END_TRANSACTION(counter_tx);(Note:
counter_tx
can be whatever name you choose, but is a
parameter to all API calls except tx_alloc()
and
tx_free()
)