PingPong.im
// Actually, this is PingPong for N=2.
// After that it's more of a RoundRobin.
uses thread.createThread, thread.Thread,
thread.Runnable, thread.sleep, thread.wait,
synch.createSemaphore, synch.Semaphore,
io.print, conv.itos, conv.stoi,
system.exit
class PingPong implements Runnable {
msg:Message
s:array[Semaphore]
id:int
init(msg_:Message, s_:array[Semaphore], id_:int):PingPong = (
msg = msg_;
s = s_;
id = id_;
this
)
name():string = "T" + itos(id)
run() = (
while (true) (
myS:Semaphore = s[id];
myS.wait();
m:string = msg.getMessage();
i:int = stoi(m, 0);
j:int = i + 1;
m = itos(j);
msg.setMessage(m);
print(name() + ": " + itos(i) + " -> " + itos(j) + "\N");
nextS:Semaphore = s[(id+1)%N];
nextS.signal();
if (j > 4*N) break;
sleep(100*(id+1));
);
)
}
class Message {
msg:string
getMessage():string = msg
setMessage(newMsg:string) = (msg = newMsg)
}
N:int
main(args:array[string]):int = (
if (length args < 1) (
print("Usage: PingPong <N>\N");
exit(1);
);
N = stoi(args[0], 2);
s:array[Semaphore] = new Semaphore[N](null);
i:int = 0;
while (i < N) (
init:int = (if (i == N-1) 0 else 1);
s[i] = createSemaphore(init, 1);
i++;
);
msg:Message = new Message;
msg.setMessage("0");
t:array[Thread] = new Thread[N](null);
i = 0;
while (i < N) (
t[i] = createThread(new PingPong.init(msg, s, i));
i++;
);
i = 0;
while (i < N) (
t[i].start();
i++;
);
i = 0;
while (i < N) (
wait(t[i]);
i++;
);
0
)