scispace - formally typeset
Open AccessProceedings ArticleDOI

Model checking transactional memories

TLDR
It is shown that, under certain conditions, the verification problem can be reduced to a finite-state problem, and the use of the method is illustrated by proving the correctness of several STMs, including two-phase locking, DSTM, TL2, and optimistic concurrency control.
Abstract
Model checking software transactional memories (STMs) is difficult because of the unbounded number, length, and delay of concurrent transactions and the unbounded size of the memory We show that, under certain conditions, the verification problem can be reduced to a finite-state problem, and we illustrate the use of the method by proving the correctness of several STMs, including two-phase locking, DSTM, TL2, and optimistic concurrency control The safety properties we consider include strict serializability and opacity; the liveness properties include obstruction freedom, livelock freedom, and wait freedomOur main contribution lies in the structure of the proofs, which are largely automated and not restricted to the STMs mentioned above In a first step we show that every STM that enjoys certain structural properties either violates a safety or liveness requirement on some program with two threads and two shared variables, or satisfies the requirement on all programs In the second step we use a model checker to prove the requirement for the STM applied to a most general program with two threads and two variables In the safety case, the model checker constructs a simulation relation between two carefully constructed finite-state transition systems, one representing the given STM applied to a most general program, and the other representing a most liberal safe STM applied to the same program In the liveness case, the model checker analyzes fairness conditions on the given STM transition system

read more

Content maybe subject to copyright    Report

Model Checking Transactional Memories
Rachid Guerraoui Thomas A. Henzinger Barbara Jobstmann Vasu Singh
´
Ecole Polytechnique F´ed´erale de Lausanne (EPFL), Switzerland
{rachid.guerraoui,tah,barbara.jobstmann,vasu.singh}@epfl.ch
Abstract
Model checking software transactional memories (STMs) is diffi-
cult because of the unbounded number, length, and delay of con-
current transactions and the unbounded size of the memory. We
show that, under certain conditions, the verification problem can
be reduced to a nite-state problem, and we illustrate the use of
the method by proving the correctness of several STMs, including
two-phase locking, DSTM, TL2, and optimistic concurrency con-
trol. The safety properties we consider include strict serializability
and opacity; the liveness properties include obstruction freedom,
livelock freedom, and wait freedom.
Our main contribution lies in the structure of the proofs, which
are largely automated and not restricted to the STMs mentioned
above. In a first step we show that every STM that enjoys certain
structural properties either violates a safety or liveness requirement
on some program with two threads and two shared variables, or
satisfies the requirement on all programs. In the second step we
use a model checker to prove the requirement for the STM applied
to a most general program with two threads and two variables. In
the safety case, the model checker constructs a simulation relation
between two carefully constructed nite-state transition systems,
one representing the given STM applied to a most general program,
and the other representing a most liberal safe STM applied to the
same program. In the liveness case, the model checker analyzes
fairness conditions on the given STM transition system.
Categories and Subject Descriptors D.1.3 [Programming tech-
niques]: Concurrent Programming; D.2.4 [Software engineering]:
Software/Program Verification
General Terms Languages, Verification
Keywords Transactional memories, Model checking
1. Introduction
With the advent of multi-core processors, there is a new urgency for
concurrent programming models that give the programmer the illu-
sion of sequentiality and the compiler maximal flexibility. A model
that has enjoyed particular recent success is software transactional
memory (STM), which allows the programmer to think in coarse-
grained code blocks that appear to be executed atomically and, at
This research was supported by the Swiss National Science Foundation.
Permission to make digital or hard copies of all or part of this work for personal or
classroom use is granted without fee provided that copies are not made or distributed
for profit or commercial advantage and that copies bear this notice and the full citation
on the first page. To copy otherwise, to republish, to post on servers or to redistribute
to lists, requires prior specific permission and/or a fee.
PLDI’08
June 7–13, 2008, Tucson, Arizona, USA.
Copyright
c
2008 ACM 978-1-59593-860-2/08/06... $5.00
the same time, minimally constrains the compiler. Inspired by how
databases manage concurrency, transactional memory was first in-
troduced by Herlihy and Moss [HM93] in multi-processor design.
Later Shavit and Touitou [ST95] introduced STM, a software-based
variant of the concept, which enables a new way of looking at con-
current programming. An extensive overview of STM can be found
in [LR07]. In this paper, we consider the following STM algo-
rithms: two-phase locking, DSTM [HLMS03], TL2 [DSS06], and
optimistic concurrency control [KR81].
Precisely because STM algorithms encapsulate the difficulty of
handling concurrency, the potential of subtle errors is enormous.
This makes STM a ripe and important proving ground for for-
mal verification. While there have been initial steps in this direc-
tion [COP
+
07], the challenge remains daunting for several reasons.
First, there is no generally agreed upon formal notion of cor-
rectness for STM. Scott [Sco06] was the first to provide a formal
semantics for STM. However, his weakest correctness criterion re-
quires the order of commits to be preserved. Thus, the popular STM
algorithm TL2 [DSS06], which does not preserve the order of com-
mits, falls outside the semantic classification by Scott. Guerraoui
and Kapalka [GK08] discussed various alternatives to precisely
capture the safety aspect of STM and highlighted the subtle dif-
ferences with database transactions.
Second, while model checking is the verification technique
that is best equipped to find concurrency bugs, model checking
is severely handicapped by several sources of unbounded state in
STM: memory size, thread count, and transaction length cannot
be bounded, and neither can the delay until a transaction commits,
nor the number of times that a transaction aborts. As with relaxed
memory models, special care is needed in formulating a verification
problem that is both relevant and solvable, as some problems about
sequentializing concurrent systems are undecidable [AMP00].
Third, the specification of an STM universally quantifies over
all possible application programs, requiring the desired safety and
liveness conditions for all programs that are executed on the STM.
In this sense, STM verification resembles the problem of check-
ing that a processor implements an instruction set architecture,
where the executed programs are also universally quantified. In
both cases, the key is to define (and check) a suitable implemen-
tation relation [BD94]. While in processor verification, the imple-
mentation relation needs to handle pipelines and out-of-order exe-
cution, in STM, we need to handle aborted transactions.
We present in this paper a new technique for verifying STM
safety and liveness properties. Our technique addresses the three
issues above as follows.
First, the safety requirements we consider are strict serializ-
ability [Pap79] and opacity [GK08]. (We consider a single-version
read/write restriction of the general notion of opacity.) Strict se-
rializability preserves the order of conflicting operations between
transactions, and the order of non-overlapping transactions. Opac-
ity ensures, in addition, that aborting transactions do not see an
inconsistent state of the memory, which can be disastrous in STMs

