Correctness Verification of Mutual Exclusion Algorithms by Model Checking

: Mutual exclusion algorithms are at the heart of concurrent/parallel and distributed systems. It is well known that such algorithms are very difficult to analyze, and in the literature, different conjectures about starvation freedom and the number of by-passes (also called the overtaking factor) exist. The overtaking factor affects the (hopefully) bounded waiting time that a process competing for entering the critical section has to suffer before accessing the shared resource. This paper proposes a novel modeling approach based on Timed Automata and the Uppaal toolset, which proves effective for studying all the properties of a mutual exclusion algorithm for N ≥ 2 processes, by exhaustive model checking. Although the approach, as already confirmed by similar experiments reported in the literature, is not scalable due to state explosion problems and can be practically applied until N ≤ 5, it is of great value for revealing the true properties of analyzed algorithms. For dimensions N > 5, the Statistical Model Checker of Uppaal can be used, which, although based on simulations, can confirm properties by estimations and probabilities. This paper describes the proposed modeling and verification method and applies it to several mutual exclusion algorithms, thus retrieving known properties but also showing new results about properties often studied by informal reasoning.


Introduction
Mutual exclusion (ME) [1][2][3][4][5] is a fundamental problem in the concurrent/parallel, distributed, embedded real-time programming domains [6][7][8][9][10].In its basic form, it can be stated as follows.We have a software system with N ≥ 2 processes which compete for the use of a shared resource R. For predictability and deterministic evolution of the system behavior, only one process should be allowed at a time to use the resource.The code executed by the process when it is using the resource constitutes its atomic critical section.Other properties of a ME algorithm include the following: (a) progress, that is, a process competing for accessing the resource eventually obtains the permission to use the resource; (b) an absence of deadlocks; and (c) no process should experience starvation, in other terms, a competing process should not suffer from an unbounded waiting or an unbounded number of by-passes/overtakings from other competing processes.
ME solutions typically can be provided by a high-level or low-level abstraction context.High-level ME mechanisms can directly be provided by a programming language (e.g., Java) and accompanying library and include semaphores, locks or monitor constructs [11].Such solutions, though, ultimately depend on the mechanisms implemented in the underlying Operating System.Primitive ME solutions are required to give support to high-level mechanisms.Primitive ME solutions can be based on specialized hardware mechanisms, e.g., machine instructions like test-and-set, or they can be designed as pure software algorithms which depend on (hopefully) few shared variables and a purposely designed, often ingenious, protocol which establishes the Entry and Exit code sections which processes have to obey, respectively, for competing and entering the resource and for releasing the resource at the end of the critical section.
This paper focuses on pure software ME primitive algorithms, whose properties can be very difficult to assess.In the literature, such algorithms are normally studied by informal reasoning [12] typical of ordinary mathematics.More structured tools are represented by assertional methods based on global invariants together with a theorem prover like PVS as a proof assistant [13][14][15][16][17][18].The correctness argument of an assertional method proceeds by first transforming an ME algorithm into a transition system.Assertions are about the state and the next state relation.It is worth noting, though, that the use of theorem provers not only can require a not easy formal representation of the algorithms and their data variables, but they are also unable to reason on the time dimension of an ME solution.
This paper proposes an original modeling and verification approach based on the Timed Automata [19] and the Uppaal toolbox [20] which enable an automated assessment of the properties of an ME algorithm through exhaustive model checking [21].Although the approach necessarily is not scalable due to the state explosion problem which inevitably intervenes when considering a number of processes N > 5, it is of great practical value for detecting the true properties of ME solutions, which can go beyond some indications formulated in the literature, particularly about the number of by-passes a process can be affected by when competing together with its peers.
This paper significantly extends the preliminary work and results of the authors as reported in two conference papers [22,23].Differences from the previous authors' work are as follows.
• The modeling and verification method is completely re-designed and its semantics and transformation on to the Timed Automata of Uppaal are clarified.• The novel approach is applied to several ME algorithms proposed in the literature, thus retrieving known results and properties but also, sometimes, discovering new features about specific ME solutions.

•
Both exhaustive model checking (MC) and statistical model checking (SMC) [24,25] can be exploited for property checking.Although SMC is based on simulations, the properties of an ME algorithm for N > 5 processes can be extrapolated by estimations and probability, thus furnishing further arguments to the indications emerged from the exhaustive verification work accomplished until N = 5 processes.
This paper is structured as follows.Section 2 presents an overview of the basic concepts of Timed Automata and Uppaal modeling.Section 3 describes the proposed modeling and verification method for mutual exclusion algorithms and its semantic transformation on to Uppaal.Section 4 demonstrates via several examples the application and the experimental verification work carried out by using the proposed approach on representative mutual exclusion algorithms.Both the atomic and the weak memory models are considered.The interplay between the exhaustive model checking and the statistical model checking activities is clarified.Finally, Section 5 concludes this paper and indicates some on-going and future work.

An Overview of Uppaal Timed Automata Modeling
Uppaal [20] is a popular modeling and verification toolbox for concurrent/distributed real-time systems.The power and flexibility of Uppaal derive from the adoption of a high-level version of Timed Automata (TA) [19] which are formal concurrent entities with an easy-to-understand graphical formulation.

