Next Article in Journal
The Impact of Environmental Risk on Business Failure: A Fuzzy-Set Qualitative Comparative Analysis Approach with Extreme Gradient Boosting Feature Selection
Previous Article in Journal
Optimal View Estimation Algorithm and Evaluation with Deviation Angle Analysis
 
 
Font Type:
Arial Georgia Verdana
Font Size:
Aa Aa Aa
Line Spacing:
Column Width:
Background:
Article

Proving Properties of Dekker’s Algorithm for Mutual Exclusion of N Processes

by
Libero Nigro
1,* and
Franco Cicirelli
2
1
DIMES, University of Calabria, 87036 Rende, Italy
2
CNR—National Research Council of Italy, Institute for High Performance Computing and Networking (ICAR), 87036 Rende, Italy
*
Author to whom correspondence should be addressed.
Algorithms 2025, 18(4), 226; https://doi.org/10.3390/a18040226
Submission received: 17 March 2025 / Revised: 9 April 2025 / Accepted: 11 April 2025 / Published: 13 April 2025
(This article belongs to the Section Algorithms for Multidisciplinary Applications)

Abstract

:
Dekker’s algorithm for mutual exclusion of two processes is the well-known first developed correct solution based only on software mechanisms. The algorithm served as the starting point for researchers to create subsequent safe solutions both for two and N > 2 processes. In recent years, Dekker proposed a generalization of his mutual exclusion algorithm for N > 2 processes (here referred to as Dekker-N). To the best of our knowledge, Dekker-N correctness was only proven by the author using informal arguments. This paper’s original contribution consists of formal modeling and verification of Dekker-N using an approach based on timed automata (TA) and the Uppaal model checker. The Dekker-N model is checked under atomic registers and also in cases where non-atomic registers are used. This paper first demonstrates that Dekker-N is correct and fair with atomic registers and effectively ensures bounded waiting for competing processes through a linear overtaking. Unfortunately, the algorithm becomes incorrect when non-atomic registers are used. The adopted formal approach, though, allowed us to prove that by making just one single common variable safe, Dekker-N turns out to be fully correct and fair with non-atomic registers as well. The paper presents the TA-based formal approach and goes on by presenting models of Dekker-N and by verifying all its mutual-exclusion properties.

1. Introduction

In his paper [1], T.J. (Dirk) Dekker reveals the way in which he invented the first mutual exclusion algorithm for two processes. The solution was prepared, in a few days, in response to a Dijkstra well-stated problem, of which the proponent and others were very doubtful of its practical solvability, about how to orchestrate two processes (machines), using only software means, in such a way that they never access some shared data simultaneously. The code fragment for accessing/modifying shared data is called the process of critical section. Dekker’s solution was formulated in 1960, and Dijkstra made it public in 1962 [2,3]. Dijkstra stressed the mutual exclusion solution had to fulfill the following additional properties: (a) absence of deadlocks among the competing processes; (b) absence of starvation which in turn means bounded waiting for a process willing to enter its critical section; (c) the solution should be independent from the relative speed of processes; and (d) read/write operations on shared variables should be indivisible.
The last requirement concerns the use of atomic registers. Nowadays [4,5,6,7], considering the use of multi-port memory, low-cost devices like cell phones [8] and similar hardware, where multiple read/write operations on the same register can occur simultaneously, it is felt that the operation of a mutual exclusion algorithm should be correct also in the presence of non-atomic registers. Another requirement often added to the above specifications is that (d), a process not interested in the critical section, should not forbid another process to enter its critical section.
Dekker’s algorithm for two processes represents the fundamental solution on which many subsequent proposals were developed. Two specific variants of the basic Dekker’s algorithm are described in [9,10]. A mutual exclusion algorithm for N 2 processes was designed by Dijkstra in [11], although the author himself recognized the possibility for a competing process to suffer unbounded waiting. Better solutions for N 2 processes were presented by Knuth [12], de Bruijn [13], and Eisenberg and McGuire [14], with a guarantee of bounded waiting, e.g., linear in the number N of waiting processes. Peterson in [15] proposed a more compact and elegant solution than the Dekker’s basic algorithm and a more general solution for N 2 processes.
The correctness of many proposed mutual exclusion algorithms was mainly based on atomic registers and informal mathematical arguments. However, intuitive reasoning, except for simple cases, cannot predict all the possible interleaving of actions that can occur in a nondeterministic concurrent/parallel system. This is testified, for example, by the different indications of the overtaking factor for a competing process in Peterson’s solution for N > 2 processes (see [16]). Formal modeling and verification approaches are now widely recognized as an essential tool for the assessment of the properties of a mutual exclusion solution. For example, the use of assertions and theorem provers was advocated in [5,10], whereas the use of model checkers with an exhaustive verification of the execution states of the processes of a concurrent system regulated by a mutual exclusion protocol was explored, e.g., in [6,7]. The work described in this paper relies on the use of Timed Automata (TA) [17] in the context of the Uppaal model checker [18,19,20] because process modeling and interactions are felt more intuitively when expressed graphically using TA instead of using, e.g., process algebra as in mCRL2 [6,21]. On the other hand, the Uppaal support of (a subset of) the Timed Computational Tree Logic (TCTL) [18] is simple yet powerful for capturing and checking properties (queries) of a TA-based mutual exclusion model. A unique feature of our TA-based approach is the possibility of investigating the interaction between timed and concurrent aspects in a model.
The adopted approach was successfully exploited to check exhaustively, under atomic and non-atomic registers, the properties of Dekker’s basic algorithm and some of its variants in [10,22], also when the solution for two processes is used as the arbitration unit in a general and standard tournament binary tree (TT) organization [16,23,24]. The approach was also successfully applied to prove properties of several algorithms for N 2 [25,26]. Three specific techniques are considered and compared in [7] for modeling non-atomic registers.
In a recent paper [1], Dekker proposed a generalization of his basic algorithm for two processes to cover N 2 processes in a fair way. The new algorithm will be referred to as Dekker-N. To the best of our knowledge, Dekker-N was only studied by the author using informal reasoning and atomic registers. An original contribution of this paper is a formal specification of Dekker-N by TA and its thorough model checking when atomic registers or non-atomic registers are used. This paper demonstrates that the Dekker-N is effectively a correct algorithm under atomic registers. It fulfills all the Dijkstra stated mutual exclusion requirements and guarantees fair behavior of processes through a linear overtaking factor. The paper also shows, though, that Dekker-N becomes incorrect when not-atomic registers are used. A specific contribution of this paper is to prove that through fencing. Specifically, making a single shared communication variable safe under read/write, Dekker-N becomes correct and fair also under non-atomic registers.
The paper is structured in two parts. In the first part (Section 2), the abstract structure of a mutual exclusion protocol and the modeling approach based on Uppaal are presented. The Dekker-2 algorithm is used as a working example. The modeling issues based on atomic and non-atomic registers are discussed. After that, the verification of all the properties of a mutual exclusion model using the Uppaal model checker with a few Timed Computational Tree Logic (TCTL) queries is detailed. In the second part (Section 3), Dekker’s algorithm for N 2 is thoroughly investigated. First, a Uppaal model is derived under the hypothesis of atomic registers, and its properties are verified. Then, a model for Dekker-N with non-atomic registers is presented and deeply model checked. It is shown that Dekker-N is correct for two processes with non-atomic registers, but it is incorrect for N > 2 . The effectiveness of the Uppaal-based approach is then demonstrated by showing how the general Dekker-N can be made correct for any number of processes and non-atomic registers. Finally, conclusions are drawn with an indication of future work.

