buildingenter() s1.wait NR.wait D.wait d1.lock s1.release D.release D.wait d2.lock d1.unlock D.release D.wait d3.lock d2.unlock D.release D.wait d3.unlock puts 'entered building' NR.release buildingleave() s2.wait ... puts 'left building' rotate() while NR.wait if(d1/d2/d3/d4) rotate90 NR.release main() sem s1=30 (enter queue length of worker threads) sem s2 (exit queue)