Specification Aspects
A model consists of a network of interacting TA.Interactions are based on unicast and broadcast channels and on global data of primitive types like integers and bools, plus structs and arrays.Unicast channels ensure two-way synchronizations in couples of TA (also called template processes or parameterizable processes).The sender process of a unicast channel transmits (!) a signal toward a single receiver.The sender, though, becomes blocked until the receiver is ready to receive (?) the signal and vice versa (rendezvous).The synchronization does not carry any data or parameters which can easily be provided through the mediation of some global data variables.After the synchronization, both the sender and receiver resume their concurrent execution.Broadcast channels, instead, enable one-way synchronizations, where a single sender can synchronize with zero, one or multiple receivers.In other terms, the sender of a broadcast channel never blocks.Uppaal models are time-sensitive.The passage of time is controlled by clocks.A clock can be reset.A clock measures the time units elapsed from its last reset.All the clocks of a model grow according to the same rate.Time is assumed to be dense.A process automaton consists of locations linked by directed edges annotated by guarded commands.A location denotes a local state where the automaton can remain for a certain amount of time (including zero or possibly infinite time units).A normal location (see the NCS location in Figure 1) denotes a state where the automaton can stay for an arbitrary time.Uppaal provides the special concept of an invariant, that is, a logical condition, e.g., based on a clock constraint, attached to a normal location, to restrict the permanence of the automaton the location.In this case, the location has to be abandoned before its invariant is up to become false.An urgent location (with an internal U) has to be exited immediately, without time passage.A committed location (see the initial location with the internal C in Figure 2) is similar to an urgent location.However, Uppaal gives priority to committed locations which will be exited before the urgent ones.Among the same group of committed or urgent locations, the exit order is non-deterministic.A guarded command is composed of three optional attributes: a guard (a logical condition based on clock and/or data constraints, drawn in green, see Figure 3) which is true by default when it is missing; a channel synchronization operation (? or !, drawn in azure, see Figure 3); and an update component (drawn in blue, see Figure 3), that is, a comma separated sequence of variable assignments and clock resets.A void command denotes a spontaneous edge.A spontaneous edge originating from a normal location can be taken at any time, also after an infinite amount of time, that is, the edge can possibly not be taken at all.A guarded command represents the unit of concurrency of the Uppaal modeling language.When a channel synchronization involves two or more locations in different automata, a joint instantaneous exiting of the corresponding locations will occur.The semantics of Uppaal prescribes, in a joint synchronization in multiple automata, that the update operations in the sender precede the updates of the receivers (the order of the receiver updates is defined in the system declaration section).

•
(Safety) Absence of deadlocks in the processes attempting to use the shared resource.• (Safety) At any time, only one process should be allowed to enter its critical section.

•
(Bounded liveness) A competing process eventually enters its critical section.In other terms, the waiting time for a competing process should be finite and hopefully small.Equivalently, the number of by-passes or the overtaking factor which a waiting process experiments from other competing processes should be bounded.This property also expresses, for a competing process, the absence of starvation.• (Liveness) A process in its non-critical section should never impede a competing process to enter its critical section.

Uppaal Modeling Method
Mutual exclusion (ME) algorithms normally do not make any assumption about the time duration of the operations in the Entry, the Exit and the CS sections (see Algorithm 1).In the proposed Uppaal method for a generic process (see Figure 1), all the elementary operations are modeled by urgent locations, thus having a 0 duration.As a consequence, the interleaved, non-deterministic execution order of process actions is naturally expressed.In addition, the use of urgent actions enables weak fairness semantics (e.g., [14,27]), which ensures progress or liveness of process executions: any process continually enabled to perform a step will eventually perform it.However, a high degree of interleaving or partial order in the nodes of the state graph, particularly when the number N of processes increases, complicates the generation and the navigation of the state graph during model checking.These considerations suggested a refinement of the ME modeling method as follows.First, the execution of the Entry actions, although continuously executed (busywaiting) in the physical process, perhaps running on a separate processor/core, in the Uppaal model can be conveniently postponed (lazy modeling) until there is an "evidence" that changes in the shared communication variables occurred which require the process to actually check if it really can prosecute toward the critical section or not.All of this in no case introduces changes in the logic of the ME algorithm, but it can reduce the burden of an excessive interleaving degree in the model.
In Figure 1, the ME model-dependent try() boolean function is introduced, which returns true if something is changed in the shared communication variables which motivates the process to execute the Entry actions.If the guess expressed by try(), for nondeterminism and concurrent execution with partner processes, would result in a failure, that is, the process still has to continue waiting in the competing state, the BW location will be re-entered.If instead the Entry actions end with success, the process continues by entering its critical section.It is worth noting that BW is immediately exited at any time the optimistic try() function returns true.Toward this, a (fictitious) signal sent over the urgent and broadcast channel synch is used.Note that no receiver exists for this asynchronous message.The CS section (see Algorithm 1) is purposely modeled as a normal location with a dwell time of exactly 1 time unit (see the invariant x ≤ 1 on CS and the guard x ≥ 1 on the edge exiting the location CS).The use of a unitary duration for any critical section makes the model time-sensitive, facilitates the prediction of the overtaking factor (see later in this paper) and does not affect the mutual exclusion algorithm evolution.On the other hand, the CS behavior can naturally break possible Zeno-cycles [28], that is, those infinite  Property verification can be assessed through the model checker.Effectively, the Dekker model is deadlock-free (query 1 of Table 1).In addition, the fundamental mutual exclusion property (query 2 of Table 1) is satisfied.This property was accompanied by the assessment that both Process(1) and Process(2) can effectively enter the CS with the two existential queries which are satisfied: E<> Process(1).CS E<> Process (2).CS Also, the liveness property checked by query 4 of Table 1 is satisfied.However, query 3 of Table 1 as well as the query Process(1).W --> Process(1).CS are not satisfied.In reality, this property is tied to the fact that the model in Figure 3 has a Zeno-cycle (see the loop from W to itself: flag[j] followed by turn!=j, which can be executed an infinite number of times and in 0 time).Query 5 of Table 1 furnishes, whatever the target process is, an overtaking factor of 1.
As a final remark, it should be observed that Zeno-cycles (equivalent to a mechanical perpetual motion) can exist in the model but not in physical reality where operations have, necessarily, a non-zero execution time, provided an adequate time resolution level is adopted.

Peterson's Algorithm for Two Processes
A more elegant and compact solution to the mutual exclusion problem for two processes was proposed by G.L. Peterson in [30].Using the same shared data as in Dekker's algorithm and the same initializations, the pseudo-code of the algorithm and its Uppaal model are shown, respectively, in Algorithm 3 and Figure 4.   Unicast and broadcast channels can be declared to be urgent.In this case, an enabled command involving an urgent synchronization, will be executed before any time passage.However, the order of exiting from multiple simultaneous urgent locations and normal locations with an exiting edge annotated with an enabled guard and an urgent synchronization is non-deterministic.
A distinguishing feature of the Uppaal modeling language which contributes to the creation of compact models is the possibility of exploiting C-like functions (see Algorithm 5 for an example) for defining the guard and/or the update components of commands.