2. Modeling a Mutual Exclusion Algorithm

The basic steps of a process involved in a mutual exclusion competition concerning the access to a common shared data resource R , is depicted in Algorithm 1. The process, with unique identifier i in [ 1 . . N ] , obeys a protocol that regulates the enter/exit of i to/from its local critical section. This is the code of process i that accesses/modifies R . The entry/exit parts of the protocol depend on some (hopefully few) shared communication variables. In an important case, a shared variable can be an exterior [23] or output [10] variable. Its write operation is the responsibility of only one process, but its value can be read, also concurrently, by all the remaining processes. In the more general case, a shared communication variable can be written/read by any process. In addition, multiple read/write accesses can occur simultaneously.
Algorithm 1. Abstract structure of a process involved in mutual exclusion.
shared communication variables
Process(i)
local variables
repeat
  NCS
  protocol-entry-part
  CS
  Protocol-exit-part
forever
In Algorithm 1, NCS denotes the non-critical section. A process in its NCS is not using the resource R ; it is also not interested in entering its critical section. In NCS, a process can remain an arbitrary time or an infinite time to model process termination. CS indicates the critical section of a process. The protocol is played in the entry/exit sections, where the shared communication variables are operated. In the entry part, a process is competing with peers for entering its critical section. If the process cannot proceed, it is assumed that it enters a busy waiting state, where it actively awaits for the shared communication variables to change, thus favoring the process. Depending on the mutual exclusion algorithm, some busy wait states could also be required in the exit part of the protocol.

2.1. Dekker’s Algorithm for Two Processes

As a concrete example, Algorithm 2 reproduces in pseudo-code Dekker’s algorithm for N = 2 processes [1,22], here referred to as Dekker-2. The algorithm is based on the following output shared communication variables:
bool flag[1..2] //all false initially
int[1..2] turn //immaterial is the initial value
There is one f l a g per process. The variable t u r n can be written by one process and read by the partner. A process communicates its willingness to enter its critical section through its Boolean f l a g . However, a competing process (engaged in the entry part) gets the grant to enter the critical section provided its turn arrived, that is, its id is assigned to t u r n . The process that achieved the permission to enter its critical section will be assigned to t u r n the identity of the partner process on exiting from the critical section. Process i , 1 i 2 , introduces a local constant j = 3 i to refer to the partner process. Busy waiting is expressed by the instruction: a w a i t   t u r n ! = j   ; . This is equivalent to the following cycle: w h i l e (   t u r n = = j   ) ; . In other terms, process i spin-locks until the variable t u r n contains i as its value.
Algorithm 2. Dekker-2 mutual exclusion algorithm.
Process(i):
Local constant: pid j = 3 − i; //j is partner process
repeat
    NCS;
    //protocol-entry-part
    flag[i] = true; //request to enter
    while( flag[j] ){ //in competition
        if( turn == j ){ //not my turn
            flag[i] = false; //reset my request
            await( turn != j ); //busy-waiting until the turn is mine
            flag[i] = true; //rise my request again
       }
    }
    //competition end: the partner has no interest in CS and the turn is mine
    CS;
    //protocol-exit-part
    turn = j; //turn assigned to partner
    flag[i] = false; //reset my request
forever
The correct operation of Dekker-2 can be checked intuitively using Algorithm 2 with the help of comments. However, for a complete assessment of Dekker-2, our approach is to, preliminarily, reduce Algorithm 2 into the Timed Automata (TA) formalism of Uppaal [18,19,20].

2.2. Reducing Dekker-2 on to Uppaal

