On Reachability in Parameterized Phaser Programs
 1 Citations
 5.5k Downloads
Abstract
We address the problem of statically checking safety properties (such as assertions or deadlocks) for parameterized phaser programs. Phasers embody a nontrivial and modern synchronization construct used to orchestrate executions of parallel tasks. This generic construct supports dynamic parallelism with runtime registrations and deregistrations of spawned tasks. It generalizes many synchronization patterns such as collective and pointtopoint schemes. For instance, phasers can enforce barriers or producerconsumer synchronization patterns among all or subsets of the running tasks. We consider in this work programs that may generate arbitrarily many tasks and phasers. We propose an exact procedure that is guaranteed to terminate even in the presence of unbounded phases and arbitrarily many spawned tasks. In addition, we prove undecidability results for several problems on which our procedure cannot be guaranteed to terminate.
1 Introduction
We focus on the parameterized verification problem of parallel programs that adopt the phasers construct for synchronization [15]. This coordination construct unifies collective and pointtopoint synchronization. Parameterized verification is particularly relevant for mainstream parallel programs as the number of interdependent tasks in many applications, from scientific computing to web services or ebanking, may not be known apriori. Parameterized verification of phaser programs is a challenging problem due to the arbitrary numbers of involved tasks and phasers. In this work, we address this problem and provide an exact symbolic verification procedure. We identify parameterized problems for which our procedure is guaranteed to terminate and prove the undecidability of several variants on which our procedure cannot be guaranteed to terminate in general.
Phasers build on the clock construct from the X10 programming language [5] and are implemented in Habanero Java [4]. They can be added to any parallel programming language with a shared address space. Conceptually, phasers are synchronization entities to which tasks can be registered or unregistered. Registered tasks may act as producers, consumers, or both. Tasks can individually issue signal, wait, and next commands to a phaser they are registered to. Intuitively, a signal command is used to inform other tasks registered to the same phaser that the issuing task is done with its current phase. It increments the signal value associated to the issuing task on the given phaser. The wait command on the other hand checks whether all signal values in the phaser are strictly larger than the number of waits issued by this task, i.e. all registered tasks have passed the issuing task’s wait phase. It then increments the wait value associated to the task on the phaser. As a result, the wait command might block the issuing task until other tasks issue enough signals. The next command consists in a signal followed by a wait. The next command may be associated to a sequence of statements that are to be executed in isolation by one of the registered tasks participating in the command. A program that does not use this feature of the next statement is said to be nonatomic. A task deregisters from a phaser by issuing a drop command on it.
The dynamic synchronization allowed by the construct suits applications that need dynamic load balancing (e.g., for solving nonuniform problems with unpredictable load estimates [17]). Dynamic behavior is enabled by the possible runtime creation of tasks and phasers and their registration/deregistration. Moreover, the spawned tasks can work in different phases, adding flexibility to the synchronization pattern. The generality of the construct makes it also interesting from a theoretical perspective, as many language constructs can be expressed using phasers. For example, synchronization barriers of Single Program Multiple Data programs, the Bulk Synchronous Parallel computation model [16], or promises and futures constructs [3] can be expressed using phasers.

We show an operational model for phaser programs based on [4, 6, 9, 15].

We propose an exact symbolic verification procedure for checking reachability of sets of configurations for nonatomic phaser programs even when arbitrarily many tasks and phasers may be generated.

We prove undecidability results for several reachability problems.

We show termination of our procedure when checking assertions for nonatomic programs even when arbitrary many tasks may be spawned.

