• No results found

One recently proposed alternative to using locks for the protection of critical sections is transactional memory (TM). With the use of locks, consistent shared data access in crit- ical sections is provided by mutual exclusion, however, many of the problems described in Section 2.2are due to the waiting mutual exclusion induces. TM instead adopts specula- tive execution of concurrent critical sections and evaluates the results of their speculative executions to check whether consistency is violated or not.

Syntactically, critical sections are enclosed in a code block with TM, much as is done with locks protecting them. In programs using TM, the resulting code blocks are called transactions and they are delimited, and distinguished from regular code, by a starting operation (generally called start) and a terminating operation (generally called commit). A higher level syntax to delimit such code blocks is

atomic{

// transaction code block ...

}

where the starting operation is expressed with the atomic keyword combined with opening brace and the terminating operation corresponds to the closing brace. The code that appears between start and commit operations is defined as transactional code. Any code that is not transactional is called non-transactional code. Any memory access that takes place in transactional code is called transactional access, while a memory access performed in non-transactional code is called non-transactional access.

Semantically, a transaction is defined as a set of operations that performs a transfor- mation on the system state and that has the atomicity, consistency, isolation and durability properties [71,72,90]. These properties can be described as follows:

ˆ Atomicity: The execution of a transaction maintains an all-or-nothing semantics: a transaction either executes fully (i.e., it commits) or acts as if it did not execute at all (i.e., it aborts). An implication of atomicity is that a transaction is seen as a single indivisible operation.

ˆ Consistency: A transaction always acts on a consistent state. In other words, a transaction is capable of capturing a consistent snapshot for the state of the data items it accesses and performs modifications based on this consistent snapshot. Start- ing from a consistent snapshot and applying modifications atomically, as defined by the atomicity property, the transformation of a transaction execution results also in a consistent state. As long as the application does not require consistency requirements other than the consistency of concurrent accesses to the shared data (an example for such requirements can be complex invariants defined on several data items), con- sistency is satisfied by the atomicity and isolation properties of a transaction. For this reason, in the rest of the document we do not consider consistency property of transactions; atomicity and isolation will be enough to satisfy transaction semantics. ˆ Isolation: Each transaction executes as if it were the only one executing in the system. This implies that a transaction cannot see tentative modifications performed by other transactions. A transaction can only be aware of modifications made effective by committed transactions.

ˆ Durability: Once a transaction commits, its result should persist.

These properties express the fundamental behavior expected from transactions as de- fined by the database community and are generally expressed altogether as ACID properties of transactions. TM adapts the transaction abstraction defined by the database community but slightly modifies the properties such that the required promises of transaction abstrac- tion is kept, while any computational overhead that is not important in program execution is ruled out. The resulting transaction is generally called memory transaction. One notable modification in memory transaction is the strictness of durability. It is generally accepted that memory transactions exclude the durability property [113, 55, 90]. We can restate this claim as memory transactions supporting a lightweight version of durability: commit- ted state persists as long as required by the program (as is the case for any variable for example) [55]. Since the durability requirement of memory transactions is quite weak they are said to be ACI instead of being ACID.

Although semantically database and memory transactions may seem similar, there is an important distinction between them: in database transactions the data stored in the database is separated from the data in the program. Database transactions perform trans- actional access only for data on the database, while memory transactions can perform

transactional access on any data structure of the program [55, 90]. Removing the separa- tion of data in the program, a new problem arises for memory transactions. If care is not taken a multi-threaded program can perform transactional and non-transactional accesses to the same data item concurrently. This fact requires an adaptation of the atomicity and isolation properties for TMs (this issue is treated in Section 2.4).

If we compare the use of locks to transactions in terms of the ACI properties they provide to a critical section, we can say that locks, when used correctly, also achieve atomicity and isolation. Atomicity is achieved because only one thread at a time can modify data items of common interest and isolation is achieved because, by the nature of mutual exclusion, threads other than the one in the critical section will be blocked, allowing the thread in the critical section to execute in isolation. Meanwhile, contrary to using locks, a transaction has the ability to rollback and restart. This rollback ability allows speculative executions of transactions and frees transactions from blocking behavior.

Thanks to their speculative nature, transactions also allow concurrent executions of critical sections even if these executions include accesses to common data items. So if consistency would not be violated, transaction execution allow parallel executions, increasing concurrency. This is not possible when locks are used since mutual exclusion impose the execution of only one thread in its critical section.

Last but not least, transactions are clearly simpler to use for the programmer since the programmer is exempted from the onus of acquiring and releasing locks. Instead, TM manages the protection of any data accessed within its code block. The programmer only needs to delimit the code blocks where shared accesses occur.

When we consider TM semantics, we distinguish two different semantics: transaction semantics and transaction block semantics. Transaction semantics describe the seman- tics associated to TM implementations, while transaction block semantics are concerned with the semantics of the language constructs providing the transaction abstraction to the programmer. We analyze each of them in separate sections below.