Figure 1 (see also [22]) shows the Uppaal model [18,19,20] of P r o c e s s ( i ) when atomic registers are used. P r o c e s s is a parameterized template model (automaton) with one single parameter: c o n s t   p i d   i ; where p i d is a sub-range type for the integers from 1 to N:
const int N = 2; //number of processes
typedef int[1, N] pid;
At the system configuration time, two instances of Process will automatically be created and denoted as Process(1), and Process(2), which share global declarations for types and variables. The primitive types int, bool, and clock; arrays data structures of these types and channels; and an array of channels are available. Each Process instance owns its local declarations.
Shared communication variables are introduced in the global environment of the Uppaal model.
A process instance is a state machine composed of locations (circle in Figure 1) and edges (arrows in Figure 1) that connect locations. Each edge hosts a guarded command that is made up of three optional attributes: (1) a guard (Boolean expression, true by default if it is missing, green colored), (2) a channel synchronization (azure colored), and (3) an update part (blue colored) that is an ordered list of assignments to variables and clock resets. The guarded command is the atomic unit of concurrency in Uppaal models. Like in Petri nets [27], an enabled command can be taken, but it is not forced to do it. Different locations can be used to provide the time behavior to a model. Time is usually expressed using clock variables (see the clock x [ i ] in Figure 1). Clocks can be reset in an update section of a command. Then, they all grow at the same rate as the global time of a model. They measure the relative time elapsed from their last reset. In a normal location (see NCS in Figure 1), the automaton can stay an arbitrary, possibly infinite, time. The dwell time of a normal location can be constrained by the use of an invariant (see the invariant x [ i ] < = 1 attached to CS in Figure 1). An urgent location (flagged with an internal U) must be abandoned immediately, without any time passage. Another kind of location to be exited without time passage is the committed one [18], which is similar to an urgent location. However, committed locations have priority and are guaranteed to be abandoned before urgent locations.
Interactions between TA can be based on unicast or broadcast channels. A unicast channel can have a sender that executes the send signal operation (symbol ! ) and a receiver that can accept the synchronization signal (symbol ? ) sent by a sender. Unicast channels obey to rendezvous. Only when both sender and receiver are ready to communicates, a synchronization can be taken. The first process that arrives to the synchronization point has to wait for the partner to arrive. Broadcast channels have one sender and zero, one, or multiple receivers. The sender of a broadcast channel never waits for receivers to be ready. This way, such kind of channels are useful for one-way, asynchronous interactions. Figure 1 uses one single broadcast channel s y n c h that purposely has one sender and no receiver. Channels can be declared to be urgent (e.g., the s y n c h channel in Figure 1). In this case, an enabled synchronization must be taken without time passage. Among the actions that can be executed at the same time, the order of execution is nondeterministic. For example, it is nondeterministic when exiting from the location BW in Figure 1 with t u r n ! = j ( s y n c h being urgent), especially when this occurs simultaneously from an urgent location in the partner model.

2.3. Semantic Aspects of a Reduced Uppaal Model

A fundamental concern of a mutual exclusion algorithm like Dekker-2 reduced in Uppaal as shown in Figure 1 is the proper reproduction of nondeterminism and action interleaving of concurrent/parallel processes. From this point of view, process actions are purposely embedded in the guarded commands of the exiting edges of urgent locations. Therefore, the duration of atomic actions is zero time units.
Regardless of the memory model, no more than one shared communication variable can be accessed in a single command. This constraint does not apply to local variables. Multiple local variables, supposed to be held in CPU registers, can be operated together in the same command without problems.
A reduced model, such as Dekker-2 in Figure 1, is both concurrent and time sensitive. Time is allowed to pass in the NCS, CS, and busy waiting locations like BW. Exiting from NCS (which is also the initial location) is modelled by a spontaneous edge. This way a process can spend an arbitrary time in doing actions unrelated to the critical section. An infinite time in NCS models process termination. It has to be verified that a process in NCS should never forbid other processes from entering their critical section.
Busy waiting can be modelled by a normal location as BW in Figure 1 or by a looped urgent location like L. The former solution is preferable from the model checker point of view, because it reduces the nondeterminism (or partial order) degree of the nodes of the state graph [18,19]. When the awaited condition holds ( t u r n ! = j ), the BW is abandoned without time passage through the urgent synchronization s y n c h ! . More generally, exiting from a busy waiting location can be guarded by a t r y ( ) function that, optimistically, checks a complex condition based on multiple shared communication variables. In this case, the exiting is immediately followed by the evaluation, step-by-step and non-deterministically, of the compound condition. At any step that would contradict the exiting from the busy waiting location, the latter is immediately re-entered. The second solution with L urgent generates a zeno-cycle [22,28] in the model (logically present also in Algorithm 1), which is an infinite series of returns in L in zero time. However, in a concrete implementation of Algorithm 2, actions could not have a zero duration, and the zeno-cycle in the model has the effect of compromising model liveness. It is possible, virtually, that a process in L never will reach the CS. However, the analysis of the model in the time domain will confirm the full correctness of Dekker-2.
Timing is also used in the CS (critical section) location. First of all, the particular duration of the dwell time of a process in CS does not matter. During a critical section, concurrent competing processes can execute as many atomic and instantaneous actions of the mutual exclusion protocol as they want, or they can wait in a busy waiting location like BW. The adopted Uppaal approach purposely assumes a critical section consumes one time unit. This way, by using a clock variable per process (see the global array x [ ] in Figure 1, which has one clock for each process instance), which gets reset just before entering a CS, it becomes possible to assess the overtaking bound, that is the number of times a competing process is by-passed by competing partners, by checking the maximum value of the clock of a process when it finds itself in L (a location immediately preceding CS).
In the case of an unfair mutual exclusion algorithm, and the continual arrival of competing processes (e.g., the NCS duration is always 0 time units), the overtaking factor can become infinite. For an (almost) fair algorithm, even under the worst case arrivals of processes, the waiting time in L for any competing process is finite, and the overtaking factor bounded. As a consequence, the particular duration of NCS, which occurs in parallel with the critical sections, does not affect the overtaking bound. To check specifically the overtaking bound, an arbitrary target process ( t p ) can be defined in the model global declarations, and its clock is reset (through the r e s e t ( i ) function in Figure 1) when it exits from the NCS and starts competing.

2.4. TCTL Verification Queries of Dekker-2