We show termination of our procedure when checking deadlockfreedom and assertions for nonatomic programs with bounded gaps between signal and wait values, even when arbitrary many tasks may be spawned.
2 Motivating Example
The program listed in Fig. 1 uses Boolean shared variables \(\mathtt {B}=\left\{ {\mathtt {a},\mathtt {done}}\right\} \). The main task creates two phasers (line 4–5). When creating a phaser, the task gets automatically registered to it. The main task also creates an unbounded number of other task instances (lines 7–8). When a task \(t\) is registered to a phaser \(p\), a pair \((w_{t}^{p},s_{t}^{p})\) in \(\mathbb {N}^2\) can be associated to the couple \((t,p)\). The pair represents the individual wait and signal phases of task \(t\) on phaser \(p\).
Registration of a task to a phaser can occur in one of three modes: \(\mathrm {\textsc {Sig\_Wait}}\), \(\mathrm {\textsc {Wait}}\) and \(\mathrm {\textsc {Sig}}\). In \(\mathrm {\textsc {Sig\_Wait}}\) mode, a task may issue both \(\mathtt {signal}\) and \(\mathtt {wait}\) commands. In \(\mathrm {\textsc {Wait}}\) (resp. \(\mathrm {\textsc {Sig}}\)) mode, a task may only issue \(\mathtt {wait}\) (resp. \(\mathtt {signal}\)) commands on the phaser. Issuing a \(\mathtt {signal}\) command by a task on a phaser results in the task incrementing its signal phase associated to the phaser. This is nonblocking. On the otherhand, issuing a \(\mathtt {wait}\) command by a task on a phaser \(p\) will block until all tasks registered to \(p\) get signal values on \(p\) that are strictly larger than the wait value of the issuing task. The wait phase of the issuing task is then incremented. Intuitively, signals allow issuing tasks to state other tasks need not wait for them. In retrospect, waits allow tasks to make sure all registered tasks have moved past their wait phases.
Upon creation of a phaser, wait and signal phases are initialized to 0 (except in \(\mathrm {\textsc {Wait}}\) mode where no signal phase is associated to the task in order to not block other waiters). The only other way a task may get registered to a phaser is if an already registered task spawns and registers it in the same mode (or in \(\mathrm {\textsc {Wait}}\) or \(\mathrm {\textsc {Sig}}\) if the registrar is registered in \(\mathrm {\textsc {Sig\_Wait}}\)). In this case, wait and signal phases of the newly registered task are initialized to those of the registrar. Tasks are therefore dynamically registered (e.g., lines 7–8). They can also dynamically deregister themselves (e.g., line 10–11).
Here, an unbounded number of producers and consumers synchronize using two phasers. Consumers require producers to be ahead wrt. the phaser they point to with \(\mathtt {p}\). At the same time, consumers need to be ahead of all producers wrt. the phaser pointed to with \(\mathtt {c}\). It should be clear that phasers can be used as barriers for synchronizing dynamic subsets of concurrent tasks. Observe that tasks need not, in general, proceed in a lock step fashion. The difference between the largest signal value and the smallest wait value can be arbitrarily large (several signals before waits catch up). This allows for more flexibility.
We are interested in checking: (a) control reachability as in assertions (e.g., line 20), race conditions (e.g., mutual exclusion of lines 20 and 33) or registration errors (e.g., signaling a dropped phaser), and (b) plain reachability as in deadlocks (e.g., a producer at line 19 and a consumer at line 30 with equal phases waiting for each other). Both problems deal with reachability of sets of configurations. The difference is that control state reachability defines the targets with the states of the tasks (their control locations and whether they are registered to some phasers). Plain reachability can, in addition, constrain values of the phases in the target configurations (e.g., requiring equality between wait and signal values for deadlocks).
3 Phaser Programs and Reachability
Initially, a unique task instance starts executing the \(\mathtt {main()\{\mathtt {stmt}\}}\) task. A phaser can recall a pair of values (i.e., wait and signal) for each task instance registered to it. A task instance can create a new phaser with \(\mathtt {v}=\mathtt {newPhaser()}\), get registered to it (i.e., gets zero as wait and signal values associated to the new phaser) and refer to the phaser with its local variable \(\mathtt {v}\). We simplify the presentation by assuming all registrations to be in \(\mathrm {\textsc {Sig\_Wait}}\) mode. Including the other modes is a matter of depriving \(\mathrm {\textsc {Wait}}\)registered tasks of a signal value (to ensure they do not block other registered tasks) and of ensuring issued commands respect registration modes. We use \(\mathtt {V}\) for the union of all local phaser variables. A task \(\mathtt {task}(\mathtt {v}_{1},\ldots ,\mathtt {v}_{k}) \left\{ {\mathtt {stmt}}\right\} \) in \(\mathtt {T}\) takes the phaser variables \(\mathtt {v}_1, \ldots \mathtt {v}_k\) as parameters (write \(\mathtt {paramOf}(\mathtt {task})\) to mean these parameters). A task instance can spawn another task instance with \(\mathtt {asynch(\mathtt {task},\mathtt {v}_1,\ldots ,\mathtt {v}_n)}\). The issuing task instance registers the spawned task to the phasers pointed to by \(\mathtt {v}_1,\ldots ,\mathtt {v}_n\), with its own wait and signal values. Spawner and Spawnee execute concurrently. A task instance can deregister itself from a phaser with \(\mathtt {v}\mathtt {.drop()}\).
A task instance can issue signal or wait commands on a phaser referenced by \(\mathtt {v}\) and on which it is registered. A wait command on a phaser blocks until the wait value of the task instance executing the wait on the phaser is strictly smaller than the signal value of all task instances registered to the phaser. In other words, \(\mathtt {v}.\texttt {wait()}\) blocks if \(\mathtt {v}\) points to a phaser such that at least one of the signal values stored by the phaser is equal to the wait value of the task that tries to perform the wait. A signal command does not block. It only increments the signal value of the task instance executing the signal command on the phaser. \(\mathtt {v}.\mathtt {next()}\) is syntactic sugar for a signal followed by a wait. Moreover, \(\mathtt {v}.\mathtt {next()\{\mathtt {stmt}\}}\) is similar to \(\mathtt {v}.\mathtt {next()}\) but the block of code \(\mathtt {stmt}\) is executed atomically by exactly one of the tasks participating in the synchronization before all tasks continue the execution that follows the barrier. \(\mathtt {v}.\mathtt {next()\{\mathtt {stmt}\}}\) thus requires all tasks to be synchronized on exactly the same statement and is less flexible. Absence of a \(\mathtt {v}.\mathtt {next()\{\mathtt {stmt}\}}\) makes a program nonatomic.
Note that assignment of phaser variables is excluded from the syntax; additionally, we restrict task creation \(\mathtt {asynch(\mathtt {task},\mathtt {v}_1,\ldots ,\mathtt {v}_n)}\) and require that parameter variables \(\mathtt {v}_i\) are all different. This prevents two variables from pointing to the same phaser and avoids the need to deal with aliasing: we can reason on the single variable in a process that points to a phaser. Extending our work to deal with aliasing is easy but would require heavier notations.
We will need the notions of configurations, partial configurations and inclusion in order to define the reachability problems we consider in this work. We introduce them in the following and assume a phaser program \(\mathtt {prg}=\left( {\mathtt {B},\mathtt {V},\mathtt {T}}\right) \).
Configurations. Configurations of a phaser program describe valuations of its variables, control sequences of its tasks and registration details to the phasers.
Control sequences. We define the set \(\mathtt {Suff}\) of control sequences of \(\mathtt {prg}\) to be the set of suffixes of all sequences \(\mathtt {stmt}\) appearing in some statement \(\mathtt {task}(\ldots )\left\{ {\mathtt {stmt}}\right\} \). In addition, we define \(\mathtt {UnrSuff}\) to be the smallest set containing \(\mathtt {Suff}\) in addition to the suffixes of all (i) \(\mathtt {s}_1;\mathtt {while(\mathtt {cond})\left\{ { \mathtt {s}_1 }\right\} };\mathtt {s}_2\) if \(\mathtt {while(\mathtt {cond})\left\{ { \mathtt {s}_1 }\right\} };\mathtt {s}_2\) is in \(\mathtt {UnrSuff}\), and of all (ii) \(\mathtt {s}_1;\mathtt {s}_2\) if \(\mathtt {if(\mathtt {cond}) \left\{ { \mathtt {s}_1 }\right\} };\mathtt {s}_2\) is in \(\mathtt {UnrSuff}\), and of all (iii) \(\mathtt {s}_1;\mathtt {v}.\mathtt {next()\{\}};\mathtt {s}_2\) if \(\mathtt {v}.\mathtt {next()\{\mathtt {s}_1\}};\mathtt {s}_2\) in \(\mathtt {UnrSuff}\), and finally of all (iv) \(\mathtt {v}.\mathtt {signal()};\mathtt {v}.\texttt {wait()}{};\mathtt {s}_2\) if \(\mathtt {v}.\mathtt {next()\{\}};\mathtt {s}_2\) is in \(\mathtt {UnrSuff}\). We write \(\mathtt {hd}(\mathtt {s})\) and \(\mathtt {tl}(\mathtt {s})\) to respectively mean the head and the tail of a sequence \(\mathtt {s}\).