Semantics and Verification Aspects
The formal semantics of a Uppaal model can be defined by a Timed Transition System (TTS) defined as (S, s0, →) where S is a set of execution states of the model, s0 is the initial state and → denotes the state relation which moves the current state to the next one.Two basic relations exist: the delay transition and the action transition.An action transition represents an instantaneous state change, e.g., tied to a joint synchronization in multiple automata.All the action transitions enabled in the current system state will be executed before time advancement.When no more actions exist to be executed at the current time, the system time can be increased by quantity δ whose amount is constrained by the fact of not falsifying any invariant in the whole model.The amount δ is added to all the model clock valuations.A particular model execution is represented by a sequence of delay/action transitions.
The Uppaal model checker (here referred to as U-MC), accepts a query formula expressed according to a subset of Timed Computational Tree Logic (TCTL) [20], builds the TTS of the model, referred to as the model state graph, and navigates the graph to prove/disprove the query.A query captures a property to be checked.Properties can be of the following types: safety (checking that a bad state is never reached), liveness (checking that a good state is eventually reached) and bounded liveness (liveness property ensured within a given time-bound) nature.
The basic TCTL supported queries are the following: A counterexample (said a diagnostic trace) can be built by U-MC to reproduce a sequence of transitions (events) which the modeler can analyze, in the symbolic simulator, to detect why a given formula was satisfied or not satisfied by the state graph.Nodes (execution states) of the state graph are made up of two parts: a data part and a time zone.The time zone represents, by a system of clock inequalities, all the possible (also infinite) time instants for reaching the given state.A node of the state graph is actually an equivalence class: it represents all the states having the same data and whose occurrence times are solutions of the time zone inequality system.Each arc exiting from a state node and linking to the next state node is labelled with the delay or action transition which causes it.
The complexity of the state graph is exponential in the number of clocks.However, it is not the absolute number of clocks used in the model which matters, but rather the maximum number of simultaneous active clocks, that is, the maximum parallelism degree of the model.An active clock is one which is currently used in an invariant or in a constraint in a guard.The number of active clocks affects the complexity of the state graph.In addition, the memory demand critically increases as more data variables are introduced by the modeler.Another measure of the state graph complexity is represented by the degree of action interleaving (partial order), mirrored by the number of exiting arcs from a state node.The Uppaal model checker (U-MC) navigates the state graph by exploring all the possible execution paths and then the action interleavings, which originate from the initial state node.
In the last few years, Uppaal was also equipped with a Statistical Model Checker (U-SMC) [24,25] which does not build the state graph but uses instead simulations for estimating properties.The memory consumption of U-SMC is linear with the model requirements.U-SMC gives the modeler the possibility of interpreting the basic TA as Stochastic Timed Automata.To a normal location, the rate of a negative exponential probability distribution can be attached, which is sampled to furnish the dwell time for remaining in the location.In the case a normal location is provided with an invariant on a clock x of the type x ≤ b, where b is the maximal time the automaton can stay in the location, and an exiting edge with a guard like x ≥ a, with a ≤ b, under U-MC, the automaton can exit the location at any time non-deterministically chosen in the dense interval [a, b].Under U-SMC, a delay is sampled by a uniform probability distribution in the same interval, which constitutes the dwell time before abandoning the location.U-SMC supports queries written in Metric Interval Temporal Logic (MITL) [25] (see Table 2 for examples).As a simple example, U-SMC can estimate the probability of an event occurrence by executing a certain number of simulations (whose amount can be automatically inferred), each one lasting after an assigned time limit, and counting how many times the event occurs in the various runs, divided by the total number of runs.As a further benefit, U-SMC can accumulate data from a simulation so as to display them graphically, thus favoring a better understanding of a dynamic behavior.
Uppaal Timed Automata are used in this work to model and analyze mutual exclusion algorithms by model checking.A key feature offered by Uppaal is the possibility of investigating the effects of time on the behavior of such algorithms.

A Modeling Method for Mutual Exclusion Algorithms
Mutual exclusion algorithms can be studied according to two memory models: the common strong memory model (SMM) and the weak memory model (WMM) [9,26].According to SMM, the write and read operations issued by processes on a memory cell are atomic.In the WMM model, though, a memory cell under writing can be simultaneously read by other processes and a non-deterministic value can be achieved (flickering).In this paper, both models will be considered.
In the following, N processes identified by unique numbers from 1 to N, compete for the use of a shared resource.The abstract code structure of the generic Process(i) is assumed to be a never-ending loop as in Algorithm 1.In the NCS section, the process does something unrelated from the shared resource.In particular, the duration of NCS is arbitrary and can include 0 time units (the NCS is immediately abandoned) and infinite time units (in the NCS, the process can block or terminate).Process i follows a specific protocol for accessing the resource.The Entry part is what is called the competing part.The process signals its interest in accessing the resource.However, it has to wait until the process obtains the grant to actually access the resource.The Exit part consists of the final operations which the process executes to let partners be informed it has finished with this access to the resource.
Both the Entry and the Exit code sections depend on and make use of the global and shared communication variables.On the other hand, each process owns some private local variables, inaccessible to other processes.The original design of a mutual exclusion algorithm concerns devising a minimal number of shared communication variables whose use is capable of ensuring the mutual exclusion and the related properties.
• (Safety) Absence of deadlocks in the processes attempting to use the shared resource.
• (Safety) At any time, only one process should be allowed to enter its critical section.
• (Bounded liveness) A competing process eventually enters its critical section.In other terms, the waiting time for a competing process should be finite and hopefully small.Equivalently, the number of by-passes or the overtaking factor which a waiting process experiments from other competing processes should be bounded.This property also expresses, for a competing process, the absence of starvation.• (Liveness) A process in its non-critical section should never impede a competing process to enter its critical section.