(due to infinite loops, or exceptions). We study opacity, because it
provides the programmer with the full sequentiality illusion and is
satisfied by most STM protocols that claim that illusion [LR07].
Strict serializability is considered here for pedagogical reasons, as
it is intuitive and captures the main technical difficulties behind
verifying opacity. The liveness requirements we consider are the
standard notions of obstruction freedom [HLM03], livelock free-
dom [AKH03], and wait freedom [Her91].
Second, we exploit the structural symmetries that are inherent in
STM algorithms to reduce the verification of unbounded STM state
spaces to a problem that involves only a small number of threads
and shared variables. Specifically, we show that every STM that en-
joys certain structural properties either violates any of the consid-
ered safety and liveness requirements on some program with two
threads and two shared variables, or satisfies the requirement on
all programs. The structural properties, which expect all threads to
be treated equally, are fulfilled by most transactional algorithms,
including for instance, two-phase locking, DSTM, TL2, and op-
timistic concurrency control. Similar techniques for reducing un-
bounded instances of model-checking tasks to small, characteristic
instances have been used for verifying protocols with an unbounded
number of identical processes [BCG89] and cache-coherence pro-
tocols [HQR99].
Third, and perhaps most importantly, we define two finite-state
transition systems that generate exactly the strictly serializable
(resp. opaque) executions of programs with two threads and two
shared variables. These transition systems can be viewed as most
liberal reference STM algorithms guaranteeing strict serializability
(resp. opacity). To our knowledge, the transition systems presented
in this paper provide the rst finite-state representation of the lan-
guage of strictly serializable (resp. opaque) executions for trans-
actions that may abort. The finite size of the transition systems is
achieved by a careful choice of state, which encompasses for every
thread a set of read variables (at most two), a set of written variables
(at most two), a set of variables not allowed to be read (at most two),
a set of variables not allowed to be written (at most two), and a set
of threads with overlapping, preceding transactions (at most 1). We
show that an STM algorithm is strictly serializable (resp. opaque)
iff for a specific, most general program with two threads and two
variables, all executions are permitted by the reference STM algo-
rithm. Then, instead of checking language containment between a
given STM algorithm and the reference algorithm, we check for
the existence of a simulation relation between both transition sys-
tems [Mil71]. The existence of a simulation relation is a commonly
used, efficient sufficient condition for language containment.
Putting all steps together, we reduce the problem of verifying
the safety of an STM algorithm, which is unbounded in many di-
mensions (memory size, thread count, transaction delay, etc.), to a
simulation check between two finite-state systems. For two-phase
locking, DSTM, TL2, and optimistic concurrency control, we ob-
tain transition systems with up to 12,000 states, and the reference
transition systems have about 12,500 states. We implemented a
simulation checker that automatically verifies strict serializability
for optimistic concurrency control and opacity for two-phase lock-
ing, DSTM, and TL2 in less than 30 minutes. It should be noted
that the methodology is applicable to any other STM algorithms
that satisfy the structural properties. Our simulation checker nds
that correctness is not self-evident in many STM algorithms. For
example, we found an ambiguity in ordering of two particular op-
erations in the published TL2 algorithm [DSS06]. One of the order-
ings makes TL2 unsafe. In this case, the simulation check provides
as counterexample an execution that is not strictly serializable (and
thus not opaque). We therefore expect our verification tool to be
useful to STM designers when they develop or modify STM algo-
rithms.
On the liveness side, we prove again a structural reduction the-
orem to check the desired liveness requirement on the nite-state
transition system that results from a given STM algorithm applied
to a most general program with two threads and one variable. We
built a model checking tool to verify the different liveness proper-
ties. In the case of obstruction freedom, this amounts to checking
a Streett condition. The check goes through for DSTM. For two-
phase locking, TL2, and optimistic concurrency control, the model
checker automatically generates counterexamples to obstruction
freedom, as it does for DSTM and livelock freedom.
2. Safety in transactional memories
We introduce a few notions about transactions, and then formalize
the correctness of transactional memories.
Let V be a set {1, . . . , k} of k variables, and let C =
{commit} ({read, write} × V ) be the set of commands on the
variables V . Also, let
ˆ
C = C {abort}. Let T = {1, . . . , n}
be a set of n threads. Let
ˆ
S =
ˆ
C × T be the set of statements.
Also, let S = C × T . A word w
ˆ
S
is a finite sequence of
statements. Given a word w
ˆ
S
, we define the thread projection
w|
t
of w on thread t T as the subsequence of w consisting of all
statements s in w such that s
ˆ
C × {t}. Given a thread projection
w|
t
= s
0
. . . s
m
of a word w on thread t, a statement s
i
is finishing
in w|
t
if it is a commit or an abort. A statement s
i
is initiating in
w|
t
if it is the first statement in w |
t
, or the previous statement s
i1
is a finishing statement.
Given a thread projection w|
t
of a word w on thread t, a
consecutive subsequence x = s
0
. . . s
m
of w|
t
is a transaction
of thread t in w if (i) s
0
is initiating in w|
t
, and (ii) s
m
is either
finishing in w|
t
, or s
m
is the last statement in w|
t
, and (iii) no other
statement in x is finishing in w|
t
. The transaction x is committing in
w if s
m
is a commit. The transaction x is aborting in w if s
m
is an
abort. Otherwise, the transaction x is unfinished in w. Given a word
w and two transactions x and y in w (possibly of different threads),
we say that x precedes y in w, written as x <
w
y, if the last
statement of x occurs before the first statement of y in w. A word
w is sequential if for every pair x, y of transactions in w, either
x <
w
y or y <
w
x. We define a function com :
ˆ
S
S
such
that for all words w
ˆ
S
, the word com(w) is the subsequence of
w that consists of every statement in w that is part of a committing
transaction.
A transaction x of a thread t writes to a variable v if x contains
a statement ((write, v), t). A statement s = ((read, v), t) in x is
a global read of a variable v if there is no statement ((write, v), t)
before s in the transaction x. A transaction x of a thread t globally
reads a variable v if there exists a global read of variable v in
transaction x. A word w is transaction equivalent to a word w
if for every thread t T , we have w|
t
= w
|
t
. Note that two
transaction equivalent words have the same order of commands for
all threads.
2.1 Safety criteria
Conflict serializability [EGLT76] is a commonly used correctness
criterion for concurrent systems and, in particular, for transactional
systems. Conflict serializability allows us to omit the values of
read and write commands, since the consistency of the values fol-
lows from preserving the order of conflicts. In the context of trans-
actional memories, a stronger property, called strict serializabil-
ity, is considered. Strict serializability preserves the order of non-
overlapping transactions too. We note that strict serializability does
not state any restrictions on the operations of the aborting trans-
actions. In the scope of STMs, an even stronger notion of correct-
ness, referred to as opacity, has been suggested [HLMS03, GK08]
to avoid unexpected side effects, like infinite loops, or array bound