Open image in new window is a finite set of task identifiers. We let \(t,u\) range over the values in Open image in new window .

Open image in new window is a finite set of phaser identifiers. We let \(p,q\) range over the values in Open image in new window .

Open image in new window fixes the values of some of the shared variables.^{1}

Open image in new window fixes the control sequences of some of the tasks.

Open image in new window is a mapping that associates to each task \(t\) in Open image in new window a partial mapping stating which phasers are known by the task and with which registration values.
Intuitively, partial configurations are used to state some facts about the valuations of variables and the control sequences of tasks and their registrations. Partial configurations leave some details unconstrained using partial mappings or the symbol \(*\). For instance, if Open image in new window in a partial configuration Open image in new window , then the partial configuration does not constrain the value of the shared variable \(\mathtt {b}\). Moreover, a partial configuration does not constrain the relation between a task \(t\) and a phaser \(p\) when Open image in new window is undefined. Instead, when the partial mapping Open image in new window is defined on phaser \(p\), it associates a pair Open image in new window to \(p\). If \(\mathtt {var}\in {\mathtt {V}}^{\left\{ {,*}\right\} }\) is a variable \(\mathtt {v}\in \mathtt {V}\) then the task \(t\) in Open image in new window uses its variable \(\mathtt {v}\) to refer to the phaser \(p\) in Open image in new window ^{2}. If \(\mathtt {var}\) is the symbol − then the task \(t\) does not refer to \(\mathtt {v}\) with any of its variables in \(\mathtt {V}\). If \(\mathtt {var}\) is the symbol \(*\), then the task might or might not refer to \(p\). The value \(\mathtt {val}\) in Open image in new window is either the value \(\mathtt {nreg}\) or a pair \((w_{}^{},s_{}^{})\). The value \(\mathtt {nreg}\) means the task \(t\) is not registered to phaser \(p\). The pair \((w_{}^{},s_{}^{})\) belongs to \((\mathbb {N}\times \mathbb {N})\cup \left\{ {(*,*)}\right\} \). In this case, task \(t\) is registered to phaser \(p\) with a wait phase \(w_{}^{}\) and a signal phase \(s_{}^{}\). The value \(*\) means that the wait phase \(w_{}^{}\) (resp. signal phase \(s_{}^{}\)) can be any value in \(\mathbb {N}\). For instance, Open image in new window means variable \(\mathtt {v}\) of the task \(t\) refers to phaser \(p\) but the task is not registered to \(p\). On the other hand, Open image in new window means the task \(t\) does not refer to \(p\) but is registered to it with arbitrary wait and signal phases.
Concrete configurations. A concrete configuration (or configuration for short) is a partial configuration Open image in new window where Open image in new window is total for each Open image in new window and where the symbol \(*\) does not appear in any range. It is a tuple Open image in new window where Open image in new window , Open image in new window , and Open image in new window . For a concrete configuration Open image in new window , we write Open image in new window to mean the predicate Open image in new window . The predicate Open image in new window captures whether the task \(t\) is registered to phaser \(p\) according to the mapping Open image in new window .
We are interested in the reachability of sets of configurations (i.e., checking safety properties). We differentiate between two reachability problems depending on whether the target sets of configurations constrain the registration phases or not. The plain reachability problem may constrains the registration phases of the target configurations. The control reachability problem may not. We will see that decidability of the two problems can be different. The two problems are defined in the following.
Plain reachability. First, we define equivalent configurations. A configuration Open image in new window is equivalent to configuration Open image in new window if Open image in new window and there are bijections Open image in new window and Open image in new window such that, for all Open image in new window , Open image in new window and \(var\in {\mathtt {V}}^{\left\{ {}\right\} }\), Open image in new window and there are some integers Open image in new window such that Open image in new window iff Open image in new window . We write \(c\sim c'\) to mean that \(c\) and \(c'\) are equivalent. Intuitively, equivalent configurations simulate each other. We can establish the following:
Lemma 1
(Equivalence). Assume two configurations \(c_1\) and \(c_2\). If \(c_1\xrightarrow []{}c_2\) and \(c_1'\sim c_1\) then there is a configuration \(c_2'\) s.t. \(c_2'\sim c_2\) and \(c_1'\xrightarrow []{}c_2'\).
Observe that if the wait value of a task \(t\) on a phaser \(p\) is equal to the signal of a task \(t'\) on the same phaser \(p\) in some configuration \(c\), then this is also the case, up to a renaming of the phasers and tasks, in all equivalent configurations. This is particularly relevant for defining deadlock configurations where a number of tasks are waiting for each other. The plain reachability problem is given a program and a target partial configuration and asks whether a configuration (equivalent to a configuration) that includes the target partial configuration is reachable.
More formally, given a program \(\mathtt {prg}\) and a partial configuration \(c\), let \(c_{init}\) be the initial configuration of \(\mathtt {prg}\), then \(\mathtt {reach}(\mathtt {prg},c)\) if and only if \(c_{init}\xrightarrow []{}^* c_1\) for \(c_1\sim c_2\) and \(c_2\) includes \(c\).
Definition 1
(Plain reachability). For a program \(\mathtt {prg}\) and a partial configuration \(c\), decide whether \(\mathtt {reach}(\mathtt {prg},c)\) holds.
Control reachability. A partial configuration Open image in new window is said to be a control partial configuration if for all Open image in new window and Open image in new window , either Open image in new window is undefined or Open image in new window . Intuitively, control partial configurations do not constrain phase values. They are enough to characterize, for example, configurations where an assertion is violated (see Fig. 2).
Definition 2
(Control reachability). For a program \(\mathtt {prg}\) and a control partial configuration \(c\), decide whether \(\mathtt {reach}(\mathtt {prg},c)\) holds.
Observe that plain reachability is at least as hard to answer as control reachability since any control partial configuration is also a partial configuration. It turns out the control reachability problem is undecidable for programs resulting in arbitrarily many tasks and phasers as stated by the theorem below. This is proven by reduction of the state reachability problem for 2counter Minsky machines. A 2counter Minsky machine \(\left( {S,\left\{ {x_1,x_2}\right\} ,\varDelta ,s_0,s_F}\right) \) has a finite set S of states, two counters \(\left\{ {x_1,x_2}\right\} \) with values in \(\mathbb {N}\), an initial state \(s_0\) and a final state \(s_F\). Transitions may increment, decrement or test a counter. For example \(\left( {s_0,\text {test}(x_1),s_F}\right) \) takes the machine from \(s_0\) to \(s_F\) if the counter \(x_1\) is zero.
Theorem 1
(Minsky machines [14]). Checking whether \(s_F\) is reachable from configuration \((s_0,0,0)\) for 2counter machines is undecidable in general.
Theorem 2
Control reachability is undecidable in general.
Proof sketch. State reachability of an arbitrary 2counters Minsky machine is encoded as the control reachability problem of a phaser program. The phaser program (see [10]) has three tasks \(\mathtt {main}\), \(\mathtt {xUnit}\) and \(\mathtt {yUnit}\). It uses Boolean shared variables to encode the state \(s\in S\) and to pass information between different task instances. The phaser program builds two chains, one with \(\mathtt {xUnit}\) instances for the xcounter, and one with \(\mathtt {yUnit}\) instances for the ycounter. Each chain alternates a phaser and a task and encodes the values of its counter with its length. The idea is to have the phaser program simulate all transitions of the counter machine, i.e., increments, decrements and tests for zero. Answering state reachability of the counter machine amounts to checking whether there are reachable configurations where the boolean variables encoding the counter machine can evaluate to the target machine state \(s_F\).
4 A GapBased Symbolic Representation
The symbolic representation we propose builds on the following intuitions. First, observe the language semantics impose, for each phaser, the invariant that signal values are always larger or equal to wait values. We can therefore assume this fact in our symbolic representation. In addition, our reachability problems from Sect. 3 are defined in terms of reachability of equivalence classes, not of individual configurations. This is because configurations violating considered properties (see Fig. 2) are not defined in terms of concrete phase values but rather in terms of relations among them (in addition to the registration status, control sequences and variable values). Finally, we observe that if a wait is enabled with smaller gaps on a given phaser, then it will be enabled with larger ones. We therefore propose to track the gaps of the differences between signal and wait values wrt. to an existentially quantified level (per phaser) that lies between wait and signal values of all tasks registered to the considered phaser.
We formally define our symbolic representation and describe a corresponding entailment relation. We also establish a desirable property (namely being a \(\mathcal {WQO}\), i.e., wellquasiordering [1, 8]) on some classes of representations. This is crucial for the decidability of certain reachability problems (see Sect. 5).
Named gaps. A named gap is associated to a taskphaser pair. It consists in a tuple (var, val) in \(\mathbb {G}=\left( {{\mathtt {V}}^{\left\{ {,*}\right\} } \times \left( \left( \mathbb {N}^4 \cup \left( \mathbb {N}^2\times \left\{ {\infty }\right\} ^2\right) \right) \cup \left\{ {\mathtt {nreg}}\right\} \right) } \right) \). Like for partial configurations in Sect. 3, \(var\in {\mathtt {V}}^{\left\{ {,*}\right\} }\) constrains variable values. The val value describes task registration to the phaser. If registered, then val is a 4tuple \((\mathtt {lw},\mathtt {ls},\mathtt {uw},\mathtt {us})\). This intuitively captures, together with some level l common to all tasks registered to the considered phaser, all concrete wait and signal values \((w_{}^{},s_{}^{})\) satisfying \(\mathtt {lw}\le (lw_{}^{}) \le \mathtt {uw}\) and \(\mathtt {ls}\le (s_{}^{}l)\le \mathtt {us}\). A named gap \((var,(\mathtt {lw},\mathtt {ls},\mathtt {uw},\mathtt {us}))\) is said to be free if \(\mathtt {uw}=\mathtt {us}=\infty \). It is said to be Bgapbounded, for \(B\in \mathbb {N}\), if both \(\mathtt {uw}\le B\) and \(\mathtt {us}\le B\) hold. A set Open image in new window is said to be free (resp. Bgapbounded) if all its named gaps are free (resp. Bgapbounded). The set Open image in new window is said to be Bgood if each one of its named gaps is either free or Bgapbounded. Finally, Open image in new window is said to be good if it is Bgood for some \(B\in \mathbb {N}\). Given a set Open image in new window of named gaps, we define the partial order \(\unlhd \) on Open image in new window , and write \((var,val) \unlhd (var',val')\), to mean (i) \(\left( var\ne var'\Rightarrow var=*\right) \), and (ii) \((val = \mathtt {nreg}) \Longleftrightarrow (val' = \mathtt {nreg})\), and (iii) if \(val=(\mathtt {lw},\mathtt {ls},\mathtt {uw},\mathtt {us})\) and \(val'=(\mathtt {lw}',\mathtt {ls}',\mathtt {uw}',\mathtt {us}')\) then \(\mathtt {lw}\le \mathtt {lw}'\), \(\mathtt {ls}\le \mathtt {ls}'\), \(\mathtt {uw}' \le \mathtt {uw}\) and \(\mathtt {us}' \le \mathtt {us}\). Intuitively, named gaps are used in the definition of constraints to capture relations (i.e., reference, registration and possible phases) of tasks and phasers. The partial order \((var,val) \unlhd (var',val')\) ensures relations allowed by \((var',val')\) are also allowed by (var, val).

Open image in new window and Open image in new window respectively represent, like for partial configurations, a valuation of the shared Boolean variables and a mapping of tasks to their control sequences.

Open image in new window constrains relations between Open image in new window tasks and Open image in new window phasers by associating to each task \(t\) a mapping Open image in new window that defines for each phaser \(p\) a named gap \((var,val)\in \mathbb {G}\) capturing the relation of \(t\) and \(p\).

Open image in new window associates lower bounds \((\mathtt {ew},\mathtt {es})\) on gaps of tasks that are registered to Open image in new window phasers but which are not explicitly captured by Open image in new window . This is described further in the constraints denotations below.
We write Open image in new window to mean the task \(t\) is registered to the phaser \(p\), i.e., Open image in new window . A constraint \(\phi \) is said to be free (resp. Bgapbounded or Bgood) if the set Open image in new window is free (resp. Bgapbounded or Bgood). The dimension of a constraint is the number of phasers it requires (i.e., Open image in new window ). A set of constraints \(\varPhi \) is said to be free, Bgapbounded, Bgood or Kdimensionbounded if each of its constraints are.
 1.
for each \(\mathtt {b}\in \mathtt {B}\), Open image in new window , and
 2.
Open image in new window and Open image in new window can be written as Open image in new window and Open image in new window , with
 3.
Open image in new window is a surjection and Open image in new window is a bijection, and
 4.
for Open image in new window with \(t_\phi =\tau (t_c)\), Open image in new window , and
 5.for each \(p_\phi =\pi (p_c)\), there is a natural level Open image in new window such that:
 (a)if Open image in new window with \(t_\phi =\tau (t_c)\), Open image in new window and Open image in new window , then it is the case that:
 i.
\((var_c\ne var_\phi ) \implies (var_\phi =*)\), and
 ii.
\((val_c=\mathtt {nreg}) \Longleftrightarrow (val_\phi =\mathtt {nreg})\), and
 iii.
if \((val_c=(w_{}^{},s_{}^{}))\) and \((val_\phi =(\mathtt {lw},\mathtt {ls},\mathtt {uw},\mathtt {us}))\) then Open image in new window and Open image in new window .
 i.
 (b)
if Open image in new window , then for each \(p_\phi =\pi (p_c)\) with Open image in new window and Open image in new window , we have: Open image in new window and Open image in new window
 (a)
Intuitively, for each phaser, the bounds given by Open image in new window constrain the values of the phases belonging to tasks captured by Open image in new window (i.e., those in Open image in new window ) and registered to the given phaser. This is done with respect to some nonnegative level, one per phaser. The same level is used to constrain phases of tasks registered to the phaser but not captured by Open image in new window (i.e., those in Open image in new window ). For these tasks, lower bounds are enough as we only want to ensure they do not block executions to target sets of configurations. We write \([\![{\phi }]\!]\) for Open image in new window .
 1.
Open image in new window , for each \(\mathtt {b}\in \mathtt {B}\) and
 2.
Open image in new window and Open image in new window can be written as Open image in new window and Open image in new window with
 3.
Open image in new window is a surjection and Open image in new window is a bijection, and
 4.
Open image in new window for each Open image in new window with \(t_a=\tau (t_b)\), and
 5.for each phaser \(p_a=\pi (p_b)\) in Open image in new window :
 (a)
if Open image in new window and Open image in new window then \(\mathtt {ew}_a \le \mathtt {ew}_b\) and \(\mathtt {es}_a\le \mathtt {es}_b\)
 (b)for each Open image in new window with \(t_a=\tau (t_b)\) and Open image in new window , and Open image in new window , it is the case that:
 i.
\((var_b \ne var_a) \implies (var_a=*)\), and
 ii.
\((val_b=\mathtt {nreg}) \Longleftrightarrow (val_a=\mathtt {nreg})\), and
 iii.
if \(val_a=(\mathtt {lw}_a,\mathtt {ls}_a,\mathtt {uw}_a,\mathtt {us}_a)\) and \(val_b=(\mathtt {lw}_b,\mathtt {ls}_b,\mathtt {uw}_b,\mathtt {us}_b)\), then \((\mathtt {lw}_a \le \mathtt {lw}_b)\), \((\mathtt {ls}_a \le \mathtt {ls}_b)\), \((\mathtt {uw}_b \le \mathtt {uw}_a)\) and \((\mathtt {us}_b \le \mathtt {us}_a)\).
 i.
 (c)
for each Open image in new window with Open image in new window , with Open image in new window , both \((\mathtt {ew}_a \le \mathtt {lw}_b)\) and \((\mathtt {es}_a \le \mathtt {ls}_b)\) hold.
 (a)
The following lemma shows that it is safe to eliminate entailing constraints in the working list procedure of Sect. 5.
Lemma 2
(Constraint entailment). \(\phi _a\sqsubseteq \phi _b\) implies \([\![{\phi _b}]\!]\subseteq [\![{\phi _a}]\!]\)
A central contribution that allows establishing the positive results of Sect. 5 is to show \(\sqsubseteq \) is actually \(\mathcal {WQO}\) on any Kdimensionbounded and Bgood set of constraints. For this, we prove Open image in new window is \(\mathcal {WQO}\) if Open image in new window is Bgood, where Open image in new window is the set of multisets over Open image in new window and \(M{{~}_\exists \!\!\preceq _\forall }\ M'\) requires each \((\mathtt {s}',g'_1,\ldots ,g'_K)\in M'\) may be mapped to some \((\mathtt {s},g_1,\ldots ,g_K)\in M\) for which \(\mathtt {s}=\mathtt {s}'\) and \(g_i \unlhd g_i'\) for each \(i:1\le i \le K\) (written Open image in new window ). Intuitively, we need to use \({{~}_\exists \!\!\preceq _\forall }\), and not simply \({{~}_\forall \!\!\preceq _\exists }\), in order to “cover all registered tasks” in the larger constraint as otherwise some tasks may block the path to the target configurations. Rado’s structure [12, 13] shows that, in general, \((\mathcal {M}\left( {S}\right) ,{{~}_\exists \!\!\preceq _\forall })\) need not be \(\mathcal {WQO}\) just because \(\preceq \) is \(\mathcal {WQO}\) over S. The proof details can be found in [10].
Theorem 3
\((\varPhi ,\sqsubseteq )\) is \(\mathcal {WQO}\) if \(\varPhi \) is Kdimensionbounded and Bgood for some predefined \(K,B\in \mathbb {N}\).
5 A Symbolic Verification Procedure
The procedure computes a fixpoint using the entailment relation of Sect. 4 and a predecessor computation that results, for a constraint \(\phi \) and a statement \(\mathtt {stmt}\), in a finite set Open image in new window . Figure 4 describes part of the computation for the \(\mathtt {v}.\mathtt {signal()}\) instruction (see [10] for other instructions). For all but atomic statements, the set Open image in new window is exact in the sense that \(\left\{ {c' ~~c\in [\![{\phi }]\!] \text { and } c'\xrightarrow [\mathtt {stmt}]{}{}c }\right\} \subseteq \bigcup _{\phi '\in \mathtt {pre_\mathtt {stmt}}}[\![{\phi '}]\!] \subseteq \left\{ {c' ~~c\in [\![{\phi }]\!] \text { and } c'\xrightarrow [\mathtt {stmt}]{}^+c }\right\} \). Intuitively, the predecessors calculation for the atomic \(\mathtt {v}.\mathtt {next()\{\mathtt {stmt}\}}\) is only an overapproximation because such an instruction can encode a testandset operation. Our representation allows for more tasks, but the additional tasks may not be able to carry the atomic operation. We would therefore obtain a nonexact overapproximation and avoid this issue by only applying the procedure to nonatomic programs. We can show the following theorems.
Theorem 4
Control reachability is decidable for nonatomic phaser programs generating a finite number of phasers.
The idea is to systematically drop, in the instantiated backward procedure, constraints violating Kdimensionboundedness (as none of the denoted configurations is reachable). Also, the set of target constraints is free (since we are checking control reachability) and this is preserved by the predecessors computation (see [10]). Finally, we use the exactness of the \(\mathtt {pre_\mathtt {stmt}}\) computation, the soundness of the entailment relation and Theorem 3. We can use a similar reasoning for plain reachability of programs generating a finite number of phasers and bounded gapvalues for each phaser.
Theorem 5
Plain reachability is decidable for nonatomic phaser programs generating a finite number of phasers with, for each phaser, bounded phase gaps.
6 Limitations of Deciding Reachability
Assume a program \(\mathtt {prg}=\left( {\mathtt {B},\mathtt {V},\mathtt {T}}\right) \) and its initial configuration \(c_{init}\). We show a number of parameterized reachability problems to be undecidable. First, we address checking control reachability when restricting to configurations with at most K taskreferenced phasers. We call this Kcontrolreachability.
Definition 3
(Kcontrolreachability). Given a partial control configuration \(c\), we write \(\mathtt {reach}_{K}(\mathtt {prg},c)\), and say \(c\) is Kcontrolreachable, to mean there are \(n+1\) configurations \((c_i)_{i:0\le i\le n}\), each with at most K reachable phasers (i.e., phasers referenced by at least a task variable) s.t. \(c_{init}=c_0\) and \(c_i {\mathop {\longrightarrow }\limits ^{}} c_{i+1}\) for \(i:0 \le i < n  1\) with \(c_n\) equivalent to a configuration that includes \(c\).
Theorem 6
Kcontrolreachability is undecidable in general.
Proof sketch. Encode state reachability of an arbitrary Minsky machine with counters x and y using Kcontrolreachability of a suitable phaser program. The program (see [10]) has five tasks: \(\mathtt {main}\), \(\mathtt {xTask}\), \(\mathtt {yTask}\), \(\mathtt {child1}\) and \(\mathtt {child2}\). Machine states are captured with shared variables and counter values with phasers \(\mathtt {xPh}\) for counter x (resp. \(\mathtt {yPh}\) for counter y). Then, (1) spawn an instance of \(\mathtt {xTask}\) (resp. \(\mathtt {yTask}\)) and register it to \(\mathtt {xPh}\) (resp. \(\mathtt {yPh}\)) for increments, and (2) perform a wait on \(\mathtt {xPh}\) (resp. \(\mathtt {yPh}\)) to test for zero. Decrementing a counter, say x, involves asking an \(\mathtt {xTask}\), via shared variables, to exit (hence, to deregister from \(\mathtt {xPh}\)). However, more than one task might participate in the decrement operation. For this reason, each participating task builds a path from \(\mathtt {xPh}\) to \(\mathtt {child2}\) with two phasers. If more than one \(\mathtt {xTask}\) participates in the decrement, then the number of reachable phasers of an intermediary configuration will be at least five.
Theorem 7
Control reachability is undecidable if atomic statements are allowed even if only a finite number of phasers is generated.
Proof sketch. Encode state reachability of an arbitrary Minsky machine with counters x and y using a phaser program with atomic statements. The phaser program (see [10]) has three tasks: \(\mathtt {main}\), \(\mathtt {xTask}\) and \(\mathtt {yTask}\) and encodes machine states with shared variables. The idea is to associate a phaser \(\mathtt {xPh}\) to counter x (resp. \(\mathtt {yPh}\) to y) and to perform a signal followed by a wait on \(\mathtt {xPh}\) (resp. \(\mathtt {yPh}\)) to test for zero. Incrementing and decrementing is performed by asking spawned tasks to spawn a new instance or to deregister. Atomicnext statements are used to ensure exactly one task is spawned or deregistered.
Finally, even with finite numbers of tasks and phasers, but with arbitrary gapbounds, we can show [9] the following.
Theorem 8
Plain reachability is undecidable if generated gaps are not bounded even when restricting to nonatomic programs with finite numbers of phasers.
Findings summary: ctrl stands for control reachability and plain for plain reachability; atomic stands for allowing the \(\mathtt {v}.\mathtt {next()\{\mathtt {stmt}\}}\) atomic instruction and nonatomic for forbidding it (resulting in nonatomic programs). Decidable problems are marked with Open image in new window and undecidable ones with Open image in new window .
Arbitrary numbers of tasks  

Finite dimension  Kreachability  Arbitrary dimension  
Bounded gaps  ctrl atomic Open image in new window (Theorem 7)  plain nonatomic Open image in new window (Theorem 5)  ctrl nonatomic Open image in new window (Theorem 6)  ctrl nonatomic Open image in new window (Theorem 2) 
Arbitrary gaps  ctrl nonatomic Open image in new window (Theorem 4)  plain nonatomic Open image in new window (From [9]) 
7 Conclusion
We have studied parameterized plain (e.g., deadlocks) and control (e.g., assertions) reachability problems. We have proposed an exact verification procedure for nonatomic programs. We summarize our findings in Table 1. The procedure is guaranteed to terminate, even for programs that may generate arbitrary many tasks but finitely many phasers, when checking control reachability or when checking plain reachability with bounded gaps. These results were obtained using a nontrivial symbolic representation for which termination had required showing an \({{~}_\exists \!\!\preceq _\forall }\) preorder on multisets on gaps on natural numbers to be a \(\mathcal {WQO}\). We are working on a tool that implements the procedure to verify phaser programs that dynamically spawn tasks. We believe our general decidability results are useful to reason about synchronization constructs other than phasers. For instance, a traditional static barrier can be captured with one phaser and with bounded gaps (in fact one). Similarly, one phaser with one producer and arbitrary many consumers can capture futures where “gets” are modeled with waits. Also, testandset operations can model atomic instructions and may result in undecidability of reachability. This suggests more general applications of the work are to be investigated.
Footnotes
References
 1.Abdulla, P.A., Cerans, K., Jonsson, B., Tsay, Y.K.: General decidability theorems for infinitestate systems. In: Proceedings of the Eleventh Annual IEEE Symposium on Logic in Computer Science, LICS 1996, pp. 313–321. IEEE (1996)Google Scholar
 2.Anderson, P., Chase, B., Mercer, E.: JPF verification of Habanero Java programs. SIGSOFT Softw. Eng. Notes 39(1), 1–7 (2014). https://doi.org/10.1145/2557833.2560582. http://doi.acm.org/10.1145/2557833.2560582CrossRefGoogle Scholar
 3.de Boer, F.S., Clarke, D., Johnsen, E.B.: A complete guide to the future. In: De Nicola, R. (ed.) ESOP 2007. LNCS, vol. 4421, pp. 316–330. Springer, Heidelberg (2007). https://doi.org/10.1007/9783540713166_22CrossRefGoogle Scholar
 4.Cavé, V., Zhao, J., Shirako, J., Sarkar, V.: HabaneroJava: the new adventures of old x10. In: Proceedings of the 9th International Conference on Principles and Practice of Programming in Java, pp. 51–61. ACM (2011)Google Scholar
 5.Charles, P., et al.: X10: an objectoriented approach to nonuniform cluster computing. SIGPLAN Not. 40(10), 519–538 (2005). https://doi.org/10.1145/1103845.1094852. http://doi.acm.org/10.1145/1103845.1094852CrossRefGoogle Scholar
 6.Cogumbreiro, T., Hu, R., Martins, F., Yoshida, N.: Dynamic deadlock verification for general barrier synchronisation. In: 20th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming, PPoPP 2015, pp. 150–160. ACM, New York (2015). https://doi.org/10.1145/2688500.2688519. http://doi.acm.org/10.1145/2688500.2688519
 7.Cogumbreiro, T., Shirako, J., Sarkar, V.: Formalization of Habanero phasers using Coq. J. Log. Algebraic Methods Program. 90, 50–60 (2017). https://doi.org/10.1016/j.jlamp.2017.02.006. http://www.sciencedirect.com/science/article/pii/S2352220816300839MathSciNetCrossRefzbMATHGoogle Scholar
 8.Finkel, A., Schnoebelen, P.: Wellstructured transition systems everywhere!. Theoret. Comput. Sci. 256(1), 63–92 (2001). https://doi.org/10.1016/S03043975(00)00102X. http://www.sciencedirect.com/science/article/pii/S030439750000102XMathSciNetCrossRefzbMATHGoogle Scholar
 9.Ganjei, Z., Rezine, A., Eles, P., Peng, Z.: Safety verification of phaser programs. In: Proceedings of the 17th Conference on Formal Methods in ComputerAided Design, FMCAD 2017, pp. 68–75. FMCAD Inc., Austin (2017). http://dl.acm.org/citation.cfm?id=3168451.3168471
 10.Ganjei, Z., Rezine, A., Henrio, L., Eles, P., Peng, Z.: On reachability in parameterized phaser programs. arXiv:1811.07142 (2019)
 11.Havelund, K., Pressburger, T.: Model checking Java programs using Java pathfinder. Int. J. Softw. Tools Technol. Transfer (STTT) 2(4), 366–381 (2000)CrossRefGoogle Scholar
 12.Jancar, P.: A note on well quasiorderings for powersets. Inf. Process. Lett. 72(5–6), 155–160 (1999). https://doi.org/10.1016/S00200190(99)001490MathSciNetCrossRefzbMATHGoogle Scholar
 13.Marcone, A.: Fine analysis of the quasiorderings on the power set. Order 18(4), 339–347 (2001). https://doi.org/10.1023/A:1013952225669MathSciNetCrossRefzbMATHGoogle Scholar
 14.Minsky, M.L.: Computation: Finite and Infinite Machines. PrenticeHall Inc., Englewood Cliffs (1967)zbMATHGoogle Scholar
 15.Shirako, J., Peixotto, D.M., Sarkar, V., Scherer, W.N.: Phasers: a unified deadlockfree construct for collective and pointtopoint synchronization. In: 22nd Annual International Conference on Supercomputing, pp. 277–288. ACM (2008)Google Scholar
 16.Valiant, L.G.: A bridging model for parallel computation. CACM 33(8), 103 (1990)CrossRefGoogle Scholar
 17.WillebeekLeMair, M.H., Reeves, A.P.: Strategies for dynamic load balancing on highly parallel computers. IEEE Trans. Parallel Distrib. Syst. 4(9), 979–993 (1993)CrossRefGoogle Scholar
Copyright information
Open Access This chapter is licensed under the terms of the Creative Commons Attribution 4.0 International License (http://creativecommons.org/licenses/by/4.0/), which permits use, sharing, adaptation, distribution and reproduction in any medium or format, as long as you give appropriate credit to the original author(s) and the source, provide a link to the Creative Commons license and indicate if changes were made.
The images or other third party material in this chapter are included in the chapter's Creative Commons license, unless indicated otherwise in a credit line to the material. If material is not included in the chapter's Creative Commons license and your intended use is not permitted by statutory regulation or exceeds the permitted use, you will need to obtain permission directly from the copyright holder.