Uppaal Modeling Method
Mutual exclusion (ME) algorithms normally do not make any assumption about the time duration of the operations in the Entry, the Exit and the CS sections (see Algorithm 1).In the proposed Uppaal method for a generic process (see Figure 1), all the elementary operations are modeled by urgent locations, thus having a 0 duration.As a consequence, the interleaved, non-deterministic execution order of process actions is naturally expressed.In addition, the use of urgent actions enables weak fairness semantics (e.g., [14,27]), which ensures progress or liveness of process executions: any process continually enabled to perform a step will eventually perform it.However, a high degree of interleaving or partial order in the nodes of the state graph, particularly when the number N of processes increases, complicates the generation and the navigation of the state graph during model checking.These considerations suggested a refinement of the ME modeling method as follows.First, the execution of the Entry actions, although continuously executed (busy-waiting) in the physical process, perhaps running on a separate processor/core, in the Uppaal model can be conveniently postponed (lazy modeling) until there is an "evidence" that changes in the shared communication variables occurred which require the process to actually check if it really can prosecute toward the critical section or not.All of this in no case introduces changes in the logic of the ME algorithm, but it can reduce the burden of an excessive interleaving degree in the model.
In Figure 1, the ME model-dependent try() boolean function is introduced, which returns true if something is changed in the shared communication variables which motivates the process to execute the Entry actions.If the guess expressed by try(), for non-determinism and concurrent execution with partner processes, would result in a failure, that is, the process still has to continue waiting in the competing state, the BW location will be re-entered.If instead the Entry actions end with success, the process continues by entering its critical section.It is worth noting that BW is immediately exited at any time the optimistic try() function returns true.Toward this, a (fictitious) signal sent over the urgent and broadcast channel synch is used.Note that no receiver exists for this asynchronous message.
The CS section (see Algorithm 1) is purposely modeled as a normal location with a dwell time of exactly 1 time unit (see the invariant x ≤ 1 on CS and the guard x ≥ 1 on the edge exiting the location CS).The use of a unitary duration for any critical section makes the model time-sensitive, facilitates the prediction of the overtaking factor (see later in this paper) and does not affect the mutual exclusion algorithm evolution.On the other hand, the CS behavior can naturally break possible Zeno-cycles [28], that is, those infinite sequences of events executed in 0 time, which could arise in a model with a lot of urgent actions.
The non-critical section NCS is instead modeled as a normal location with a spontaneous exiting edge.As a consequence, NCS can be abandoned in 0 time units, or the process automaton can remain in it also an infinite number of time units.The last situation models the process which can be stopped into NCS.
Special care is required in the modeling of the actions of both the Entry and the Exit sections.Under both the strong memory model (SMM) and the weak memory model (WMM), it is fundamental to realize that individual shared communication variables must be set (written) or obtained (read) in separated edges of the Uppaal process model.All of this mirrors the fact that each single shared communication variable has to be accessed from a different memory location.As a consequence, a condition based on multiple shared variables has to be split, and its result calculated by separately evaluating its basic components.This way, the evaluation of the condition can be correctly affected by the non-determinism and interleaving of the various processes.The situation is different for local variables of a process.Such variables are supposed to be held in separate registers so that multiple local variables can be operated in a single edge command without errors.
The above mentioned constraints on the use of shared communication variables do not apply in the formulation of the try() function body, where the goal is to "rapidly" predict, e.g., that the process can possibly enter its critical section.It has to be stressed, though, that a true result of try() expresses only an optimistic prediction which can be falsified in the actual non-deterministic execution of Entry actions.
As one can see from Figure 1, the initial location of a process model is represented by NCS.The overall model with N process instances can be initialized by a Bootstrap automaton (see Figure 2) whose initial location is marked as committed so as to be sure, through the initialize() function, that all the global shared data are initialized before any process starts executing.After the execution of the initialize() function, the Bootstrap moves to a final normal location without exits, thus disconnecting from the model.

Predicting the Overtaking Factor
In the model of Figure 1, time can advance not only because the CS location has one time unit duration but also because of the unpredictable staying of the process into the NCS.The interplay of CS/NCS timing is a key factor for predicting the number of overtakings.Since all the processes are identical, one of them can be elected for measuring the overtakings.Let it be denoted by tp (target process, by default the process 1).Some common global declarations of a mutual exclusion Uppaal model are the following: const int N=. ..; //the number of processes typedef int [1,N] pid; //the type of process unique identifiers const pid tp=1; //target process example clock x[pid]; //one clock per process The clock x[tp] is reset as soon as the target process starts competing.The following reset(i) function can be used for this purpose: After its reset, x[tp] grows as other competing processes enter their critical sections.Due to the unitary duration of the location CS (see Figure 1), the maximal value reached by x[tp] measured before entering its CS, can furnish the number of overtakings.Such a number coincides with the number of CSs executed by competing processes before the tp process is allowed to enter its CS.
Semantic correctness of this approach, despite the timing introduced by NCS, can be stated as in the following.Of course, by design, a mutual exclusion algorithm is expected to ensure only one process can be in its critical section at a time, and that a finite number of overtakings can be suffered by any competing process and also by the tp process.Let ∆ tp be the finite amount of time that the (competing) tp process has to wait before entering its CS.Let tc be a competing process which obtains its CS before tp and then enters its NCS which is finally abandoned after a time ∆ tc , when a new competition for tc is started.In the case ∆ tc ≥ ∆ tp it necessarily follows that the process tp eventually enters its CS, and a new competition phase is then launched.If instead ∆ tc < ∆ tp , this means that the time spent by tc into its NCS naturally occurs, by concurrency/parallelism, as part of the time spent for waiting by tp, mirrored by the clock valuation x[tp].Therefore, the time behavior of processes into NCS does not forbit the correct detection of the maximal number of overtakings by observing the clock x [tp].
An important consequence of the mutual exclusion property and of the choice of the target process tp for observing the number of overtakings is that, at any moment of the model verification, despite the number N of the processes, at most two clocks can be active: that of the process tp and one of the competing processes which is allowed to enter its critical section.

Model Checking and TCTL Queries
A basic set of TCTL [20] queries (see also Section 2.2), which can be used to study a mutual exclusion algorithm expressed in Uppaal according to the general process model of Figure 1, is suggested in Table 1.The use of the built-in functions sum(. ..) and exists(. ..) should be self-explanatory.A[] (sum(i:pid)Process(i).CS)<=1 At most one process can be in its critical section (CS).

Process(tp).BW − − >Process(tp).CS
A process in BW eventually enters the critical section.

E<> Process(1).NCS && exists(j:pid) Process(j).CS
A process in NCS does not forbid another process from entering the CS.
The first query of Table 1 asks if it is always true (A[]), or invariantly, that in all the states of the state graph, there is no deadlock.The second query checks if, invariantly, the number of processes that are in the CS location is always less than or equal to one (the fundamental mutual exclusion property).The third query, based on the leads − to operator −− >, states that starting from the BW location, it inevitably follows that the process enters its CS.The fourth existential query (E<>) verifies that a process in the NCS does not forbid another process to be in the CS.The fifth query, finally, asks to quantify the maximal number of overtakings suffered by the chosen target process.Different locations, not necessarily the BW, can be chosen for observing the suprema value of x[tp].For example, a (urgent) location just before entering the CS could be adopted as well.The sup query is equivalent to the following basic query: A[] Process(tp).BW imply x[tp]<=ov-bound where ov-bound is the expected lower bound of the overtaking factor.