violations. Opacity requires that a word be strictly serializable, and
that even aborting transactions do not read inconsistent values.
Now, we formalize these correctness criteria. We start with
the notion of a conflict. Transactional memories use direct update
semantics (every transaction modifies the shared variables in place
and restores them upon abort), or deferred update semantics (every
transaction modifies a local copy, and changes the shared copy
upon a commit). We choose to define conflicts under the deferred
update semantics. A statement s
1
of transaction x and a statement
s
2
of transaction y (where x is different from y) conflict in a word w
if (i) s
1
is a global read of some variable v, and s
2
is a commit, and
y writes to v, or (ii) s
1
and s
2
are both commits, and x and y write
to the same variable v. A word w = s
0
. . . s
m
is conflict equivalent
to a word w
if (i) w is transaction equivalent to w
, and (ii) for
every pair s
i
, s
j
of statements in w, if s
i
and s
j
conflict and i < j,
then s
i
occurs before s
j
in w
. Note that transaction equivalence
ensures that conflict equivalence is a symmetric relation, since w
is a permutation of w.
A word w = s
0
. . . s
m
is strictly equivalent to a word w
if (i)
w is conflict equivalent to w
, and (ii) for every pair x, y of trans-
actions in w, where x is a committing or an aborting transaction, if
x <
w
y, then it is not the case that y <
w
x. A word w
ˆ
S
is
strictly serializable if there exists a sequential word w
such that w
is strictly equivalent to com(w). Furthermore, a word w is opaque
if there exists a sequential word w
such that w
is strictly equiva-
lent to w. We note that given a word w, if w is opaque, then w is
strictly serializable. An infinite word w
ˆ
S
ω
is strictly serializ-
able (resp. opaque) if every finite prefix of w is strictly serializable
(resp. opaque).
Example. Consider a word w = ((read, v
1
), t
1
), ((write, v
1
), t
2
),
((write, v
2
), t
2
), (commit, t
2
), ((read, v
2
), t
1
), (abort, t
1
). w has
two transactions: (i) an aborting transaction of t
1
, and (ii) a com-
mitting transaction of t
2
. The following pairs of statements conflict:
(((read, v
1
), t
1
),(commit, t
2
)) and (((read, v
2
), t
1
), (commit, t
2
)).
The word w is strictly serializable because com(w) = ((write, v
1
),
t
2
), ((write, v
2
), t
2
), (commit, t
2
). On the other hand, w is not
opaque since t
1
reads the old value of v
1
(before t
2
commits) and
the new value of v
2
(committed by t
2
).
2.2 Transactional memories
We consider thread programs as our basic sequential unit of com-
putations. We express thread programs as infinite binary trees on
commands. This makes the representation independent of specific
control flow statements, such as exceptions for handling aborts of
transactions. For every command of a thread, we define two succes-
sor commands, one if the command is successfully executed, and
another if the command fails due to an abort of the transaction. Note
that this definition allows us to capture easily different retry mech-
anisms of TMs, e.g., retry the same transaction until it succeeds or
try another transaction after an abort. We use a set of thread pro-
grams to define a multithreaded program. Formally, a thread pro-
gram θ on a set C of commands is a function θ : B
C. We
write Θ for the set of thread programs. A (multithreaded) program
p on n threads and k variables is an n-tuple p = hθ
1
, . . . , θ
n
i of
thread programs on C. Figure 1(a) shows an example program on
two threads and two variables. Let P
n,k
be the set of all programs
on n threads and k variables. Let P be the set of all programs.
We define a transactional memory as an abstract function that
takes as input a program, and produces a set of infinite words.
Formally, a transactional memory (TM) is a function M : P
2
ˆ
S
ω
. A transactional memory M ensures strict serializability (resp.
opacity) for all programs with n threads and k variables if for every
program p P
n,k
, every word w M(p) is strictly serializable
(resp. opaque). Moreover, a transactional memory M ensures strict
(read, v
1
)
(read, v
1
) (write, v
2
)
0 1
(read, v
1
)
(write, v
1
)
(write, v
1
)
10 10
(commit)
(commit)
θ
1
: θ
2
:
(a) An example program on two threads
and two variables
Program
TM Algorithm
Scheduler
Execution
trace
CommandsResponse
(b) Interaction in
the model
Figure 1. Our framework of transactional memory
serializability (resp. opacity) if it ensures strict serializability (resp.
opacity) for all programs with an arbitrary number of threads and
variables.
3. Transactional memory algorithms
We use state transition systems to define TM. A TM algorithm is
a family of TM transition systems, one for n threads and k vari-
ables, for every n and k. A TM transition system consists of a set
of states, an initial state, an extended set of commands depending
on the underlying TM, a pending function, and a transition rela-
tion between the states. The extended commands include the set C
of commands, and TM specific additional commands. For exam-
ple, a given TM may require that a thread locks a variable before
writing to the variable, or that a thread validates the variables read
in a transaction, before accessing a new variable. Every extended
command is assumed to execute atomically. The pending function
represents the pending command of a thread in a state, and ensures
that if a thread has not nished the execution of a particular com-
mand, then no other command is executed by the thread.
A TM algorithm interacts with a program and a scheduler (see
Fig. 1(b)). The scheduler chooses a thread, which determines the
next command to be executed. The TM transition system decides
whether the command can be executed in a single atomic step, or
in several atomic steps (using additional extended commands), or
has to be aborted. The TM algorithm gives back to the program a
response. The response is if the TM algorithm needs additional
steps to complete the command, 0 if the TM algorithm needs to
abort the transaction, and 1 if the TM algorithm has completed
the command. Given a program, a scheduler, and a TM transition
system, we get a run. Projecting the run to the set of successful
statements (that is, aborts, and statements that get response 1) gives
a word in
ˆ
S
ω
. We describe the language of a TM transition system
as the set of words on
ˆ
S
ω
that it can produce for any program and
any scheduler.
Formally, a scheduler σ on T is a function σ : N T . We
define a TM algorithm A as a family of TM transition systems
A
n,k
= hQ, q
init
, D, π, δi for each n and k, where Q is a set of
states, q
init
is the initial state, D is the set of extended commands
with C D, the function π : Q × T C {⊥} represents
the pending command in a state for a thread , and δ Q ×
ˆ
C ×
ˆ
S
D
× Resp × Q is the deterministic or non-deterministic transition
relation, where
ˆ
S
D
= (D {abort}) × T and Resp = {⊥, 0, 1}.
The transition relation δ and the pending function π obey the
following rules:
1. For all threads t T , we have π(q
init
, t) =.
2. For all states q, q
Q such that there exists an incoming
transition ( q, c, (d, t), r, q
) δ to q
, if r =, then π(q
, t) = c,
otherwise π(q
, t) =.
3. For all states q, q
Q such that there exists an incoming
transition (q , c, (d, t), r, q
) δ to q
, then π(q
, u) = π(q, u)
for all threads u 6= t.