A model like Dekker-2 of Figure 1 can preliminarily be studied (debugging) using the Uppaal symbolic simulator [20], which permits one to observe graphically the evolution of the process instances and the corresponding values of the global and local data declarations, when selected or randomly chosen transitions occur. The simulator can reveal some bad properties. For example, a deadlocked state can be reached, but one cannot conclude the model is correct. Model correctness can only be determined by exhaustive verification based on the preliminary creation of the (hopefully finite) model state graph [18,19]. The state graph is a timed transition system, where nodes represent the possible execution states of the model, and the arcs denote the possible timed or instantaneous transitions between states. Each node contains a data part and a time constraint part. The data part depends on the sizes and the values of the global and local data declarations. The time constraint part is a clock inequality system that describes all the possible time instants at which the state node can be reached. Proving properties of a model rests on the model checker that systematically traverses all the execution paths in the state graph, which is strongly influenced by the nondeterminism degree of nodes, that is, the number of possible exiting transitions at each node.
Property checking of the Dekker-2 model can be practically accomplished by issuing TCTL queries [18] as noted in the following. First of all, Dekker-2 makes no hypothesis on the relative speed of processes.
1. Mutual exclusion. At most one process at a time can enter its critical section. The following query can be used.
A[] (sum(i:pid)Process(i).CS) <= 1
This asks if it is always true (or invariantly) that in all the states of the state graph the number of processes simultaneously found in their CS location is less than or equal to 1.
Dekker-2 satisfies the mutual exclusion property.
2. Absence of deadlocks. One of the following TCTL queries can be issued.
A[] !deadlock
E<> deadlock
The first query asks the model checker to assess if invariantly that there is no deadlocked state in the state graph. The second query demands to verify if there exists at least one deadlocked state in the state graph. The absence of deadlocks is confirmed by the first query that gets satisfied, or, equivalently, by the second query that terminates unsatisfied.
Dekker-2 has no deadlock.
3. Absence of starvation. A competing process should always wait for a bounded time before achieving the permission to enter its critical section. The following suprema query [21] can be issued.
sup{ Process(tp).L } : x[tp]
This query asks to determine the maximum value of the clock x[tp] when the process tp is found in the L location (see Figure 1) that immediately precedes CS.
Dekker-2 guarantees 1 is the maximum waiting time for a competing process (overtaking bound), thus confirming the algorithm is fair.
4. Liveness 1. Every process eventually enters its critical section. For Dekker-2 the following queries can be used:
E<> Process(1).CS
E<> Process(2).CS
Both queries are satisfied, thus giving more arguments to the mutual exclusion property and to the absence of starvation.
5. Liveness 2. A process in its NCS should not forbid other processes to enter the critical section. The following query can be used.
E<> exists(i:pid)Process(i).NCS && exists(j:pid)Process(j).CS
This query asks if there exists at least one state where some process i is in its NCS whereas some other process j , j i , is in its CS.
Based on the responses to the above-described TCTL queries, Dekker-2 was found a correct mutual exclusion algorithm when atomic registers are used. All the experiments are carried out on a Win11 Pro desktop platform with Dell XPS 8940, Intel i7-10700 (eight physical + eight virtual cores), CPU@2.90 GHz, and 32 GB RAM.

2.5. Extending the Dekker-2 Model to Non-Atomic Registers

Due to the widespread diffusion of multi-port memory, low-cost devices like phone-cells and similar hardware equipment [8,29], nowadays, a mutual exclusion algorithm is required to behave correctly without guaranteeing that the read and write operations on the same register are always atomic or indivisible. The problem is then to check the correctness of an algorithm in the presence of non-atomic registers, too.
According to [4,6], a first scenario/pattern is the so called Single Writer Single Reader (SWSR), where a read operation can co-occur with a write operation on the same register. SWSR can affect the behavior of Dekker-2, because of the use of output-only shared communication variables, namely, that a variable is only written by one process and read by the partner. Reading a variable during a write gives rise to the flickering phenomenon [4,6,10]. Specifically, the reader achieves a nondeterministic value of the variable, belonging to the variable type domain.
The SWSR pattern generalizes to the Single Writer Multiple Reader (SWMR) case when, as in the Dekker-N algorithm studied later in this paper, shared registers are still output variables, and a single writer can be in access of a register simultaneously to multiple reader processes. In this case, each concurrent reader can receive a possibly different nondeterministic value chosen in the type domain of the register.
In the worst case Multiple Writer Multiple Reader (MWMR) scenario, simultaneous write operations on the same non-output variable determines the scrambled register value [4,6,10]. Reading a variable affected by scrambling returns a nondeterministic value in the type domain of the variable.
A mutual exclusion algorithm is said to be W-Safe [10] if it is immune to the possible flickering effects of the shared registers. The algorithm is called RW-Safe [10] when it is robust concerning both flickering and scrambling.
In a recent paper [7], all the above-introduced patterns of non-atomic registers are modelled in Uppaal using three techniques: the Simple, the Loop, and the Decoration techniques. In the Simple case, the writer first assigns the variable a nondeterministic value; then, this is followed by the assignment of the effective value. This way a read can effectively return the previous value, the flickered value, or the new value of the variable. In the Loop technique [6,10], the writer first executes a loop, which eventually terminates. At each iteration, a nondeterministic value is temporarily assigned to the variable. At the loop termination, the effective value is assigned to the variable. A reader can then achieve the previous value, any flickered value, or the final assigned value to the variable. The Decoration technique decorates the model by adding Boolean variables w x , one for each shared communication variable x , which indicate whether x is under writing or not. The writer first sets the decoration variable to true, then it assigns the effective value to the variable. In the next action, the decoration value is reset to false. Depending on the values of w x variables, a reader can access the last assigned value to the variable or a nondeterministic (flickered or scrambled) value.
The three techniques are equivalent in practical use, although they have different repercussions on the state graph and the model checker. The Simple technique was used, e.g., in [16,22]. The Decoration technique is more efficient. The decoration variables remain almost always at their default false value, except, temporarily, when a write operation is accomplished. In the rest of this paper, Decoration will be used for studying models under non-atomic registers.
Figure 2 shows a modification of the Dekker-2 model according to the Decoration technique and the SWSR pattern of use of non-atomic registers. Three global variables were added, namely, b o o l   w f [ 1,2 ] and b o o l   w t , which are associated with the f l a g [ 1,2 ] and the t u r n variables, respectively. When checking a shared communication variable, if it is under writing, a nondeterministic value is returned. Otherwise, the true value of the variable is used. For brevity, the int values of Boolean, 0 for false and 1 for true, are used. Decorated edges like the one from L to CS exploit the nondeterministic field (yellow colored in Figure 2) of a guarded command, which assigns to variable v , strictly local to the command, a nondeterministic value selected in the type of the shared variable, e.g., the b i t interval [0, 1] for a f l a g variable. The meaning of the command “ v : b i t   ! w f [ j ] ? ! f l a g [ j ] : ! v ” is the following. In the case the variable f l a g [ j ] is not under writing ( w f [ j ] is false), the last value of f l a g [ j ] is checked for false. Otherwise, ( w f [ j ] is true), the non-deterministic value v is used for the test.
The Dekker-2 model of Figure 2 was thoroughly verified using the Uppaal model checker. It proved to be W-Safe and fully correct from all the mutual exclusion queries discussed in Section 2.4. This version too is fair and guarantees 1 is the overtaking bound.
It is worth noting that a decorated model like that in Figure 2 is more expensive for model checking than the version for atomic registers because of the augmented degree of the nondeterminism in the model.