Statistical Model Checking and MITL Queries
The basic process model in Figure 1 can easily be adapted for it to be also exploited under the Uppaal Statistical Model Checker (U-SMC) [25].Basically, the possibility of time not advancing in the NCS location can be avoided by attaching to NCS the rate of an exponential probability distribution function which can conveniently be established as mu = 1.0/EOF,where EOF is the expected overtaking factor.Some MITL queries useful for checking the model of a mutual exclusion algorithm through simulations are proposed in Table 2.It is to be anticipated, though, that it can be difficult, in simulation, to observe the effective number of overtakings.This is because U-SMC, during a simulation, follows a particular execution path of the actions interleaving, whereas the model checker analyzes all the possible paths.Probability that the overtaking factor (x[tp]) can be found greater than the expected-value.
Query 1 of Table 2 asks U-SMC to estimate, using an inferred number of simulation runs each lasting 10,000 time units, the occurrence probability of the event "is there any state in which the number of processes in CS is greater than 1?".U-SMC proposes a confidence interval (by default with a confidence degree 95%) for the event probability.Of course, the confidence interval should indicate an almost impossible event.With the default parameters setting of U-SMC [25], a typical "impossible" event is witnessed by the interval [0, 0.0981446].Similarly, an almost "certain" event is denoted by a confidence interval of [0.901855, 1].The second query monitors the number of processes simultaneously in CS in a simulation, e.g., lasting 100 time units.Following the query execution, U-SMC can show the accumulated data graphically.The third query quantifies the probability of a process, e.g., the tp, to effectively enter its critical section.Such a query is expected to suggest an almost sure event.The fourth and fifth queries ask U-SMC to quantify the confidence interval of the probability that the target process experiences a number of overtakings, respectively, greater than the expected bound (an event which should be impossible) or that such a number is always found to be less than the expected bound (an event which should be certain).

Modeling and Analysis of Mutual Exclusion Algorithms
The following reports several modeling examples and their analysis results.The presented models are examples of scientific models [29], in the sense that they are aimed at permitting reasoning on and semantic interpretation of the selected mutual exclusion algorithms.They differ from engineering models where a formal system model is preliminarily prepared and analyzed toward a physical implementation.All the presented experiments were carried out using the latest version Uppaal 5.0.0, 64 bit, running on a Win11 Pro desktop platform, Dell XPS 8940, Intel i7-10700 (8 physical cores), CPU@2.90GHz, 32GB RAM.

Solutions for Two Processes
The mutual exclusion problem for two processes was solved in the sixties of the previous century by T.J. Dekker [6].This algorithm was improved by G.L. Peterson in [30].

Dekker's Algorithm
Dekker's algorithm is based on the following shared communication variables: bool flag [2], int [1,2] turn The flag array is initialized to all false.The initial value of turn can be either 1 or 2. The generic process i (1 or 2) is shown in Algorithm 2, where the Entry and Exit code sections are clearly recognizable.The local constant j denotes the partner process.Each process sets the value of its own flag[], which can be checked by the partner (flag[.]variables are said exterior variables in [31]).When a process wants to compete for the use of the resource, it sets its flag[] variable to true.The value of turn ultimately decides which process actually enters its critical section.When a process exits from its CS, it gives the turn to the partner and puts its flag[] to false to state it is, at the moment, not interested in the resource.Despite its apparent simplicity, understanding the Entry section can be difficult.Non-determinism, in fact, is at the heart of the algorithm behavior.The Uppaal model of Process(i) is depicted in Figure 3, where the try() function (see Figure 1) was directly expanded.The Process automaton has only one parameter: const pid i.The use of the pid typedef enables N instances (here N = 2) of the Process automaton to be created at the system Bootstrap time, and the various instances are distinguished by Process(1) and Process (2).
The behavior of the algorithm can be preliminarily visually inspected by animating the Uppaal model in the symbolic simulator, which is the typical tool for debugging model errors.Effectively, one "can see" that the two processes never enter their CS simultaneously.In addition, should the partner be in the busy-waiting location BW, when the current process exits its CS, the waiting process can be unblocked by receiving its turn.Things, though, can be more complicated with respect to what intuitively emerges from the animation.
Property verification can be assessed through the model checker.Effectively, the Dekker model is deadlock-free (query 1 of Table 1).In addition, the fundamental mutual exclusion property (query 2 of Table 1) is satisfied.This property was accompanied by the assessment that both Process(1) and Process(2) can effectively enter the CS with the two existential queries which are satisfied: E<> Process(1).CS E<> Process(2).CS Also, the liveness property checked by query 4 of Table 1 is satisfied.However, query 3 of Table 1 as well as the query Process(1).W --> Process(1).CS are not satisfied.In reality, this property is tied to the fact that the model in Figure 3 has a Zeno-cycle (see the loop from W to itself: flag[j] followed by turn!=j, which can be executed an infinite number of times and in 0 time).Query 5 of Table 1 furnishes, whatever the target process is, an overtaking factor of 1.As a final remark, it should be observed that Zeno-cycles (equivalent to a mechanical perpetual motion) can exist in the model but not in physical reality where operations have, necessarily, a non-zero execution time, provided an adequate time resolution level is adopted.

Peterson's Algorithm for Two Processes
A more elegant and compact solution to the mutual exclusion problem for two processes was proposed by G.L. Peterson in [30].Using the same shared data as in Dekker's algorithm and the same initializations, the pseudo-code of the algorithm and its Uppaal model are shown, respectively, in Algorithm 3 and Figure 4.The Peterson algorithm was found to be fully correct from all the queries of Table 1, with an overtaking factor of 1.What is interesting, in the Peterson model, is that it does not have any Zeno-cycle by construction.In the algorithm, a process i in busy-waiting finishes waiting as soon as the partner process j is not interested in the use of the resource or the turn is assigned to i. Any one of these conditions commands the exiting of process i from BW.On the other hand, when a process exits its CS, in the case it immediately starts competing again, not only signals this by setting its flag[] to true but also assigns the turn The Peterson algorithm was found to be fully correct from all the queries of Table 1, with an overtaking factor of 1.What is interesting, in the Peterson model, is that it does not have any Zeno-cycle by construction.In the algorithm, a process i in busy-waiting finishes waiting as soon as the partner process j is not interested in the use of the resource or the turn is assigned to i. Any one of these conditions commands the exiting of process i from BW.On the other hand, when a process exits its CS, in the case it immediately starts competing again, not only signals this by setting its flag[] to true but also assigns the turn to the partner which, if in BW, immediately becomes unblocked while the first process certainly waits in its BW.

