monitor oca
{
condition player[N];
int playerPosition[N] = { 0, ..., 0 };
bool winner = false;
bool blocked[N] = { false, ..., false };
int turn = 0;
blockedPlayer = {} // Python-like dictionary
muovi(i, n)
{
if (winner)
return 2;
if (i != turn)
player[i].wait();
if (winner)
return 2;
playerPosition[i] += n;
if (playerPosition[i] >= 99)
{
winner = true;
for (int j = 0; j < i; j++)
player[j].signal();
for (int j = i + 1; j < N; j++)
player[j].signal();
return 1;
}
if (isMultiple13(playerPosition[i]))
{
if (blockedPlayer[playerPosition[i]])
blocked[blockedPlayer[playerPosition[i]]] = false;
blocked[i] = true;
blockedPlayer[playerPosition[i]] = i;
}
turn = (i + 1) % N;
while (blocked[turn])
turn = (turn + 1) % N;
player[turn].signal();
return 0;
}
}
/*
In una situazione ideale, il giocatore (n), terminata la giocata, segnala il giocatore (n + 1) e termina.
Solo dopo che il giocatore (n) ha terminato, il giocatore (n + 1) inizia la sua giocata.
Questa situazione ideale e' descrivibile mediante la politica Signal And Continue.
Con Signal Urgent, di converso, il giocatore (n) non termina l'esecuzione della procedure entry
fino a quando non la termina il giocatore (n + 1). Il giocatore (n + 1) non la termina fino a quando
non termina il giocatore (n + 2) et cetera.
Questo meccanismo dello Urgent Stack risulta inutilmente dispendioso in questa fattispecie.
*/
adoublesend(msg, dst1, dst2)
{
asend(msg, dst1);
arecv(dst1);
asend(msg, dst2);
}
adoublerecv(sender)
{
output = arecv(sender);
asend(OK, sender);
return output;
}