//process i
status[i] := competing
do
{
while (turn <> i)
{
status[i] := out;
if status[turn] = out then turn := i
}
status[i] := cs
} while (status[other] = cs);
//critical section
status[i] := out;
In the above turn is a shared read/write variable, every process can
read values of the status[] array, but only process i can write to
status[i]. In addition, operations need to be instantaneous (as far as
I can tell).
Can this be implemented in software?
===
Gregory Woodhouse <gregory....@sbcglobal.net>
"Mathematics is the science of patterns."
--Lynn Arthur Steen, 1988
I can't understand this pseudocode. Is i and input variable or a
process thread? Are the status[i] values of 'competing','out','cs'
just simple flag states, line an enum? When you say that only process
i can write to status[i] is this a needed restriction, a coding
consequence, or something else?
And more basically, what is the purpose of the code?
Thanks
(And as you know I have no background in computer science, so go easy
on me :-) )
Kevin
I'll bite.
I can't understand this pseudocode. Is i and input variable or a
process thread? Are the status[i] values of 'competing','out','cs'
just simple flag states, line an enum? When you say that only process
i can write to status[i] is this a needed restriction, a coding
consequence, or something else?
And more basically, what is the purpose of the code?
Thanks
(And as you know I have no background in computer science, so go easy
on me :-) )
Kevin
OK, now I get it...
There are n processes running on the same
> machine, and the goal is to ensure that no two of them can be in what is
> called their "critical region" at the same time. The algorithm is of
> historical interest because it is n process distributed algorithm (dating to
> 1965, I think) and is a generalization of a two process solution first
> published by Dekker. It makes some fairly restrictive assumptions: both the
> variable turn and the array status[] are shared by all processes, any
> process may write to turn at any time and any process may read turn[j] at
> any time, but it may process i may only write to it if j = i. Updates are
> immediate.
>
> //process i
> status[i] := competing //process i is competing for access to the critical
> region
> do
> {
> while (turn <> i)
> {
> status[i] := out //process i has lost (for now)
> if (status[turn] = out) then turn := i
> }
> status[i] := cs
> } while (status[j] = cs for any j <> i);
> //process i enters its critical section
> write ("process ", i , " is entering its critical section!");
> write ("process", i, " is about to leave its critical section!");
> status[i] := out //process i is now in its remainder region
>
Your original question was whether this could be implemented in
software. My concern is that with multi-tasking, there could be a
case where process A tests and finds that the critical area is now
available, but before it has time to actually set the status to
reflect that it is going to enter, another process ("B") beats A to
the punch, confusing A.
In M, it seems like this could be accomplished with locks. I.e.
process A should repeatedly try to lock a segment of the message
array. If it succeeds, OK, proceed. If it fails, then try again.
Kevin
hope this is a bit better. There are n processes running on the same machine, and the goal is to ensure that no two of them can be in what is called their "critical region" at the same time. The algorithm is of historical interest because it is n process distributed algorithm (dating to 1965, I think) and is a generalization of a two process solution first published by Dekker. It makes some fairly restrictive assumptions: both the variable turn and the array status[] are shared by all processes, any process may write to turn at any time and any process may read turn[j] at any time, but it may process i may only write to it if j = i. Updates are immediate.
In M, it seems like this could be accomplished with locks. I.e.
process A should repeatedly try to lock a segment of the message
array. If it succeeds, OK, proceed. If it fails, then try again.
Kevin
This may be off topic but check out how erlang solves concurrency.
http://www.defmacro.org/ramblings/concurrency.html
Without hardware locking, I believe this does guarantee that if a
process gets to //critical section, it does have exclusive access.
While there is no possibility for a deadlock, the algorithm does have a
potential livelock situation, described below.
Consider a starting condition of turn=1, processes 2 and 3 are
competing, so status[2] and status[3] are set to competing. Since turn
is 1, both processes 2 and 3 set status[2] and status[3] to out and then
come to the statement if status[turn] = out then turn := i.
They both see status[turn=1] to be out, and set turn to i. At random,
turn might be 2 or 3, but the value doesn't matter. Both set
status[i]=cs, so status[2] and status[3] will both get set to cs.
The interesting part comes in the evaluation of while (status[other] =
cs) - 2 may see status[3] as cs and 3 may see status[2] as cs.
Another weakness of this technique of course is that there must be space
allocated in status for the maximum number of processes. Of course,
status could be coded as a tree that grows dynamically, but it will keep
growing and trees are slower than arrays for performance.
Regards
-- Bhaskar
Greg --
Without hardware locking, I believe this does guarantee that if a
process gets to //critical section, it does have exclusive access.
While there is no possibility for a deadlock, the algorithm does have a
potential livelock situation, described below.
Consider a starting condition of turn=1, processes 2 and 3 are
competing, so status[2] and status[3] are set to competing. Since turn
is 1, both processes 2 and 3 set status[2] and status[3] to out and then
come to the statement if status[turn] = out then turn := i.
They both see status[turn=1] to be out, and set turn to i. At random,
turn might be 2 or 3, but the value doesn't matter. Both set
status[i]=cs, so status[2] and status[3] will both get set to cs.
The interesting part comes in the evaluation of while (status[other] =
cs) - 2 may see status[3] as cs and 3 may see status[2] as cs.
Another weakness of this technique of course is that there must be space
allocated in status for the maximum number of processes. Of course,
status could be coded as a tree that grows dynamically, but it will keep
growing and trees are slower than arrays for performance.
Regards
-- Bhaskar
Greg Woodhouse wrote, on 09/13/2006 07:13 PM:
[KSB] <...snip...>
> Now the tests I performed were some years ago under DSM. As far as I
> know, global updates may be immediately visible in GT.M (or Caché),
> but if they are not, I don't think Dijkstra's algorithm will work.
[KSB] Since GT.M has no daemon, but instead processes cooperate with one
another to manage the database, the write is instantaneously visible as
soon as the process making the update releases the critical section
where it sets shared memory control structures.