Solutions for N ≥ 2 Processes
Several algorithms are reported in the literature.In the following, a subset of representative algorithms is considered, and their properties are thoroughly studied using the modeling and verification method proposed in this paper.

Dijkstra's Algorithm
The first solution to the mutual exclusion problem for N ≥ 2 processes, numbered from 1 to N, was proposed by E.W. Dijkstra in [32].The algorithm is based on the following shared variables:  [32], is shown in Algorithm 4. Informal arguments about its (not trivial) correctness were discussed in [32].
The Uppaal model of Algorithm 4 is depicted in Figure 5, whereas the adopted try() function is shown in Algorithm 5.As one can see, try() returns true if, optimistically, Process(i) could proceed toward its CS.After a true value of try(), the exact actions of the Entry section of Algorithm 4 are executed.Since in Li3 the value of b[k] has to be checked, the value of k is first read into the (at the moment free) local variable j; then, the value of b[j] is consulted.From Li3, the model always comes back to BW.To reduce the burden of the model checker operation, each time BW or NCS is re-entered, the local value of j is reset to 1. From Li4, if all the c[j], 1 ≤ j ≤ N, j! = i, are true, the process moves to its CS.
Modelling 2024, 5, FOR PEER REVIEW 13 was also not verified whatever the target process was.The overtaking factor for N = 3 is unbounded (undefined) for processes i>1.This result, mentioned, e.g., in [33], complies with the implicit assumption in the design of Algorithm 4 that processes are expected to compete rather infrequently, as it may occur in some applications.The model in Figure 5 was investigated for N varying from two to five.It emerged that the model satisfies the properties of absence of deadlocks and that of mutual exclusion (queries 1 and 2 of Table 1).In addition, a different behavior emerged from Process(1) from the other processes.Process(1) satisfies query 3 but not the other processes.Query 4 was also not verified whatever the target process was.The overtaking factor for N = 3 is unbounded (undefined) for processes i>1.This result, mentioned, e.g., in [33], complies with the implicit assumption in the design of Algorithm 4 that processes are expected to compete rather infrequently, as it may occur in some applications.

Knuth's Algorithm
This algorithm was proposed in [33] as an attempt to improve Dijkstra's solution described in [32].It is based on the following shared communication variables int [1,N] control; int k both initialized to 0. A process i signals to partners about its status by writing a value in {0,1,2} in its control[i] variable.The value 0 mirrors that the process is not interested in the CS.The value 1 means the process wants to compete for the resource, thus starting the Entry section of Algorithm 1. Finally, the value 2 mirrors that the process is up to enter its CS.The algorithm is reproduced in Algorithm 6.The meaning of the for statement at line L1 is to first use the indices from k down to 1, by step −1, then to use the indices from N down to 1 step −1.It should be noted that initially, when k = 0, only the second part of the for from N down to 1 is executed.The Uppaal model corresponding to Algorithm 6 is shown in Figure 6.The busywaiting location coincides with L1.The try() function is reported in Algorithm 7 and basically executes the actions from L1 to L2 without state changes.The decrement function dec(j) is also shown in Algorithm 7. The correctness of the intricate Knuth's algorithm was informally discussed in [33], where it was predicted to have an overtaking factor of 2 − 1.
The Uppaal model of Figure 6 was extensively analyzed by model checking, with N ranging from 2 to 5. Queries 1, 2 and 4 of Table 1 were found satisfied.In particular, query 1 about the absence of deadlocks which requires the complete generation of the state graph, in the case N = 5 terminates after 265 sec with a RAM peak of 5GB.Query 3 of Table 1, stating that a competing process in L1 eventually reaches the CS location, was found to be not satisfied.This last property testifies the existence of a Zeno-cycle in the Entry part.By using our proposed time-sensitive model, it emerged that the number of observed overtakings, for varying N, is reported as in Table 3.
From Table 3, a linear number of overtakings N − 1, not 2 N−1 − 1, emerges.The same results were observed on the more expensive Knuth's model where the location L1 of Figure 6 is turned urgent and the try() function is ignored; thus, the maximum degree of interleavings is required by Algorithm 6.On the adapted model for U-SMC, query 4 of Table 2 Pr[<=10000](<>Process(tp).L1 && x[tp] > (N−1)) launched, e.g., for N = 10, proposes the confidence interval of an almost impossible event.

de Bruijn's Algorithm
N.G. de Bruijn suggested in [34] an improvement to Knuth's algorithm which consisted of a replacement of the three lines of the L3 instructions of Algorithm 6 with the following: In addition, the initial value of k is no longer 0 but can be any process identifier.As a consequence of the above modifications, the new algorithm should ensure a bound on the overtakings of 1  2 N(N − 1).The Uppaal model of the de Bruijn algorithm is shown in Figure 7.
Model checking the de Bruijn model confirmed exactly the same basic properties as those of Knuth's model.The observed overtakings vs. N are shown in Table 4.
if( control[k]==0 || k==i ) then k= (if k==1 then N else k−1); In addition, the initial value of k is no longer 0 but can be any process identifier.
As a consequence of the above modifications, the new algorithm should ensure a bound on the overtakings of N(N − 1).The Uppaal model of the de Bruijn algorithm is shown in Figure 7.  4.
k==i   By increasing N, it seems the overtakings tend to be (slightly) smaller than 1  2 N(N − 1).On the adapted model for U-SMC, the query  1 are satisfied.In particular, query 1, which checks for the absence of deadlocks, in the case N = 5, ends in 102 sec with a memory peak of 2.3 GB.Table 6 collects the overtaking factor for N ranging from 2 to 5. It emerged an overtaking bound of N(N − 1).This result agrees with that reported in [3] but not with the papers [12,36] which claimed the bound to be N − 1.

