// 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 )