3. Dekker’s Mutual Exclusion for Any Number of Processes

In [1], Dekker proposed a fair mutual exclusion algorithm for N 2 processes. Fairness is based on a linked list of precedence. After completing its critical section, the process places itself at the bottom of the list, and lower ranking competing processes are moved one place up in the list. Since the list is consulted concurrently by processes, movements in the list are tricky. In particular, moves are carried out in such a way that all processes in the list continue to be visible to all the other processes. The process is placed at the bottom and temporarily occurs twice in the list. Due to this operation, the bottom is not used as the list end. The penultimate element is effectively the last element, and the bottom is the next element to it.
The algorithm uses the following shared communication variables with the shown initialization:
int top = N, penult = 2;
int[0, 2] c[1..N] //all 0 initially
int[0, N] next[1..N]; //for all j in [1..N], next[j] = j − 1
The c [ ] array is analogous to the f l a g [ ] array of Dekker-2. However, instead of the two Boolean values 0 (false) and 1 (true), three values are now used to express the status of a process i . When c[ i ]=0, the process is not interested in the critical section. The value c[ i ] = 1 denotes the process that starts competing (ready status). Finally, when c[ i ] = 2, the process is up to enter its critical section.
All the communication variables are output or behave as output variables. Each c [ . ] variable is associated with a distinct process that has the responsibility of writing its status information in it. The process can change the t o p , p e n u l t , and n e x t variables at its abandoning of the critical section. All the variables, though, can be checked concurrently by all the processes.
Algorithm 3 reproduces in pseudo-code Dekker’s algorithm for N 2 processes (Dekker-N). A competing process i acquires permission to enter its critical section when predecessor processes, from the top of the n e x t [ ] list up to the one immediately before i , are found in the status of being not interested in the critical section ( c [ p r e ] = = 0 ). Such a situation must be assessed twice: with c [ i ] = 1 and then with c [ i ] = 2 . After that, the process i   must wait until posterior processes (from n e x t [ i ] to penultimate) are at most in the ready status ( c [ p o s t ] < 2 ).
On exiting from its critical section, the process   i is placed at the bottom of the list, provided   i is not already the bottom. If required, process i becomes the next b o t t o m , and the previous b o t t o m is established as the penultimate of the list. After that, if the process i was the t o p , the t o p variable is updated to the next element of i . Otherwise, the previous i will have the next i as the next element. Finally, process i sets its status to not interested in the critical section ( c [ i ] = 0 ), and the NCS is re-entered.
Dekker-N will be first reduced to Uppaal under atomic registers, and its properties, including fairness, will be investigated. Then, the algorithm will be adapted to work with non-atomic registers, and its correctness will be deeply verified.
Algorithm 3. Pseudo-code of Dekker-N.
Process(i):
local variables: int pre, previous, post, pos, subtop, bottom;
repeat
    NCS;
    w0: c[i] = 1;
    w1: pre = top;
    in1: if( pre !=i ){
            if( c[pre] > 0 ) goto w1;
            pre = next[pre]; goto in1
        } // all c[pre] == 0
        c[i] = 2; //same loop with c[i] = 2
        pre = top;
    in2: if( pre !=i ){            
            if( c[pre] > 0 ) goto w0;
            previous := pre; pre := next[pre]; goto in2;
        } // c[i] = 2, all c[pre] = 0
    //c[i] = 2, preceding processes not interested
    //now wait until posterior processes are ready
    if( i == top || previous != penult ){
        w2: post = i;
        in3: pos = post; post = next[post];
            if( c[post] == 2 ) then goto w2;
            if( pos != penult ) goto in3;
    } //c[i] = 2, all c[pre] = 0, all c[post] < 2
    CS;
    //place process i at bottom
    bottom = next[penult];
    if( i != bottom ){
        next[bottom] = i; penult = bottom; subtop = next[i];
        if( i == top ) top = subtop;
        else next[previous] = subtop;
    }
    c[i] = 0;
forever

3.1. Transforming Dekker-N into Uppaal by Using Atomic Registers

The following are the basic global declarations of the Dekker-N Uppaal model:
const int N = 4; //example
typedef int[1, N] pid;
typedef int[0, 2] value;
//shared communication variables
pid top = N, penult = 2;
value c[pid]; //all zero by default
pid next[pid]; //all 1 by default
urgent broadcast chan synch;
clock x[pid];
As one can see, the n e x t [ ] list was changed, with respect to [1], to have only process indexes in [1, N] as values. In fact, the n e x t [ 1 ] value is immaterial and can be assigned itself as the next value. This provision reduces the number of possible values of n e x t [ ] , which in turn tends to improve the burden of the model checker.
The Uppaal model is organized in two timed automata: B o o t s t r a p p e r and P r o c e s s .
B o o t s t r a p p e r (see Figure 3) is a parameterless automaton that has the responsibility of model initialization. Its initial location is purposely declared as committed. This way its exiting edge will certainly be taken before any other edge in the P r o c e s s models. Recall that P r o c e s s locations (see, e.g., Figure 1) are normal or urgent locations. The function initialize() is detailed in Figure 4. The B o o t s t r a p p e r , after the edge with initialize(), enters an anonymous normal location from which it will take no part in the subsequent model evolution.
Figure 5 shows the P r o c e s s automaton equipped with the sole parameter: c o n s t   p i d   i . Atomic registers are automatically ensured by the atomic actions of Uppaal TA-based modeling language. Atomic actions are executed one at a time and in any order. Consequently, considering that only one communication variable can be accessed/modified in a guarded command, only one write or read operation can occur at any time.
A notable point in Figure 5 is the introduction of the busy waiting BW location that precedes the first loop on the predecessor processes when c [ i ] = = 1 . This provision was made to reduce the partial order degree in the state graph that inevitably would accompany the continuous checking, in the model, of communication variables by chained urgent locations. From BW, the P r o c e s s automaton tentatively exits when there is a chance all the predecessor processes of   i   are in the not interested status: c [ p r e ] = = 0 . Toward this, the try() function of Figure 6 was prepared, which optimistically checks the exiting condition from BW. Optimism is related to the fact that multiple shared communication variables are simultaneously checked. However, model concurrency and nondeterminism are correctly ensured given that P r o c e s s   i , after abandoning the BW location through the synchronization on the urgent and broadcast s y n c h channel, evaluates one-at-a-time the single variables of the try() loop, and it immediately re-enters BW if any predecessor is found in the ready status ( c [ p r e ] > 0 ).
In Figure 5, it is worth noting the provision to reset as soon as possible local variables after their use. This action can improve model checking by ensuring variables return to their default status.
The system configuration of the Dekker-N model is achieved by the following declaration:
system Bootstrapper, Process;
which automatically creates one instance of the B o o t s t r a p p e r and N instances of the P r o c e s s automaton indexed by the integers in [1, N].