CS
k=1,j++  This algorithm was proposed in [37] with the aim of improving the behavior of the generalized Peterson's algorithm.Using the same variable names as in Peterson's algorithm, the new shared variables are as follows: bool q [1,N]; int [1,N] turn [1,N] The array q[] instead of holding process ids now contains bool values (0 or 1).In addition, the ladder has N levels here, not N − 1. Differently from Peterson's solution, where a process has to reach the last level of the ladder for entering its CS, in the Block and Woo algorithm (see Algorithm 10), a process can obtain permission when it obtains a level "high enough" with respect to the number of competing processes.Should this number be m, the process goes into its CS when it reaches the level m.The Uppaal model corresponding to Algorithm 10 is depicted in Figure 10.
addition, the ladder has N levels here, not N − 1. Differently from Peterson's solution, where a process has to reach the last level of the ladder for entering its CS, in the Block and Woo algorithm (see Algorithm 10), a process can obtain permission when it obtains a level "high enough" with respect to the number of competing processes.Should this number be m, the process goes into its CS when it reaches the level m.The Uppaal model corresponding to Algorithm 10 is depicted in Figure 10.Model checking the Block and Woo algorithm for N ≤ 4 and using the queries of Table 1 confirmed that it satisfies all the basic properties of a mutual exclusion algorithm.In addition, the solution does not have Zeno-cycles, and its overtaking factor was found to be 1  2 N(N − 1), in agreement with the evaluation provided by the authors in [37].This number coincides with that which we have found for the generalized Peterson's algorithm (see Section 4.2.5);so, the new algorithm does not seem to be a real improvement.Using query 2 of Table 2. To give an idea of the wall-clock time required by some U-SMC queries, query 4 of Table 2 11, there is a state explosion even for N = 4.For N = 2 and N = 3, all the TCTL queries 1 to 4 of Table 1 were found satisfied.Query 5 suggested a N − 1 overtaking factor, which exactly confirms the authors prediction in [13].try() For this model, the MITL queries in Table 2 were useful for investigating the algorithm's behavior on the adapted model for U-SMC for N >= 4. In particular, all the responses to Table 2 queries confirmed expectations, with a bound on the overtakings of N − 1.As an example, for N = 10, Figure 12 reports the result generated by U-SMC for query 2 of Table 2. To give an idea of the wall-clock time required by some U-SMC queries, query 4 of Table 2 furnishes an indication of an impossible event after 29 runs and 62 s.

Solutions under the Weak Memory Model
It has been pointed out, e.g., in [9,13,26], that the hypothesis of a RAM memory with atomic read/write operations is today almost ideal, especially when one considers the use of personal devices (e.g., cell phones) with multi-port memories [38].In these cases, multiple reads can occur during a write operation on a given memory cell.The effect of multiple readers on the same memory cell holding a shared variable , to which the value  has to be assigned, can be modeled by returning a non-deterministic value (flickering) belonging to the type of .
The presence of flickering in the model of a mutual exclusion algorithm increases the non-determinism and partial order in the state graph, which complicates the exploration

Solutions under the Weak Memory Model
It has been pointed out, e.g., in [9,13,26], that the hypothesis of a RAM memory with atomic read/write operations is today almost ideal, especially when one considers the use of personal devices (e.g., cell phones) with multi-port memories [38].In these cases, multiple reads can occur during a write operation on a given memory cell.The effect of multiple readers on the same memory cell holding a shared variable var, to which the value v has to be assigned, can be modeled by returning a non-deterministic value (flickering) belonging to the type of var.
The presence of flickering in the model of a mutual exclusion algorithm increases the non-determinism and partial order in the state graph, which complicates the exploration of model checking.As a consequence, not only does the algorithm become more challenging to analyze, but it could lose its properties.
All the algorithms for N ≥ 2 processes previously studied in this paper were also checked under flickering.Only the generalized Peterson's algorithm, Block and Woo's algorithm and Aravind and Hesselink's algorithm were found to be robust and safe under the weak memory model.For brevity, the following only considers the Araving and Hesseling's algorithm/model modified with flickering (see Figure 13).As always, in the Uppaal model of Figure 13, the guards of edge commands are shown in green, the nondeterministic selection of a value belonging to its type is depicted in yellow and the update actions appear in blue.As an example of flickering, when the Process(i) automaton leaves its NCS in Figure 13, it has, among the other actions, to set (write) its act[i] shared variable to the true value.Due to flickering, though, a non-deterministic assignment of a value belonging to int [0,1] (the integers equivalent of false and true) is first anticipated, which is then followed by the correct assignment of act[i]=true.This way, it is perfectly possible, for non-determinism, that a reader can achieve the value defined by the flickering and not the right value.
The model of Figure 13 was analyzed by exhaustive model checking for N in [2,3] and by statistical model checking for N in [4,10].It was found to be correct from all the TCTL and MITL queries, respectively, of Table 1 and Table 2. What is interesting is that the bounded overtaking factor was confirmed to be N − 1 as in the normal case without flickering.For the above properties, Aravind and Hesselink's algorithm emerged as one of the most safe and efficient mutual exclusion algorithms.

Conclusions
Reasoning on a concurrent/parallel software system [3,8,9] can be very complex.The origin of this difficulty stands in the non-determinism and action interleaving which dominate the evolution of the system.All of this can jeopardize the human intuition with which informal reasoning tries to predict the properties of a concurrent system.As an example of flickering, when the Process(i) automaton leaves its NCS in Figure 13, it has, among the other actions, to set (write) its act[i] shared variable to the true value.Due to flickering, though, a non-deterministic assignment of a value belonging to int [0,1] (the integers equivalent of false and true) is first anticipated, which is then followed by the correct assignment of act[i]=true.This way, it is perfectly possible, for non-determinism, that a reader can achieve the value defined by the flickering and not the right value.
The model of Figure 13 was analyzed by exhaustive model checking for N in [2,3] and by statistical model checking for N in [4,10].It was found to be correct from all the TCTL and MITL queries, respectively, of Tables 1 and 2. What is interesting is that the bounded overtaking factor was confirmed to be N − 1 as in the normal case without flickering.For the above properties, Aravind and Hesselink's algorithm emerged as one of the most safe and efficient mutual exclusion algorithms.

