Three different specifications of a queuing lock algorithm. ----------------------------------------------------------- Author: Kazuhiro Ogata Email: ogata@jaist.ac.jp The queuing lock algorithm (or simply QLOCK) can be written informally as this l1: put(queue, i) l2: repeat until top(queue) = i Critical Section cs: get(queue) Each process i is supposed to repeatedly execute this program. queue is a queue of process IDs, which is shared by all processes. put(queue,i) puts i into queue at the end, top(queue) returns the top of queue, and get(queue) deletes the top form queue. Initially queue is empty and each process is at label l1. In any specification, the queue is modeled as an array data and two variables hd and tl. hd and tl point to the top and last elements of the queue, respectively, if the queue is not empty. The capacity of the queue is L, which is given as an argument. If hd = tl + 1, the queue is empty. If tl = L, the queue is saturated. Initially, hd = 1 and tl = 0. 1. The first specification (qlock1.sal) The queue is declared as a global data, which is shared by all processes. This specification is based on examples/bakery/bakery.sal. 2. The second specification (qlock2.sal) The queue is represented as a module. The module is synchronously composed with processes. 3. The third specification (qlock3.sal) The queue is represented as a module. The module is asynchronously composed with processes. For each specification, we can do various analyses such as % sal-smc -v 3 --assertion='qlockX{;2,2}!mutex' % sal-deadlock-checker -v 3 --module='qlockX{;2,2}!system' % sal-wmc -v 3 --assertion='qlockX{;2,2}!reachable' % sal-smc -v 3 --assertion='qlockX{;2,2}!lofree' where qlockX is qlock1, qlock2, or qlock3.