168 research outputs found
Concurrent Data Structures Linked in Time
Arguments about correctness of a concurrent data structure are typically
carried out by using the notion of linearizability and specifying the
linearization points of the data structure's procedures. Such arguments are
often cumbersome as the linearization points' position in time can be dynamic
(depend on the interference, run-time values and events from the past, or even
future), non-local (appear in procedures other than the one considered), and
whose position in the execution trace may only be determined after the
considered procedure has already terminated.
In this paper we propose a new method, based on a separation-style logic, for
reasoning about concurrent objects with such linearization points. We embrace
the dynamic nature of linearization points, and encode it as part of the data
structure's auxiliary state, so that it can be dynamically modified in place by
auxiliary code, as needed when some appropriate run-time event occurs. We name
the idea linking-in-time, because it reduces temporal reasoning to spatial
reasoning. For example, modifying a temporal position of a linearization point
can be modeled similarly to a pointer update in separation logic. Furthermore,
the auxiliary state provides a convenient way to concisely express the
properties essential for reasoning about clients of such concurrent objects. We
illustrate the method by verifying (mechanically in Coq) an intricate optimal
snapshot algorithm due to Jayanti, as well as some clients
An Epistemic Perspective on Consistency of Concurrent Computations
Consistency properties of concurrent computations, e.g., sequential
consistency, linearizability, or eventual consistency, are essential for
devising correct concurrent algorithms. In this paper, we present a logical
formalization of such consistency properties that is based on a standard logic
of knowledge. Our formalization provides a declarative perspective on what is
imposed by consistency requirements and provides some interesting unifying
insight on differently looking properties
Linearizability with Ownership Transfer
Linearizability is a commonly accepted notion of correctness for libraries of
concurrent algorithms. Unfortunately, it assumes a complete isolation between a
library and its client, with interactions limited to passing values of a given
data type. This is inappropriate for common programming languages, where
libraries and their clients can communicate via the heap, transferring the
ownership of data structures, and can even run in a shared address space
without any memory protection. In this paper, we present the first definition
of linearizability that lifts this limitation and establish an Abstraction
Theorem: while proving a property of a client of a concurrent library, we can
soundly replace the library by its abstract implementation related to the
original one by our generalisation of linearizability. This allows abstracting
from the details of the library implementation while reasoning about the
client. We also prove that linearizability with ownership transfer can be
derived from the classical one if the library does not access some of data
structures transferred to it by the client
A History of BlockingQueues
This paper describes a way to formally specify the behaviour of concurrent
data structures. When specifying concurrent data structures, the main challenge
is to make specifications stable, i.e., to ensure that they cannot be
invalidated by other threads. To this end, we propose to use history-based
specifications: instead of describing method behaviour in terms of the object's
state, we specify it in terms of the object's state history. A history is
defined as a list of state updates, which at all points can be related to the
actual object's state.
We illustrate the approach on the BlockingQueue hierarchy from the
java.util.concurrent library. We show how the behaviour of the interface
BlockingQueue is specified, leaving a few decisions open to descendant classes.
The classes implementing the interface correctly inherit the specifications. As
a specification language, we use a combination of JML and permission-based
separation logic, including abstract predicates. This results in an abstract,
modular and natural way to specify the behaviour of concurrent queues. The
specifications can be used to derive high-level properties about queues, for
example to show that the order of elements is preserved. Moreover, the approach
can be easily adapted to other concurrent data structures.Comment: In Proceedings FLACOS 2012, arXiv:1209.169
Verifying Concurrent Stacks by Divergence-Sensitive Bisimulation
The verification of linearizability -- a key correctness criterion for
concurrent objects -- is based on trace refinement whose checking is
PSPACE-complete. This paper suggests to use \emph{branching} bisimulation
instead. Our approach is based on comparing an abstract specification in which
object methods are executed atomically to a real object program. Exploiting
divergence sensitivity, this also applies to progress properties such as
lock-freedom. These results enable the use of \emph{polynomial-time}
divergence-sensitive branching bisimulation checking techniques for verifying
linearizability and progress. We conducted the experiment on concurrent
lock-free stacks to validate the efficiency and effectiveness of our methods
Simplifying proofs of linearisability using layers of abstraction
Linearisability has become the standard correctness criterion for concurrent
data structures, ensuring that every history of invocations and responses of
concurrent operations has a matching sequential history. Existing proofs of
linearisability require one to identify so-called linearisation points within
the operations under consideration, which are atomic statements whose execution
causes the effect of an operation to be felt. However, identification of
linearisation points is a non-trivial task, requiring a high degree of
expertise. For sophisticated algorithms such as Heller et al's lazy set, it
even is possible for an operation to be linearised by the concurrent execution
of a statement outside the operation being verified. This paper proposes an
alternative method for verifying linearisability that does not require
identification of linearisation points. Instead, using an interval-based logic,
we show that every behaviour of each concrete operation over any interval is a
possible behaviour of a corresponding abstraction that executes with
coarse-grained atomicity. This approach is applied to Heller et al's lazy set
to show that verification of linearisability is possible without having to
consider linearisation points within the program code
Specifying and Verifying Concurrent Algorithms with Histories and Subjectivity
We present a lightweight approach to Hoare-style specifications for
fine-grained concurrency, based on a notion of time-stamped histories that
abstractly capture atomic changes in the program state. Our key observation is
that histories form a partial commutative monoid, a structure fundamental for
representation of concurrent resources. This insight provides us with a
unifying mechanism that allows us to treat histories just like heaps in
separation logic. For example, both are subject to the same assertion logic and
inference rules (e.g., the frame rule). Moreover, the notion of ownership
transfer, which usually applies to heaps, has an equivalent in histories. It
can be used to formally represent helping---an important design pattern for
concurrent algorithms whereby one thread can execute code on behalf of another.
Specifications in terms of histories naturally abstract granularity, in the
sense that sophisticated fine-grained algorithms can be given the same
specifications as their simplified coarse-grained counterparts, making them
equally convenient for client-side reasoning. We illustrate our approach on a
number of examples and validate all of them in Coq.Comment: 17 page
- …