3.2. Model Checking the Dekker-N Model with Atomic Registers

The model in Figure 5 was exhaustively verified by separately using NCS as a normal location (with arbitrary stay time) and as an urgent location (zero stay time). The use of NCS as normal location enables us to check that the algorithm correctly behaves when processes possibly terminate in NCS or re-enter the system after an arbitrary time. The use of NCS urgent ensures the worst case arrival of ready processes. Making NCS urgent favors the model checker because it eliminates a source of time behavior.
Figure 7 reports a snapshot of the Uppaal verifier when NCS is normal and N is set to three processes. As one can see from the green circle generated in response to each query, the model was found correct from all the mutual exclusion queries. In addition, the overtaking bound ( o v ) emerged to be o v = 2 .
The model of Figure 5 was verified for N ranging in [2..4]. The same green answers as in Figure 7 were found for each value of N. Table 1 collects the observed overtaking bound o v (see last query in Figure 7), the elapsed time (ET) in sec, and the peak of memory usage (M) of the model checker. For N = 5 , the model with NCS normal suffers from state explosions in the state graph, and the verifier was stopped as soon as the virtual memory exceeded the available RAM (32 GB).
The Dekker-N model becomes more scalable when NCS is made urgent. The model was verified for N in [2..5]. For N = 6, the model is still affected by state explosions. All the queries, as shown in Figure 7, achieved the same responses as in Figure 7. Table 2 reports the overtaking bound results in the new scenario.
From Table 1 and Table 2, it emerges that Dekker-N under atomic registers is fair with an overtaking bound o v = N 1 , that almost coincides with the N indication of informal analysis in [1].

3.3. The Dekker-N Model with Non-Atomic Registers

Figure 8 shows Dekker-N model decorated for using non-atomic registers. The following global declarations were added:
//decoration variables—all false initially
bool wt, //true when writing to top
      wp; //true when writing to penult
bool wc[pid], //true when writing to c[.],
wn[pid]; //true when writing to next[.]
The existence of only output shared communication variables implies that the model in Figure 8 takes care only of variable flickering due to the SWMR pattern. The model in Figure 8 was preliminarily debugged using the symbolic simulator of Uppaal. It emerged that due to flickering, the contents of the n e x t list can temporarily become cyclic; thus, the try() function can enter an infinite loop during the evaluation of predecessor processes. As a consequence, the try() function was modified according to Figure 9. A v i s i t e d [ ] array was introduced, and a possible loop in the n e x t list was discovered. Under these circumstances, try() terminates by returning false. After that, the model was verified with the model checker by first assuming NCS is a normal location. For N = 2 , the model of Figure 8 was found to be W-Safe and fully correct. The result complies with the author’s expectation stated in [1] that the mutual exclusion solution, when reduced to operate with two processes, would be equivalent to Dekker’s algorithm for two processes (see Section 2.2 and Section 2.5). The experimental results confirm that the property holds both with atomic and non-atomic registers.
The next verification step was to check the model in Figure 8 for N > 2 . Unfortunately, already for N = 3 , the decorated model loses the fundamental mutual exclusion property because more than one process can enter simultaneously the critical section (see Figure 10). In addition, the query that checks for the overtaking bound becomes inconclusive.
In the light of the observed results, the Dekker-N model was found to be incorrect for N > 2 when non-atomic registers are used. The model was then studied by making some changes (see Figure 11). In particular, considering the role played by the t o p common variable, the provision of fencing t o p was added, thus ensuring it behaves as a regular atomic variable. Reading t o p will always return either the previous or the newly assigned value, but never a flickered value. Fencing is supposed to be supported by some low-level hardware mechanism that controls the access to the t o p variable and enforces that read/write operations on t o p are indivisible. In Figure 11, the w t variable was eliminated, and any read to t o p returns the last value stored in the variable. With these changes, Dekker-N becomes correct also with non-atomic registers. However, the adapted model suffers from state explosions when N = 4 .
The verification process was then continued by turning NCS into an urgent location. Correct behavior, that is, satisfaction of all the mutual exclusion properties, including fairness, was then observed until N = 5 .
The verification work was finally directed at further checking the behavior of the Dekker-N model with non-atomic registers when processes that exit the critical section immediately re-enter the system and are newly ready. In other terms, the NCS location was always kept urgent. An unexpected remarkable result emerged that the model in Figure 8, without fencing the t o p variable and with the try() function used with atomic registers (see Figure 6), turns out to be W-Safe and fully correct and has the same overtaking bound o v = N 1 of the atomic registers scenario. The model was verified up to N = 5 . This interesting result confirmed the usefulness and flexibility of the adopted Uppaal approach, which can reveal subtle, not intuitive properties, when timing and concurrency are allowed to be studied in combination.
The positive effects of fencing the top common variable were also retrieved when the Simple and the Loop techniques for handling the non-atomic registers were used. The Loop technique was confirmed to be the most expensive for the model checking.

4. Conclusions

