In this paper we also propose simple algorithms based on bounded tickets for ... so that the serialization is consistent with the behavior of the whole system.
Simple Mutual Exclusion Algorithms Based on Bounded Tickets on the Asynchronous Shared Memory Model Masataka Takamura and Yoshihide Igarashi Department of Computer Science, Gunma University, Kiryu, Japan 376-8515 {takamura,igarashi}@comp.cs.gunma-u.ac.jp
Abstract. We propose two simple algorithms based on bounded tickets for the mutual exclusion problem. These are modifications of the Bakery algorithm. An unattractive property of the Bakery algorithm is that the shared memory size is unbounded. The first algorithm based on bounded tickets uses one extra process that does not correspond to any user. It is lockout-free and mutual exclusion on the asynchronous singlewriter/multi-reader shared memory model. We then modify it to reduce the shared memory size with the cost of another extra process. The maximum waiting time using each of them is bounded by (n − 1)c + O(nl), where n is the number of users, l is an upper bound on the time between two successive atomic steps, and c is an upper bound on the time that any user spends using the resource. The shared memory size needed by the first algorithm and the second algorithm are (n+1)(1+log(2n+1)) bits and n(2 + log n) + 2 bits, respectively.
1
Introduction
Mutual exclusion is a problem of managing access to a single indivisible resource that can only support one user at a time. An early algorithm for the mutual exclusion problem proposed by Dijkstra [8] guarantees mutual exclusion, but it does not guarantee lockout-freedom. Subsequent algorithms are improvements on Dijkstra’s algorithm by guaranteeing fairness to the different users [2,11,12,14,15,16,18,19] and by weakening the type of shared memory [4,5,6,7,10,14,15,16]. The Bakery algorithm for the mutual exclusion problem is due to Lamport [14]. It works in a way like a queue of customers in a bakery, where customers draw tickets. It only uses single-writer/multi-reader shared variables, and satisfies the first-in first-served property. These are attractive features. An unattractive property of the Bakery algorithm is that it uses unbounded size shared variables. The problem of bounding the size of shared variables is important and has been much studied [1,2,9,13,20]. One of the solutions to this problem is an algorithm using a general technique, bounded time-stamping [9]. The algorithms given in [1,13] are also solutions to this problem. The shared memory size of the bounded Bakery algorithm given in [1] is O(n2 ), where n is the number of the O.H. Ibarra and L. Zhang (Eds.): COCOON 2002, LNCS 2387, pp. 259–268, 2002. c Springer-Verlag Berlin Heidelberg 2002
260
Masataka Takamura and Yoshihide Igarashi
users in the system. The algorithm given in [13] uses single-writer shared memory of size O(n log n) bits together with a multi-writer shared variable although any concurrency does not occur concerning the multi-writer shared variable. In this paper we also propose simple algorithms based on bounded tickets for the mutual exclusion problem on the asynchronous single-writer/multi-reader shared memory model. Initially we modify the Bakery algorithm so that it requires only bounded size single-writer/multi-reader shared variables. This provisional version guarantees mutual exclusion under the condition that there is always a user trying to use the resource. In order to remove this condition we use an extra process in our first algorithm called n-bmexcl1. The algorithm using the extra process guarantees lockout-freedom and mutual exclusion. The existence of an extra process may be unattractive feature, but the shared memory size for our algorithm is smaller than that of the algorithm given in [1]. We modify our algorithm to make a further reduction of the shared memory size with the penalty of the number of extra processes. For each of the algorithms proposed in this paper, the time from when a particular user tries to use the resource until it is actually granted to use the resource is bounded by (n − 1)c + O(nl), where n is the number of the users, l is an upper bound on the time between two successive atomic steps, and c is an upper bound on the time that any user is granted to use the resource. The waiting time for obtaining the grant to use the resource by the algorithms given in [1,13] is also (c−1)c+O(nl). The waiting time by the original Bakery algorithm is bounded by (n − 1)c + O(n2 l) [17]. The shared memory size needed by our first algorithm and second algorithm are (n + 1)(1 + log(2n + 1)) bits and n(2 + log n) + 2 bits, respectively. The algorithms proposed in this paper is an improvement of the size of shared variables on the original Bakery algorithm and the algorithm given in [1].
2
Preliminaries
The computation model used here is the asynchronous single-writer/multi-reader shared memory model. It is a collection of processes and shared variables. The mutual exclusion problem is to devise a protocol of how to allocate a single indivisible and nonsharable resource among n users U1 , . . . , Un . Interactions between a process and its corresponding user are by input actions from the user to the process and by output actions from the process to the user. Each process is considered to be a state machine with signals entering and leaving the process, representing its input and output actions. All communication among the processes is via the shared memory. Such a state machine is called an I/O automaton [17]. We assume that the order of actions by processes can be serialized so that the serialization is consistent with the behavior of the whole system. A user with access to the resource is modeled as being in the critical region. When a user is not involved in the resource, it is said to be in the remainder region. In order to gain admittance to the critical region, a process executes a trying protocol. The duration from the start of executing the trying protocol to the entrance of the critical region is called the trying region. After the end
Simple Mutual Exclusion Algorithms
261
of the use of the resource by a user, the corresponding process executes an exit protocol. The duration of executing the exit protocol is called the exit region. These procedures can be repeated in cyclic order, from the remainder region to the trying region, to the critical region, to the exit region, and then back again to the remainder region. We assume that the n processes are numbered 1, . . . , n. Each process i corresponds to user Ui (1 ≤ i ≤ n). An extra process is introduced in our first algorithm named n-bmexcl1, and two extra processes are introduced in our second algorithm named n-bmexcl2. The extra process used in n-bmexcl1, does not correspond to any user, but each extra process used in n-bmexcl2 corresponds to a user. For n-bmexcl1 the inputs to process i from user Ui are tryi , which means a request by user Ui for access to the resource, and exiti , which means an announcement of the end of the use of the resource by Ui . For n-bmexcl1 the outputs from process i to user Ui are criti , which means the grant of the resource to Ui , and remi , which tells Ui that it can continue with the rest of its work. For users Un−1 and Un of n-bmexcl2, input and output correspondence between these users and processes are modified. A system solving the mutual exclusion problem should satisfy the following conditions. (1) There is no reachable system state in which more than one user is in the critical region. (2) If at least one user is in the trying region and no user is in the critical region, then at some later point some user enters the critical region. (3) If a user is in the exit region, then at some later point the user enters the remainder region. (4) If all users always return the resource, then any user wishing to enter the critical region eventually does so. Conditions (1), (2), (3) and (4) above are called mutual exclusion, progress for the trying region, progress for the exit region, and lockout-freedom, respectively. The following procedure n-Bakery is the Bakery algorithm quoted from [3,17], (a, b) < (a , b ) at line 07 means that a < a , or a = a and b < b . The entry section of the Bakery algorithm begins with a part called the doorway (from line 02 to line 04) where processes in the trying region obtain their tickets. Then processes with their tickets proceed to execute the major part of the algorithm. If process i completes executing the doorway before process j begins the doorway, process i enters the critical region before process j does so. Hence, the Bakery algorithm satisfies the first-in first-served property. procedure n-Bakery shared variables for every i ∈ {1, . . . , n}: choosing(i) ∈ {0, 1}, initially 0, writable by i and readable by all j = i; ticket(i) ∈ N , initially 0, writable by i and readable by all j = i; process i input actions {inputs to process i from user Ui }: tryi , exiti ;
262
Masataka Takamura and Yoshihide Igarashi
output actions {outputs from process i to user Ui }: criti , remi ; ** Remainder region ** 01: tryi : 02: choosing(i) := 1; 03: ticket(i) := 1 + maxj=i ticket(j); 04: choosing(i) := 0; 05: for each j = i do begin 06: waitfor choosing(j) = 0; 07: waitfor ticket(j) = 0 or (ticket(i), i) < (ticket(j), j) end; 08: criti ; ** Critical region ** 09: exiti : 10: ticket(i) := 0; 11: remi ; The Bakery algorithm uses only single-writer/multi-reader shared variables, but for each i (1 ≤ i ≤ n), the size of ticket(i) is unbounded. The running time for the trying region by n-Bakery is bounded by (n − 1)c + O(n2 l). The computation of the for statement at line 05 takes O(n2 l) time. The running time of this part can also be reduced to O(nl) time by replacing the statements from line 05 to line 07 in n-Bakery with the statements from line 05 to line 10 in procedure n-provision in Section 3.
3
A Provisional Algorithm
The algorithm given in this section is a provisional one. It is a simple modification of the Bakery algorithm. For a technical reason, the domain of ticket numbers used by the algorithm is {−1, 0, . . . , 2n − 2}. A ticket with any number of {0, . . . , 2n − 2} is called a regular ticket and the ticket with −1 is called the invalid ticket. The algorithm works correctly as a lockout-free mutual exclusion protocol under the condition that there always exists a process with a regular ticket after a process first gets a regular ticket. The order of the regular tickets is cyclic in modulo 2n − 1. It is not necessarily that regular ticket numbers appearing in the trying region at a time point in an execution are cyclically consecutive. We will show such a scenario in Example 1. Here a gap means a cyclically non-consecutive part in the set of regular tickets. For example, if n = 5 and the set of regular tickets appearing at a time point is {8, 0, 1, 4}, then from 2 to 3 and from 5 to 7 are gaps. Furthermore, there may be some processes with the same ticket number in the trying region. We define the order among the tickets in the trying region as follows: The first number just after the end of the largest gap is the smallest one. Starting from this number, the order is decided cyclically in modulo 2n − 1. For the set of regular tickets, {8, 0, 1, 4}, ticket 8 is the smallest one, and the order of these tickets are 8,0,1,4, since gap from 5 to 7 is larger than gap from 2 to 3. If two or more processes have the same ticket number, the order of these processes is the order of process identifiers. We first define our terminology. Function scanticket() scans all shared variables ticket(j) (1 ≤ j ≤ n) and returns the set of pairs of regular tickets and
Simple Mutual Exclusion Algorithms
263
process identifiers holding the regular tickets. Function rmax(S) returns the largest ticket number in set S, if S is not the empty set, and returns −1 otherwise. Function previ (S) returns the identifier of the largest process that is smaller than process i in the order of pairs of ticket numbers and process identifiers if process i is not the smallest one in S, and otherwise it returns an arbitrary process identifier except i itself. procedure n-provision shared variables for every i ∈ {1, . . . , n}: choosing(i) ∈ {0, 1}, initially 0, writable by i and readable by all j = i; ticket(i) ∈ {−1, 0, . . . , 2n − 2}, initially −1, writable by i and readable by all j = i; process i input/output actions: the same as in n-Bakery ** Remainder region ** 01: tryi : 02: choosing(i) := 1; 03: ticket(i) := (1 + rmax(scanticket())) modulo 2n − 1; 04: choosing(i) := 0; 05: index := {1, 2, . . . , n}; 06: while index = ∅ do 07: for each j ∈ index do 08: if choosing(j) = 0 then index := index − {j}; 09: j := previ (scanticket()); 10: waitfor ticket(j) = −1 or (ticket(i), i) < (ticket(j), j); 11: criti ; ** Critical region ** 12: exiti : 13: ticket(i) := −1; 14: remi ; Example 1. Let n = 5. The following scenario is possible in a fair execution of nprovision. Assume ticket(1) = 0, ticket(2) = 1, ticket(3) = 2, ticket(4) = 3, and ticket(5) = −1 at a time point. Then process 5 enters the trying region. During the execution of scanticket() by process 5, it observes ticket(1) = 0 but before observing ticket(2) and ticket(3), process 2 and process 3 quickly move to the critical region and exit the critical region in this order. Then process 5 observes ticket(2) = −1, ticket(3) = −1 and ticket(4) = 3, and obtains ticket(5) = 4 since the gaps observed by process 5 are from 1 to 2 and from 4 to 8 (in this case the largest gap is observed to be from 4 to 8). This example shows that process may observe more than one gap in a certain situation. Observation 1. If after a process first gets a regular ticket, scanticket() never becomes empty at any time when it is called by any process, then the latest ticket number in the trying region is the first number of the largest gap in the set
264
Masataka Takamura and Yoshihide Igarashi
scanticket() called by the latest process. Note that this observation is not always correct if the size of the domain of regular tickets is less than 2n − 1. This is the reason why we take {−1, 0, . . . , 2n − 2} as the domain of regular tickets. Theorem 1. For an execution by procedure n-provision, if scanticket() never becomes empty after a process first gets a regular ticket then both mutual exclusion and lockout-freedom are satisfied in the execution. Proof Sketch. Assume that after a process first gets a regular ticket, scanticket() is always a non-empty set. From Observation 1, a new ticket number added at line 03 is cyclically larger by one than the largest ticket number among the ticket numbers in scanticket(). Hence, regular ticket numbers held by processes in the trying region are well ordered. Thus the order of ticket numbers in scanticket() can be correctly decided. Then the process, say process i, with the smallest ticket can send output signal criti at line 11 to tell the corresponding user that the resource is now available. The smallest ticket is reset after the end of use of the resource at line 13 in the exit region. Therefore, mutual exclusion is satisfied in any fair execution by n-provision under the condition given in the theorem. Every step in any fair execution by n-provision is progressive if the condition given in the theorem is satisfied. Hence, the theorem holds. Theorem 2. For any execution by n-provision such that scanticket() never becomes empty after a process first gets a regular ticket, the time from when a particular process enters its trying region until the process enters its critical region is bounded by (n − 1)c + O(nl). The total size of shared memory for nprovision is n(2 + log n) bits. Proof. The part from line 02 to line 04 of the program is called the doorway. The running time of the doorway is O(nl) since each statement at lines 01, 02 and 04 can be executed in O(l) time and the statement at line 03 can be executed in O(nl) time. The while statement at lines 06 to 08 can be executed in O(nl) time, since for any j such that choosing(j) = 1 in the doorway, choosing(j) is set to 0 in O(nl) time. The statement at line 09 can be executed in O(nl) time. The statement at line 10 is completed in (n − 1)c + O(l) time, since the number of processes with smaller tickets at the beginning of executing the waitfor statement is at most n − 1. The statement at line 11 is executed in O(l) time. Hence, the running time in the trying region is (n − 1)c + O(nl). The algorithm needs n 1-bit shared variables, choosing(i), 1 ≤ i ≤ n, and n shared variables, ticket(i) (1 ≤ i ≤ n), each of which stores one of 2n distinct values, −1, 0, 1, . . . , 2n − 2. Hence, the total size of the shared memory is n(2 + log n) bits. In the case where scanticket() becomes empty at a time point during an execution of n-provision, it may not run properly as suggested in the next example. Example 2. Let n = 5. The following scenario is possible in a fair execution of n-provision. Assume that ticket(1) = 4 and all other tickets are invalid at a time
Simple Mutual Exclusion Algorithms
265
point. Then process 2 enters the trying region and observes scanticket() = {4}. Just after that observation by process 2, process 1 enters the critical region and quickly exits the critical region. Before process 2 sets ticket(2) = 5, process 3 enters the trying region and observes scanticket() = ∅. Then process 3 sets ticket(3) = 0. Immediately after that, process 4 enters the trying region and observes the two gaps, and then it sets its ticket to be 1. Consequently two gaps, {2, 3, 4}, {6, 7, 8} are created. In this situation, a new comer to the trying region cannot decide which is the largest gap. That is, the new comer cannot decide which is the largest ticket, 0 or 5.
4
Mutual Exclusion Algorithms
We give two mutual exclusion algorithms that are modifications of n-provision. The first algorithm, called n-bmexcl1, uses an extra process that does not correspond to any user. It is first-in first-served as the Bakery algorithm. The extra process prevents the set of regular tickets from being empty. The order of tickets is defined as the order used in n-provision, but we take modulo 2n instead of modulo 2n − 1. The second algorithm, n-bmexcl2, is a marginal improvement on the first algorithm in the shared memory size. procedure n-bmexcl1 shared variables for every i ∈ {1, 2, . . . , n + 1}: choosing(i) ∈ {0, 1}, initially 0, writable by i and readable by all j = i; ticket(i) ∈ {−1, 0, . . . , 2n − 1}, initially −1 for 1 ≤ i ≤ n and 0 for i = n + 1, writable by i and readable by all j = i; process i for 1 ≤ i ≤ n input/output actions: the same as in n-Bakery; ** Remainder region ** 01: tryi : 02: choosing(i) := 1; 03: ticket(i) := (1 + rmax(scanticket())) modulo 2n; 04: choosing(i) := 0; 05: index := {1, 2, . . . , n + 1}; 06: while index = ∅ do 07: for each j ∈ index do 08: if choosing(j) = 0 then index := index − {j}; 09: j := previ (scanticket()); 10: waitfor ticket(j) = −1 or (ticket(i), i) < (ticket(j), j); 11: criti ; ** Critical region ** 12: exiti : 13: ticket(i) := −1; 14: remi ; process n + 1 input/output actions:
none
266
Masataka Takamura and Yoshihide Igarashi
01: repeat 02: choosing(n + 1) := 1; 03: ticket(n + 1) := (1 + rmax(scanticket() − {ticket(n + 1)})) modulo 2n; 04: choosing(n + 1) := 0; 05: index := {1, 2, . . . , n, n + 1}; 06: while index = ∅ do 07: for each j ∈ index do 08: if choosing(j) = 0 then index := index − {j}; 09: j := prevn+1 (scanticket()); 10: waitfor ticket(j) = −1 or (ticket(n + 1), n + 1) < (ticket(j), j); 11: waitfor |scanticket()| ≥ 2; 12: forever; A ticket controlled by process n + 1 always exists in the trying region. Hence, for scanticket() called by any process at any time point in a fair execution by n-bmexcl1, there is a unique largest gap in scanticket(). Any behavior of this extra process does not cause any harm. The mechanism of granting a process to enter the critical region in an execution by n-bmexcl1 is the same as in an execution by n-provision. The existence of the extra process affects the running time in the trying region of any other process by O(nl) time. The next theorem is straightforward. Theorem 3. For any execution by n-bmexcl1, it satisfies lockout-freedom and mutual exclusion, and the time from when any user requests to use the resource until it is allowed to use the resource is bounded by (n − 1)c + O(nl). The total size of shared memory needed by n-bmexcl1 is (n + 1)(1 + log(2n + 1)) bits. The next algorithm, n-bmexcl2, is a variation of n-bmexcl1. For n−1 ≤ i ≤ n, the i-th user corresponds to process i and process i + 2 in the next procedure, where inputs tryi and exiti are sent to process i + 2, output criti is sent from process i, and output remi is sent from process i + 2. procedure n-bmexcl2 shared variables f lag(n − 1) ∈ {0, 1}, initially 0, writable by n + 1 and readable by n − 1; f lag(n) ∈ {0, 1}, initially 0, writable by n + 2 and readable by n; for every i ∈ {1, 2, . . . , n}: choosing(i) ∈ {0, 1}, initially 0, writable by i and readable by all j = i; ticket(i) ∈ {−1, 0, 1, . . . , 2n − 2}, initially −1 for 1 ≤ i ≤ n − 2 and 0 for n − 1 ≤ i ≤ n, writable by i and readable by all j = i; process i for 1 ≤ i ≤ n − 2 input/output actions: the same as in n-Bakery; ** Remainder region ** 01: tryi : 02: choosing(i) := 1; 03: ticket(i) := (1 + rmax(scanticket())) modulo 2n − 1;
Simple Mutual Exclusion Algorithms
267
04: choosing(i) := 0; 05: index := {1, 2, . . . , n}; 06 to 11: the same as lines 06 to 11 in n-bmexcl1; ** Critical region ** 12 to 14: the same as lines 12 to 14 in n-bmexcl1; process i for n − 1 ≤ i ≤ n input actions: none; output action: criti ; 01: repeat 02: choosing(i) := 1; 03: ticket(i) := (1+rmax(scanticket()−{ticket(i)})) modulo 2n−1; 04: choosing(i) := 0; 05 to 10: the same as lines 05 to 10 for process i (1 ≤ i ≤ n − 2); 11: f lagi := f lag(i); 12: if f lagi = 1 then criti ; 13: waitfor |scanticket()| ≥ 2; 14: forever; process i for n + 1 ≤ i ≤ n + 2 input actions: tryi−2 , exiti−2 ; output action: remi−2 ; ** Remainder region ** 01: tryi−2 : 02: f lag(i − 2) := 1; ** Critical region ** 03: exiti−2 : 04: f lag(i − 2) := 0; 05: remi−2 ; The running time for the trying region of n-bmexcl2 is the same as the running time for the trying region of n-bmexcl1 within a constant factor. In nbmexcl2, there are n one-bit shared variables, choosing(i), 1 ≤ i ≤ n, n shared variables ticket(i), 1 ≤ i ≤ n of log 2n bits, and two one-bit shared variables, f lag(n − 1) and f lag(n). We, therefore, have the next theorem. Theorem 4. For any execution by n-bmexcl2, it satisfies lockout-freedom and mutual exclusion, and the time from when any user requests to use the resource until it is allowed to use the resource is bounded by (n − 1)c + O(nl). The total size of shared memory for n-bmexcl2 is n(2 + log n) + 2 bits.
5
Concluding Remarks
The algorithms proposed in this paper are improvements on the Bakery algorithm, but we use an extra process in n-bmexcl1 and two extra processes in n-bmexcl2. The shared memory size of each of our algorithms is smaller than the shared memory size of the algorithm given in [1], the latter does not use any extra process. We are interested in a problem whether further modifications are possible to remove the extra process(es) either in n-bmexcl1 or in n-bmexcl2 without any penalty.
268
Masataka Takamura and Yoshihide Igarashi
References 1. U.Abraham, “Bakery Algorithms”, Technical Report, Dept. of Mathematics, Ben Gurion University, Beer-Sheva, Israel, May 2001. 2. J.H.Anderson, “Lamport on mutual exclusion: 27 years of planting seeds”, Proceedings of the 27th Annual ACM Symposium on Principles of Distributed Computing, Newport, Rhode Island, pp.3–12, 2001. 3. H.Attiya and J.Welch, “Distributed Computing: Fundamentals, Simulations and Advanced Topics”, McGraw-Hill, New York, 1998. 4. J.E.Burns, “Mutual exclusion with linear waiting using binary shared variables”, ACM SIGACT News, vol.10, pp.42–47, 1978. 5. J.E.Burns, P.Jackson, N.A.Lynch, M.J.Fischer, and G.L.Peterson, “Data requirements for implementation of N-process mutual exclusion using a single shared variable”, J. of the ACM, vol.29, pp.183–205, 1982. 6. J.E.Burns, and N.A.Lynch, “Bounds on shared memory for mutual exclusion”, Information and Computation, vol.107, pp.171-184, 1993. 7. A.B.Cremers and T.N.Hibbard, “Mutual exclusion of N processors using an O(N )-valued message variable”, 5th International Colloquium on Automata, Languages and Programming, Udine, Italy, Lecture Notes in Computer Science, vol.62, pp.165–176, 1978. 8. E.W.Dijkstra, “Solution of a problem in concurrent programming control”, Communications of the ACM, vol.8, p.569, 1965. 9. D.Dolev and N.Shavit, “Bounded concurrent time-stamping”, SIAM J. on Computing, vol.26, pp.418–455, 1997. 10. M.J.Fischer, N.A.Lynch, J.E.Burns, and A.Borodin, “Distributed FIFO allocation of identical resources using small shared space”, ACM Transactions on Programming Languages and Systems, vol.11, pp.90–114, 1989. 11. Y.Igarashi, H.Kurumazaki, and Y.Nishitani, “Some modifications of the tournament algorithm for the mutual exclusion problem”, IEICE Transactions on Information and Systems, vol.E.82-D, pp.368–375, 1999. 12. Y.Igarashi and Y.Nishitani, “Speedup of the n-process mutual exclusion algorithm”, Parallel Processing Letters, vol.9, pp.475–485, 1999. 13. P.Jayanti, K.Tan, G.Friedland, and A.Katz, “Bounded Lamport’s bakery algorithm”, Proceedings of SOFTSEM’2001, Lecture Notes in Computer Science, vol.2234, Springer-Verlag, Berlin, pp.261–270, November 2001. 14. L.Lamport, “A new solution of Dijkstra’s concurrent programming problem”, Communications of ACM, vol.17, pp.453–455, 1974. 15. L.Lamport, “The mutual exclusion problem. Part II : Statement and solutions”, J. of the ACM, vol.33, pp.327–348, 1986. 16. L.Lamport, “A fast mutual exclusion algorithm”, ACM Transactions on Computer Systems, vol.5, pp.1-11, 1987. 17. N.A.Lynch, “Distributed Algorithms”, Morgan Kaufmann, San Francisco, California, 1996. 18. G.L.Peterson, “Myths about the mutual exclusion problem”, Information Processing Letters, vol.12, pp.115–116, 1981. 19. G.L.Peterson and M.J.Fischer, “Economical solutions for the critical section problem in a distributed system”, Proceedings of the 9th Annual ACM Symposium on Theory of Computing, Boulder, Colorado, pp.91–97, 1977. 20. M.Takamura and Y.Igarashi, “A simplification of the Bakery algorithm based on bounded tickets for the mutual exclusion problem”, Technical Report of IEICE, vol.101, no.376, COMP2001-45, pp.61–68, October 2001.