P1. all good: synchronized in-synch deterministically P2. 3 points: 3-6 all a, all b -> 6 interleave a1 b1 a2 b2 a3 b3 .... minimum 2 -> +2 points P3. 3 points deadlock -1 point if you have something else as a problem P4. //Thread A //Thread B line a1 line b1 s1.signal s2.signal s2.wait s1.wait line a2 line b2 deadlock //Thread A //Thread B line a1 line b1 s2.wait s1.wait s1.signal s2.signal line a2 line b2 //Thread A //Thread B line a1 line b1 s2.wait s2.signal s1.signal s1.wait line a2 line b2 wrong //Thread A //Thread B s2.signal line a1 line b1 s2.wait s1.signal s1.wait line a2 line b2 -1 point for overly synchonizing extra n threads: T1 T2 T3 s1-2.sig s2-1.sig s3-1.signal s1-3.sig s2-3.sig s3-2.signal s2-1.w s1-2.w s1-3.w s3-1.w s3-2.w s2-3.w Another solution: sem m[n]; Thread i ======== m[i].signal foreach j except i m[j].wait m[j].signal Another solution: T0 s[1].signal sem[0].wait T1 s[1].wait s[2].signal sem[1].wait T2 s[2].wait s[3].signal sem[2].wait .... Tn s[n].wait sem[n-1].signal ..... sem[0].signal Another solution: sem zzz[n-1] sem aaa[n-1] T i=1..N-1 zzz[i].signal aaa[i].wait T N foreach z in zzz z.wait foreach a in aaa a.signal P5. P6. P7. -2 points for counting -1 point for thing outside of critical section that should be inside P8. barrier solution that ALWAYS expects 5 threads to be done 4 points P8. 2.5 points for each of lightswitch and multiplexer LS1.wait(m) LS2.wait(m) s4.wait s6.wait s4.singal s6.signal LS1.signal(m) LS2.signal(m)