Dekker’s mutual exclusion algorithm for two processes (Dekker-2) [1,2,3] is the first well-known software-based solution that has triggered the development of subsequent algorithms for N 2 processes. In [22], Dekker-2 and some of its variants were formally modelled and verified by model checking under atomic and non-atomic registers [6,7], as well as in the context of a standard tournament tree-based organization [24,26]. The adopted approach is based on timed automata [17] and the Uppaal toolbox [18,19,20]. It is intuitive because it supports the graphical specification of processes as automata in a high-level modeling language. It is powerful for the exhaustive verification, assisted by Timed Computational Tree Logic (TCTL) queries [18], of concurrent and timed systems. In [1], Dekker proposed a new and fair mutual exclusion algorithm for any number of processes (Dekker-N). The author analyzed the algorithm using informal reasoning. To the best of our knowledge, no previous formal modeling and verification of the algorithm has been reported in the literature. This paper applied our Uppaal approach for a thorough analysis of Dekker-N. It emerged that Dekker-N is a fully correct and fair mutual exclusion algorithm when atomic registers are used. A competing process can suffer from an overtaking bound of N 1 . Dekker-N was then adapted to work with non-atomic registers where it was confirmed to be correct only when N = 2 . For N > 2 , Dekker-N loses its fundamental mutual exclusion property. However, as an original contribution of this paper, the adopted approach was capable of showing that by fencing, with the help of some physical mechanism, just one single common variable and thus forcing it to have atomic read/write operations, Dekker-N turns out to be correct also with non-atomic registers.
A unique feature of our Uppaal approach is its capability of enabling a careful analysis of a general model as Dekker-N when timing is used in combination with concurrency and nondeterminism.
The continuation of the research will be geared to the following points. First, continue experimenting with the approach and non-atomic registers in other mutual exclusion algorithms for any number of processes, e.g., in the context of the tournament tree organization [16,22,23,24]. Second, compare Dekker-N with similar algorithms also based on a binary tree tournament approach. Third, implement the Dekker-N model and similar algorithms using the Theatre actor system [16,30] to study the model with non-atomic registers and higher values of N , using stochastic behavior and simulation.

Author Contributions

Conceptualization, L.N. and F.C; methodology, L.N. and F.C.; validation, L.N. and F.C.; formal analysis, L.N. and F.C.; writing-original draft preparation, L.N.; writing-review and editing, L.N. and F.C. All authors have read and agreed to the published version of the manuscript.

Funding

This research received no external funding.

Data Availability Statement

All data are contained in the paper.

Conflicts of Interest

The authors declare no conflict of interest.

References

  1. Dekker, T.J. History of Dekker’s algorithm for mutual exclusion. In Tales of Electrologica: Computers, Software and People; Alberts, G., Groote, J.F., Eds.; Springer Nature: Cham, Switzerland, 2022; Chapter 6; pp. 111–120. [Google Scholar]
  2. Dijkstra, E.W. About the Sequentiality of Process Descriptions; University of Texas: Austin, TX, USA, 1962; EWD35 translated. [Google Scholar]
  3. Dijkstra, E.W. Co-operating sequential processes. In Programming Languages: NATO Advanced Study Institute: Lectures Given at a Three Weeks Summer School Held in Villard-le-Lans; Genuys, F., Ed.; Academic Press Inc.: Cambridge, MA, USA, 1968; pp. 43–112. [Google Scholar]
  4. Lamport, L. On Interprocess Communication: Part I and II. Distributed Computing; Springer: Berlin/Heidelberg, Germany, 1986; pp. 77–101. [Google Scholar]
  5. Hesselink, W.H. Verifying a simplification of mutual exclusion by Lycklama–Hadzilacos. Acta Inform. 2013, 50, 199–228. [Google Scholar] [CrossRef]
  6. Spronck, M.; Luttik, B. Process-Algebraic Models of Multi-Writer Multi-Reader Non-Atomic Registers. In Proceedings of the 34th International Conference on Concurrency Theory (CONCUR) 2023, Antwerp, Belgium, 18–23 September 2023; pp. 5.1–5.17. [Google Scholar]
  7. Nigro, L. Verifying mutual exclusion algorithms with non-atomic registers. Algorithms 2024, 17, 536. [Google Scholar] [CrossRef]
  8. Frenzel, L.E. Dual-Port SRAM Accelerates Smart-Phone Development. Electronic Design 2004. Available online: https://www.electronicdesign.com/technologies/industrial/boards/article/21774041/dual-port-sram-accelerates-smart-phonedevelopment (accessed on 16 March 2025).
  9. Doran, R.W.; Thomas, L.K. Variants of the software solution to mutual exclusion. Inf. Process. Lett. 1980, 10, 206–208. [Google Scholar] [CrossRef]
  10. Buhr, P.A.; Dice, D.; Hesselink, W.H. Dekker’s mutual exclusion algorithm made RW-safe. Concurr. Comput. Pract. Exp. 2016, 28, 144–165. [Google Scholar] [CrossRef]
  11. Dijkstra, E.W. Solution of a problem in concurrent programming control. Commun. ACM 1965, 8, 569. [Google Scholar] [CrossRef]
  12. Knuth, D.E. Additional comments on a problem in concurrent programming control. Commun. ACM 1966, 9, 321–322. [Google Scholar] [CrossRef]
  13. de Bruijn, N.G. Additional comments on a problem in concurrent programming control. Commun. ACM 1967, 10, 137–138. [Google Scholar] [CrossRef]
  14. Eisenberg, M.A.; McGuire, M.R. Further comments on Dijkstra’s concurrent programming control problem. Commun. ACM 1972, 15, 999. [Google Scholar] [CrossRef]
  15. Peterson, G.L. Myths about the mutual exclusion problem. Inf. Process. Lett. 1981, 12, 115–116. [Google Scholar] [CrossRef]
  16. Nigro, L.; Cicirelli, F. Property assessment of Peterson’s mutual exclusion algorithms. Applied Computing and Intelligence 2024, 4, 66–92. [Google Scholar] [CrossRef]
  17. Alur, R.; Dill, D.L. A theory of timed automata. Theor. Comput. Sci. 1994, 126, 183–235. [Google Scholar] [CrossRef]
  18. Behrmann, G.; David, A.; Larsen, K.G. A tutorial on UPPAAL. In Formal Methods for the Design of Real-Time Systems; Bernardo, M., Corradini, F., Eds.; Springer: Berlin/Heidelberg, Germany, 2004; LNCS 3185; pp. 200–236. [Google Scholar]
  19. Zhou, W.; Zhao, Y.; Zhang, Y.; Wang, Y.; Yin, M. A comprehensive survey of UPPAAL-assisted formal modeling and verification. Softw. Pract. Exp. 2024, 55, 272–297. [Google Scholar] [CrossRef]
  20. Uppaal on-Line. Available online: https://uppaal.org (accessed on 16 March 2025).
  21. Groote, J.F.; Keiren, J.J.; Luttik, B.; de Vink, E.P.; Willemse, T.A. Modelling and analysing software in mCRL2. In Formal Aspects of Component Software, Proceedings of the 16th International Conference, FACS 2019, Amsterdam, The Netherlands, 23–25 October 2019; Proceedings 16; Springer International Publishing: Berlin/Heidelberg, Germany, 2020; pp. 25–48. [Google Scholar]
  22. Nigro, L.; Cicirelli, F.; Pupo, F. Modeling and Analysis of Dekker-based Mutual Exclusion Algorithms. Computers 2024, 13, 133. [Google Scholar] [CrossRef]
  23. Kessels, D.E. Arbitration without common modifiable variables. Acta Inform. 1982, 17, 135–141. [Google Scholar] [CrossRef]
  24. Hesselink, W.H. Tournaments for mutual exclusion: Verification and concurrent complexity. Form. Asp. Comput. 2017, 29, 833–852. [Google Scholar] [CrossRef]
  25. Nigro, L.; Cicirelli, F. Correctness verification of mutual exclusion algorithms by model checking. Modelling 2024, 5, 694–719. [Google Scholar] [CrossRef]
  26. Nigro, L. Formal Modeling and Verification of Lycklama and Hadzilacos’s Mutual Exclusion Algorithm. Mathematics 2024, 12, 2443. [Google Scholar] [CrossRef]
  27. Murata, T. Petri Nets: Properties, analysis and applications. Proc. IEEE 1989, 77, 541–580. [Google Scholar] [CrossRef]
  28. Bowman, H.; Gomez, R.; Su, L. A tool for the syntactic detection of zeno-timelocks in Timed Automata. Electron. Notes Theor. Comput. Sci. 2005, 139, 25–47. [Google Scholar] [CrossRef]
  29. Wang, Z.; Zuo, Q.; Li, J. An intelligent multi-port memory. In Proceedings of the 2008 International Symposium on Intelligent Information Technology Application Workshops, Shanghai, China, 21–22 December 2008; pp. 251–254. [Google Scholar]
  30. Nigro, L. Parallel Theatre: An actor framework in Java for high performance computing. Simul. Model. Pract. Theory 2021, 106, 102189. [Google Scholar] [CrossRef]
