The Transactional Memory module provides transactional semantics when accessing main memory. You can load and store variables in main memory, or adopt memory regions into a transactions. More...
Files | |
file | picotm-tm-ctypes.h |
Provides Transactional Memory operations for native C types. | |
file | picotm-tm.h |
Public interfaces of picotm's Transactional Memory module. | |
The Transactional Memory module provides load and store operations for main memory. In order to avoid conflicting access to shared memory locations, picotm has to know which transaction uses which locations. The Transactional Memory module maintains these information.
A call to load_tx()
copies a memory location's value into a transaction, as illustrated in the example below.
This copies the value of x
into our transaction's variable x_tx
and puts the memory location of x
under control of the transaction manager. We are free to change the value of x_tx
at will, since it's transaction local. If we change it, the original non-transactional value in x
remains unchanged.
In a similarly way we store a copy of a transactional variable in a memory location. This is done with store_tx()
.
As with all transactional modifications, the store will not be executed immediately, but only become permanent after the transaction successfully committed.
We don't have to deal with all these addresses ourselves. The TM module comes with helper functions for the basic C types. With load_int_tx()
and store_int_tx()
we can rewrite the example transactions as shown below.
Besides load_int_tx()
and store_int_tx()
, the Transactional Memory module provides similar functions for the basic C types. Each is defined via the macros PICOTM_TM_LOAD_TX()
and PICOTM_TM_STORE_TX()
. We can use these macros to define load and store functions for our application's data types. Both macros expand to inline C functions, so we don't loose performance compared to load_tx()
and store_tx()
.
Since address and pointer handling can be tricky, there are also helpers for loading and storing pointers. These functions load and store the address stored in a pointer variable, but not the value stored at that address.
Loads and stores always copy values into or out of a transaction. There are cases where we don't want a copy, but the exact memory location of a value. This is called privatization. For example, the function memcpy()
loads and stores an indefinite amount of data between memory buffers. The actual buffer size is often not known in advance. It would be wasteful to first load the data into a transaction-local buffer and then further store it in another buffer.
The functions privatize_tx()
and privatize_c_tx()
offer privatization of memory locations.
This privatizes x
for transactional access from within the transaction. The number of bytes is given in the second argument. The flags argument is a bitmask of PICOTM_TM_PRIVATIZE_LOAD
and PICOTM_TM_PRIVATIZE_STORE
. These flags control how picotm handles the memory location. If we only privatized a memory location for loading or storing, we may never invoke the other operation. Setting no flags at all will discard the memory location. This signals to other transactions that the memory is invalid and to be freed.
There can be cases where we don't know in advance how large in size the privatized buffer is going to be. For example, if we privatize a C string, the length is not explicitly stored in the string, but given by the location of the terminating \0
character. To privatize a memory region up to and including a specific character, there is privatize_c_tx()
.
Using privatize_c_tx()
with strings is the most common use case, but arbitrary characters are possible.
Finally, there is loadstore_tx()
. Even through the name suggests load-and-store, the function is a mixture of load, store and privatization. It privatizes an input buffer for loading and an output buffer for storing, and copies the input buffer's content into the output buffer.
A call to loadstore_tx()
is like a call to memcpy()
that privatizes its input buffers. It's an optimization for platform without transactional C library.