Conclusions
Reasoning on a concurrent/parallel software system [3,8,9] can be very complex.The origin of this difficulty stands in the non-determinism and action interleaving which dominate the evolution of the system.All of this can jeopardize the human intuition with which informal reasoning tries to predict the properties of a concurrent system.This paper proposes an original approach based on formal modeling for the automated analysis of mutual exclusion algorithms, which are at the heart of concurrent/parallel, realtime operating systems.The approach is based on the Timed Automata [19] as implemented in the popular and continually evolving Uppaal toolbox [20].The major limitation of the proposed method is the well-known state explosion problem, which arises in complex algorithms which make use of or generate too much data.As an example, solutions like Lamport's bakery algorithm [39], which grants access to the critical section on the basis of an ever-increasing service number, are difficult to be handled by exhaustive model checking; it could be studied by the Statistical Model Checker instead.The state explosion restriction forbids, even for addressable algorithms, the analysis when the number N of the involved processes is greater than 5. Another reason for having chosen Uppaal for the experiments rests on the fact that the tool also provides a Statistical Model Checker [24,25] which does not build the model state graph but instead relies on simulations and stochastic behavior.This way, the tool permits an exploration of the properties of a complex algorithm by estimating event probabilities which can be of great practical value by providing further arguments about the correctness of a given algorithm for non-trivial values of N.
This paper applies the proposed modeling and verification approach to several challenging algorithms.For all these algorithms, all the expected properties were found to be satisfied, except for the overtaking factor.This way, the known results defined in the literature were retrieved and confirmed.However, in some cases, unexpected results emerged regarding the bounded degree of the overtaking which a competing and waiting process can suffer before obtaining the permission to enter its critical section.
This paper investigates mutual exclusion algorithms from the point of view of a classic memory model with read/write atomic operations.However, modeling and verification aspects under the adoption of a weak memory model-that is, when multiple readers can simultaneous access an under writing memory cell with the uncertainty (flickering) [9,13] which accompanies the reading process-are also investigated.
Besides the reported algorithms, the proposed approach was successfully applied and its properties were retrieved for the following algorithms: Burns and Lamport [2,40], Peterson and Fisher [41], the state-of-the-art tournament tree (TT)-based solutions studied in [17] as well as the TT versions of the algorithms of Kessels [31], Hafidi et al. [18] and others.
The prosecution of the research will address the following points: first, to optimize the implementation of the approach and deepen the differences from alternative methods like the theorem provers which normally are unable to deal with timing aspects; second, to extend the approach for experimenting with more general contexts of memory consistency models (e.g., [42,43]); and third, to exploit parallel computing [44] for studying large models on a multi-core machine.

Figure 1 .
Figure 1.Proposed abstract Uppaal model for a mutual exclusion process.Figure 1. Proposed abstract Uppaal model for a mutual exclusion process.

Figure 1 . 7 Figure 2 .
Figure 1.Proposed abstract Uppaal model for a mutual exclusion process.Figure 1. Proposed abstract Uppaal model for a mutual exclusion process.Modelling 2024, 5, FOR PEER REVIEW 7
bool [1..N] b, c; int k The initial value of k, 1 ≤ k ≤ N, is immaterial.If Process(i) enters its CS, k holds the value i. Process(i) modifies the values b[i] and c[i] which are inspected by the other processes.All the elements of the arrays b[] and c[] are initialized to the true value.The algorithm, reproduced as in

Algorithm 4 .
The E.W. Dijkstra Algorithm for the N ≥ 2 Processes Process(i): local int j; Li0: b[i] := false; Lil: if k # i then Li2: begin c[i] := true; Li3 if b[k] then k:=i; go to Lil end else Li4: begin c[i] := false; for j := 1 step 1 until N do if j # i and not c[j] then go to Lil end; critical section; c[i] := true; b[i] := true; remainder of the cycle in which stopping is allowed; go to Li0

Figure 7 .
Figure 7. Uppaal model of de Bruijn's algorithm.Model checking the de Bruijn model confirmed exactly the same basic properties as those of Knuth's model.The observed overtakings vs. N are shown in Table4.
Pr[<=10000](<>Process(tp).L1 && x[tp]>(N*(N−1)/2)) for varying values of N responds with an event that is almost impossible.4.2.4.The Eisenberg and McGuire Algorithm A further improvement of Knuth's algorithm was proposed by Eisenberg and McGuire in [35].It uses the same shared variables and the same initializations as in de Bruijn's algorithm (see Section 4.2.3).The new algorithm (see Algorithm 8) is committed to providing a linear overtaking factor of N − 1.The Uppaal model of Eisenberg and McGuire's algorithm is depicted in Figure 8.The try() function was adjusted in a straightforward way according to steps L1 to L3 of Algorithm 8.All the basic properties as in the Knuth and de Bruijn algorithms are satisfied.In addition, the liveness query (absence of starvation): bool try(){ return (forall(k:pid)(k==i || q[k]<j) || turn[j]!=i); }//try Queries 1 to 4 of Table

Figure 10 .
Figure 10.Uppaal model for the Block and Woo algorithm for N ≥ 2 processes.

Figure 10 .Algorithm 10 .
Figure 10.Uppaal model for the Block and Woo algorithm for N ≥ 2 processes.

Figure 11 .
Figure 11.Uppaal model for the Aravind and Hesselink algorithm for N ≥ 2 processes.The try() function for the model of Figure 11 is bool try(){ return level==0 || N−1-(sum(q:pid)!act[q])<level || !bb || turn[level]!=i;}//try Due to the use of many global and local variables in the model of Figure11, there is a state explosion even for N = 4.For N = 2 and N = 3, all the TCTL queries 1 to 4 of Table1were found satisfied.Query 5 suggested a N − 1 overtaking factor, which exactly confirms the authors prediction in[13].

Figure 11 .
Figure 11.Uppaal model for the Aravind and Hesselink algorithm for N ≥ 2 processes.

Figure 12 .
Figure 12.Number of processes vs. time, simultaneously found in their CS for N = 10.

Figure 12 .
Figure 12.Number of processes vs. time, simultaneously found in their CS for N = 10.

Modelling 2024, 5 , 24 Figure 13 .
Figure 13.The Uppaal model of the Aravind and Hesselink algorithm under the weak memory model and flickering.

Figure 13 .
Figure 13.The Uppaal model of the Aravind and Hesselink algorithm under the weak memory model and flickering.

Algorithm 1 .
General Code Structure of a Process Involved in Mutual Exclusion

Table 1 .
Some TCTL queries for checking a modeled mutual exclusion algorithm.

Table 2 .
Some MITL queries for monitoring the overtaking factor.

Table 6 .
Observed overtakings vs. N for the generalized Peterson's algorithm.
furnishes an indication of an impossible event after 29 runs and 62 s.