Figure 1. Uppaal model for Dekker-2 [22].
Figure 1. Uppaal model for Dekker-2 [22].
Algorithms 18 00226 g001
Figure 2. The Dekker-2 model using non-atomic registers and the Decoration technique.
Figure 2. The Dekker-2 model using non-atomic registers and the Decoration technique.
Algorithms 18 00226 g002
Figure 3. The Bootstrapper automaton.
Figure 3. The Bootstrapper automaton.
Algorithms 18 00226 g003
Figure 4. The initialize() function.
Figure 4. The initialize() function.
Algorithms 18 00226 g004
Figure 5. The Process automaton of Dekker-N based on atomic registers.
Figure 5. The Process automaton of Dekker-N based on atomic registers.
Algorithms 18 00226 g005
Figure 6. The try() function of the model in Figure 5.
Figure 6. The try() function of the model in Figure 5.
Algorithms 18 00226 g006
Figure 7. Snapshot of the Uppaal model checker when Dekker-N of Figure 5 is verified with N = 3.
Figure 7. Snapshot of the Uppaal model checker when Dekker-N of Figure 5 is verified with N = 3.
Algorithms 18 00226 g007
Figure 8. The Dekker-N model with non-atomic registers.
Figure 8. The Dekker-N model with non-atomic registers.
Algorithms 18 00226 g008
Figure 9. The try() function adapted for working with flickering.
Figure 9. The try() function adapted for working with flickering.
Algorithms 18 00226 g009
Figure 10. Verification snapshot of the Dekker-N model with non-atomic registers for N = 3.
Figure 10. Verification snapshot of the Dekker-N model with non-atomic registers for N = 3.
Algorithms 18 00226 g010
Figure 11. The Dekker-N model with non-atomic registers and top fencing.
Figure 11. The Dekker-N model with non-atomic registers and top fencing.
Algorithms 18 00226 g011
Table 1. Observed overtaking bound for the model in Figure 5.
Table 1. Observed overtaking bound for the model in Figure 5.
NovET (Sec)M
21019 MB
320.327 MB
431472.8 GB
Table 2. Observed overtaking bound for the model in Figure 5 with the NCS urgent location.
Table 2. Observed overtaking bound for the model in Figure 5 with the NCS urgent location.
NovET (Sec)M
21019 MB
32020 MB
431.4552 MB
541081.6 GB
Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content.

Share and Cite

MDPI and ACS Style

Nigro, L.; Cicirelli, F. Proving Properties of Dekker’s Algorithm for Mutual Exclusion of N Processes. Algorithms 2025, 18, 226. https://doi.org/10.3390/a18040226

AMA Style

Nigro L, Cicirelli F. Proving Properties of Dekker’s Algorithm for Mutual Exclusion of N Processes. Algorithms. 2025; 18(4):226. https://doi.org/10.3390/a18040226

Chicago/Turabian Style

Nigro, Libero, and Franco Cicirelli. 2025. "Proving Properties of Dekker’s Algorithm for Mutual Exclusion of N Processes" Algorithms 18, no. 4: 226. https://doi.org/10.3390/a18040226

APA Style

Nigro, L., & Cicirelli, F. (2025). Proving Properties of Dekker’s Algorithm for Mutual Exclusion of N Processes. Algorithms, 18(4), 226. https://doi.org/10.3390/a18040226

Note that from the first issue of 2016, this journal uses article numbers instead of page numbers. See further details here.

Article Metrics

Back to TopTop