4. For all states q and all threads t, if π(q, t) = c where c 6=, then
for all outgoing transitions (q, c
1
, (d, t), r, q
) δ from q, we have
c
1
= c.
5. For all states q and all threads t, if π(q, t) =, then there
exists an outgoing transition (q, c, (d, t), r, q
δ from q for every
command c C.
6. For all q Q, for all transitions (q, c, (d, t) , r, q
) δ, we have
d = abort if and only if r = 0.
Note that the rules above restrict the transition relation and
the pending function π such that π is unique. A command c is
enabled in a state q for thread t if π( q, t) {⊥, c} (i.e., either
no command is pending, or c itself is pending). In a deterministic
transition relation δ, a command c is abort enabled in a state
q for thread t if c is enabled in q for thread t and there is no
transition (q, c, (d, t), r, q
) δ such that d D. A transition
relation δ is deterministic if for all q Q and (c, t) S, if
(q, c, (d
1
, t), r
1
, q
1
) δ and (q, c, (d
2
, t), r
2
, q
2
) δ, then d
1
=
d
2
, r
1
= r
2
, and q
1
= q
2
. Unless otherwise stated, TM transition
systems have deterministic transition relations. We shall use non-
deterministic TM transition systems later to describe reference TM
algorithms.
Let p = hθ
1
, . . . , θ
n
i be a program in P
n,k
. Let σ be a sched-
uler on n threads. A run ρ = hq
0
, l
0
, (d
0
, t
0
), r
0
ihq
1
, l
1
, (d
1
, t
1
),
r
1
i . . . of a TM transition system A
n,k
with scheduler σ on pro-
gram p is an infinite sequence of tuples of states, program lo-
cations, statements, and responses, where l
j
= h l
1
j
, . . . , l
n
j
i
(B
)
n
for all j 0 and the following hold: (i) q
0
= q
init
and l
0
= hǫ, . . . , ǫi, (ii) for all j 0, there exists a transi-
tion (q
j
, c
j
, (d
j
, t
j
), r
j
, q
j+1
) δ such that t
j
= σ(j) and
c
j
= θ
t
j
(l
t
j
j
) and for all t T , we have l
t
j+1
= l
t
j
if either
t 6= t
j
or r
j
=, and l
t
j+1
= l
t
j
· r
j
otherwise. Given a sched-
uler and a program, there is exactly one run for a deterministic TM
transition system A
n,k
, whereas there is at least one run for a non-
deterministic TM transition system. We say that a statement s
j
ˆ
S
is successful in the run ρ = h q
0
, l
0
, s
0
, r
0
ihq
1
, l
1
, s
1
, r
1
i . . . if (i)
r
j
{0, 1}, or (ii) r
k
= 1 with j < k and r
j+1
. . . r
k1
are all
equal to . We define the language L(A
n,k
) of A
n,k
as the set
of all infinite words w
ˆ
S
ω
such that w is the sequence of all
successful statements in a run of A
n,k
with some scheduler on n
threads, on some program on n threads and k variables. For a TM
algorithm A , we require that for n n
and k k
, the language
L(A
n,k
) L(A
n
,k
).
A TM algorithm A defines a transactional memory M such
that for all n and k , for every program p in P
n,k
and every word
w
ˆ
S
ω
, we have w M(p) iff there exists a scheduler σ on
T and a corresponding run ρ of A
n,k
with σ on p such that w
is the sequence of all successful statements in ρ. It follows that
a TM defined by a TM algorithm A ensures strict serializability
(resp. opacity) for all programs with n threads and k variables iff
all words in L(A
n,k
) are strictly serializable (resp. opaque).
In the following sections, we describe different transactional
memories as TM algorithms. To simplify the description, we view
a state q of the corresponding TM transition systems as an n-tuple
hq
1
. . . q
n
i, where each component q
t
corresponds to a thread t and
is called the thread state of t.
3.1 The sequential TM
To keep our first example simple, we describe a sequential TM. The
sequential TM executes the transactions sequentially (as ideally
suited for a uniprocessor). We define the sequential TM M
seq
using
a sequential TM algorithm A
seq
. The sequential TM transition
system A
n,k
seq
for n threads and k variables is given by the tuple
hQ, q
init
, D, π, δi. The thread state q
t
of thread t is in {T, F}.
If a thread t has an unfinished transaction in a state q, then the
thread state q
t
is T, and F otherwise. The initial state q
init
=
hF, . . . , Fi. The set of extended commands is D = C. A transition
(q
1
, c, (d, t), r, q
2
) is in δ if c is enabled in q
1
for thread t and one
of the following holds:
1. Read (resp. write). (i) c = (read, v) (resp. c = (write, v)) and
d = c and r = 1, and (ii) q
u
1
= F for all u 6= t, and (iii) q
t
2
= T
and q
u
2
= q
u
1
for all u 6= t. When a thread reads (resp. writes) a
variable, if the state of all other threads is F, then the state of t is
set to T.
2. Commit. (i) c = commit and d = c and r = 1, and (ii) q
u
1
= F
for all u 6= t, and (iii) q
t
2
= F and q
u
2
= q
u
1
for all u 6= t. When a
thread commits, if the state of all other threads is F, then the state
of t is set to F.
A transition (q
1
, c, (abort, t), 0, q
2
) is in δ if c is abort enabled
in q
1
for thread t and q
2
= q
1
.
3.2 The two-phase locking TM
Our second example of a TM algorithm is based on two-phase lock-
ing (2PL) protocol, commonly used in database transactions. Every
transaction locks the variables it reads or writes before accessing
them, and releases all acquired locks during the commit. A shared
lock is acquired for reading, and an exclusive lock is acquired for
writing. We define the 2PL TM M
2PL
using a 2PL TM algorithm
A
2PL
. The 2PL TM transition system A
n,k
2PL
for n threads and k
variables is given by the tuple hQ, q
init
, D, π, δi. The thread state
q
t
of thread t is a pair hrs, wsi, where rs V is the set of vari-
ables locked by t in shared mode, and ws V is the set of vari-
ables locked in exclusive mode. For every thread, the initial thread
state of thread t is q
t
init
= h∅, ∅i. The set of extended commands is
D = C ({rlock , wlock} × V ). A transition (q
1
, c, (d, t), r, q
2
) is
in δ if c is enabled in q
1
for thread t and one of the following holds:
1. Read. (i) c = (read, v) and d = c and r = 1, and (ii)
v ws
t
1
rs
t
1
, and (iii) q
2
= q
1
. When a thread reads a variable
that already exists in the read set or the write set of the thread, then
the state does not change.
2. Write. (i) c = (write, v) and d = c and r = 1, and (ii) v ws
t
1
,
and (iii) q
2
= q
1
. When a thread writes to a variable that already
exists in the write set of the thread, then the state does not change.
3. Read Lock. (i) c = (read, v) and d = (rlock, v) and r =,
and (ii) v / rs
t
1
and v / ws
u
1
for all threads u, and (iii) rs
t
2
=
rs
t
1
{v}, and (iv) q
u
2
= q
u
1
for all threads u 6= t. When a thread t
reads v, and v is not in the read set of t, and v is not in the write set
of any thread, then v is added to the read set of t.
4. Write Lock. (i) c = (write, v) and d = (wlock, v) and r =,
and (ii) v / ws
t
1
and v / rs
u
1
ws
u
1
for all threads u 6= t, and (iii)
rs
t
2
= rs
t
1
{v}, and (iv) q
u
2
= q
u
1
for all threads u 6= t. When a
thread writes v, and v is not in the write set of t, and v is not in the
read set or write set of any thread other than t, then v is added to
the write set of t.
4. Commit. (i) c = commit and d = c and r = 1, and (ii) rs
t
2
= ,
and ws
t
2
= , and (iii) for all threads u 6= t, we have q
u
2
= q
u
1
.
When a thread commits, the read set and the write set are changed
to empty.
A transition (q
1
, c, (abort, t), 0, q
2
) is in δ if c is abort enabled
in q
1
for thread t and rs
t
2
= and ws
t
2
= , and q
u
2
= q
u
1
for all
threads u 6= t.
3.3 The dynamic software transactional memory
Dynamic software transactional memory (DSTM) [HLMS03] is
one of the most popular STM algorithms. The algorithm exists
in several avors. In this work, we focus on one of them, called
invisible read DSTM, where the transactions require ownership of
variables only for writing. The readers are not visible to the writers.
Upon reading, a transaction validates its read set in order to ensure
opacity. In our work, we ignore optimizations like early release

possible in DSTM. We model the situation of a transaction aborting
another transaction by allowing each transaction to set an abort
flag for other transactions, and requiring that a transaction aborts
whenever the abort flag is set for the thread. We define DSTM
TM M
dstm
using a DSTM TM algorithm A
dstm
. The DSTM TM
transition system A
n,k
dstm
for n threads and k variables is given by
hQ, q
init
, D, π, δi. A thread state q
t
of thread t is defined as a 3-
tuple hstatus
t
, rs
t
, os
t
i, where status
t
{aborted, validated,
invalid, finished} is the status of thread t, and rs
t
V is the
read set of thread t, and os
t
V is the ownership set of thread
t. For every thread, the initial thread state of thread t is q
t
init
=
hfinished, , ∅i. The set of extended commands is D = C
({own} × V ) {validate}. A transition (q
1
, c, (d, t), r, q
2
) is in δ
if c is enabled in q
1
for thread t and one of the following holds:
1. Local read. (i) c = (read, v) and d = c and r = 1, and (ii)
v os
t
1
and status
t
1
6= aborted, and (iii) q
2
= q
1
. When a thread
reads v such that the read is not global, the state does not change.
2. Global read. (i) c = (read, v) and d = c and r = 1, and (ii)
v / os
t
1
and status
t
1
= finished, and (iii) rs
t
2
= rs
t
2
{v} and
os
t
2
= os
t
1
and status
t
2
= status
t
1
, and (iv) q
u
2
= q
u
1
for all threads
u 6= t. When a thread reads v globally, if the status of the thread is
finished, then v is added to the read set of the thread.
3. Own. (i) c = ( write, v) and d = (own, v) and r =, and (ii)
status
t
1
6= aborted, and (iii) rs
t
2
= rs
t
1
and os
t
2
= os
t
1
{v}
and status
t
2
= status
t
1
, and (iv) for all threads u 6= t, if v os
u
1
,
then status
u
2
= aborted, and os
u
2
= , and rs
u
2
= , otherwise
status
u
2
= status
u
1
and os
u
2
= os
u
1
and rs
u
2
= rs
u
1
. When a
thread writes to v, if the status of the thread is not aborted, then
the variable v is added to the owned set of the thread, and if some
thread owns v, then the status of that thread is set to aborted and
its read set and own set are set to empty.
4. Write. (i) c = (write, v) and d = c and r = 1, and (ii)
status
t
1
6= aborted and v os
t
1
, and (iii) q
u
2
= q
u
1
for all u T .
When a thread writes to v, if the status is not aborted and v is in the
own set of the thread, then the state does not change.
5. Validate. (i) c = commit and d = validate and r =, and
(ii) status
t
1
= finished and status
t
2
= validated, and (iii) for
all threads u 6= t, we have rs
u
2
= rs
u
1
and os
u
2
= os
u
1
, and if
rs
t
1
os
u
1
6= , then status
u
2
= aborted, else status
u
2
= status
t
1
.
When a thread t commits, if the status is finished, then the status is
changed to validated, and for all threads u whose own set intersects
with the read set of t, the status of u is changed to aborted.
6. Commit. (i) c = commit and d = c and r = 1, and (ii)
status
t
1
= validated, and (iii) os
t
2
= , and rs
t
2
= and
status
t
2
= finished, and (iv) for all threads u 6= t, we have rs
u
2
=
rs
u
1
and os
u
2
= os
u
1
, and if rs
u
1
os
t
1
6= , then status
u
2
= invalid,
else status
u
2
= status
u
1
. When a thread t commits, if the status is
validated, then the own set and read set of t are set to empty and
the status is set to finished, and the status of threads, whose read
set intersects with the own set of t, is set to invalid.
A transition (q
1
, c, (abort, t), 0, q
2
) is in δ if the command c
is abort enabled in q
1
for thread t, and status
t
2
= finished, and
rs
t
2
= and os
t
2
= , and q
u
2
= q
u
1
for all threads u 6= t.
3.4 The TL2 transactional memory
Transactional locking 2 (TL2) [DSS06] is a TM that uses global
version numbers to ensure correctness. Version numbers allow ef-
ficient read set validation in a distributed setting. We model ver-
sion numbers using modified sets for each thread. When a trans-
action commits, it adds its write set to the modified set of ev-
ery thread with an unfinished transaction. We define the TL2 TM
M
TL2
using the TL2 TM algorithm as A
TL2
. The TL2 TM tran-
sition system A
n,k
TL2
for n threads and k variables is given by the
tuple hQ, q
init
, D, π, δi. A thread state q
t
of t in the TL2 algo-
rithm is defined as a 5-tuple hstatus
t
, rs
t
, ws
t
, ls
t
, ms
t
i, where
status
t
{validated, finished}, rs
t
V is the read set, ws
t
V
is the write set, ls
t
V is the lock set, and ms
t
V is the
modified set. The initial thread state q
t
init
= hfinished, , , , ∅i
for all threads t T . The set of extended commands is D =
C ({lock} × V ) {validate }. A transition (q
1
, c, (d, t), r, q
2
)
is in δ if c is enabled in q
1
for t and one of the following holds:
1. Local read. (i) c = (read, v) and d = c and r = 1, and (ii)
v ws
t
1
and q
2
= q
1
. When a thread reads v such that the read is
not global, the state does not change.
2. Global read. (i) c = (read, v) and d = c and r = 1, and (ii)
v / ws
t
1
and v / ms
t
1
, and (iii) rs
t
2
= rs
t
1
{v} and ls
t
2
= ls
t
1
and ws
t
2
= ws
t
1
and ms
t
2
= ms
t
1
and status
t
2
= status
t
1
, and (iv)
for all threads u 6= t, we have q
u
2
= q
u
1
. When a thread reads v and
the read is global, if the variable is not in the modified set, then v is
added to the read set.
3. Write. (i) c = (write, v) and d = c and r = 1, and (ii)
ws
t
2
= ws
t
1
{v} and ls
t
2
= ls
t
1
and rs
t
2
= rs
t
1
and ms
t
2
= ms
t
1
and status
t
2
= status
t
1
, and (iv) q
u
2
= q
u
1
for all threads u 6= t.
When a thread writes to v, the variable v is added to its write set.
4. Lock. (i) c = commit and d = (lock, v) and r = , and (ii)
status
t
1
= finished and v ws
t
1
and (iii) there is no thread u T
such that v ls
u
1
, and (iv) ls
t
2
= ls
t
1
{v} and rs
t
2
= rs
t
1
and
ws
t
2
= ws
t
1
and ms
t
2
= ms
t
1
and status
t
2
= status
t
1
, and (v) for
all threads u 6= t, we have q
u
2
= q
u
1
. When a thread t commits, if
the status is finished and v is in the write set of t and v is not in the
lock set of any thread, then v is added to the lock set of t.
5. Validate. (i) c = commit and d = validate and r =, and (ii)
status
t
1
= finished and rs
t
1
ms
t
1
= and ws
t
1
= ls
t
1
and for all
threads u 6= t, we have rs
t
1
ls
u
1
= , and (iii) status
t
2
= validated
and ls
t
2
= ls
t
1
and rs
t
2
= rs
t
1
and ws
t
2
= ws
t
1
and ms
t
2
= ms
t
1
,
and (iv) q
u
2
= q
u
1
for all threads u 6= t When a thread commits,
if the status is finished, and the read set does not intersect with the
modified set, and the write set is equal to the lock set, and the read
set does not intersect with the lock set of any other thread, then the
status is set to validated.
6. Commit. (i) c = commit and d = c and r = 1, and (ii)
status
t
1
= validated, and (iii) rs
t
2
= ls
t
2
= ws
t
2
= ms
t
2
=
and status
t
2
= finished, and (iv) for all threads u 6= t, we have
rs
u
2
= rs
u
1
and ws
u
2
= ws
u
1
and ls
u
2
= ls
u
1
and status
u
2
=
status
u
1
. (v) for all threads u 6= t such that rs
u
1
ws
u
1
6= , we
have ms
u
2
= ms
u
1
ws
t
1
. When a thread t commits, if the status
is validated, then the status is changed to finished, and the read,
write, lock, and modified sets are set to empty, and all variables
written by t are added to the modified sets of all threads that have
an unfinished transaction.
A transition (q
1
, c, (abort, t), 0, q
2
) is in δ if the command c
is abort enabled in q
1
for thread t, and status
t
2
= finished, and
rs
t
2
= ws
t
2
= ls
t
2
= ms
t
2
= , and q
u
2
= q
u
1
for all threads u 6= t.
3.5 The optimistic concurrency control TM
We now discuss a common concurrency protocol used in databases.
It was proposed by Kung et al. [KR81], and is called optimistic
concurrency control (OCC). OCC executes the transactions of the
threads without any synchronization. Before committing, every
transaction chooses a sequence number and validates its read set.
Transactions commit in the order of sequence numbers, which
we model using precedence sets, similar to the way we modeled
version numbers using modified sets in the TL2 TM algorithm.
We define the OCC TM M
occ
using an OCC TM algorithm
A
occ
. We refer to the OCC TM transition system with n threads
and k variables as A
n,k
occ
. The formal definition of the transition
system can be obtained from the original algorithm, as we did in
the previous examples.
Table 1 shows runs with different schedules on the program in
Figure 1(a), for each TM algorithm described above.

Citations
More filters
Book

Transactional Memory, 2nd Edition

TL;DR: This book presents an overview of the state of the art in the design and implementation of transactional memory systems, as of early spring 2010.
Proceedings ArticleDOI

Semantics of transactional memory and automatic mutual exclusion

TL;DR: This paper develops semantics and type systems for the constructs of the Automatic Mutual Exclusion (AME) programming model and model STM systems that use in-place update, optimistic concurrency, lazy conflict detection, and roll-back.
Book

Principles of Transactional Memory

TL;DR: The aim of this book is to provide theoretical foundations for transactional memory, as well as answering precisely when a TM implementation is correct, what kind of properties it can ensure, what are the power and limitations of a TM, and what inherent trade-offs are involved in designing a TM algorithm.
Journal ArticleDOI

Semantics of transactional memory and automatic mutual exclusion

TL;DR: This article develops semantics and type systems for the constructs of the Automatic Mutual Exclusion (AME) programming model for STM systems that use in-place update, optimistic concurrency, lazy conflict detection, and rollback.
Journal ArticleDOI

Towards formally specifying and verifying transactional memory

TL;DR: TMS1 (Transactional Memory Specification 1), a precise specification of correct behaviour of a TM runtime library, is presented and a simulation proof that TMS2 implements TMS1 is presented, thus showing that to prove that an implementation satisfies T MS1, it suffices to proved that it satisfies TMS 2.
References
More filters
Proceedings ArticleDOI

Transactional memory: architectural support for lock-free data structures

TL;DR: Simulation results show that transactional memory matches or outperforms the best known locking techniques for simple benchmarks, even in the absence of priority inversion, convoying, and deadlock.
Journal ArticleDOI

The notions of consistency and predicate locks in a database system

TL;DR: It is argued that a transaction needs to lock a logical rather than a physical subset of the database, and an implementation of predicate locks which satisfies the consistency condition is suggested.
Journal ArticleDOI

Wait-free synchronization

TL;DR: A hierarchy of objects is derived such that no object at one level has a wait-free implementation in terms of objects at lower levels, and it is shown that atomic read/write registers, which have been the focus of much recent attention, are at the bottom of the hierarchy.
Journal ArticleDOI

On optimistic methods for concurrency control

TL;DR: In this paper, two families of non-locking concurrency controls are presented, which are optimistic in the sense that they rely mainly on transaction backup as a control mechanism, "hoping" that conflicts between transactions will not occur.
Proceedings ArticleDOI

Software transactional memory

TL;DR: STM is used to provide a general highly concurrent method for translating sequential object implementations to non-blocking ones based on implementing a k-word compare&swap STM-transaction, a novel software method for supporting flexible transactional programming of synchronization operations.