resource users() import general_semaphore var S : cap general_semaphore var num_users : int := 5, nap_time : int := 4, init_val : int := 3 var run_time : int := 60 getarg(1, num_users); getarg(2, nap_time); getarg(3, init_val) getarg(4, run_time) S := create general_semaphore("S", init_val) write(num_users, "users with nap_time=", nap_time, "initial value=", init_val, "and run_time=", run_time) process a_user(i := 1 to num_users) var napping : int do true -> napping := int(random(1000*nap_time)) write("age()=", age(), "user", i, "napping for", napping) nap(napping) write("age()=", age(), "user", i, "doing a down") S.down() napping := int(random(1000*nap_time)) write("age()=", age(), "after down, user", i, "napping for", napping) nap(napping) write("age()=", age(), "user", i, "doing an up") S.up() od end a_user nap(1000*run_time); write("must stop now"); stop end users /* ............... Example compile and run(s) % sr -o semaphores lock.sr general_semaphore.sr users.sr lock.sr: general_semaphore.sr: users.sr: lock.sr: general_semaphore.sr: users.sr: linking: % ./semaphores 5 4 2 7 a general semaphore named S with initial value 2 has been created lockd: a lock named mutex has been created, initially locked? false lockd: a lock named blocked has been created, initially locked? true lockd: a lock named serial has been created, initially locked? false 5 users with nap_time= 4 initial value= 2 and run_time= 7 age()= 101 user 1 napping for 2394 age()= 105 user 2 napping for 151 age()= 108 user 3 napping for 2222 age()= 111 user 4 napping for 3573 age()= 114 user 5 napping for 3213 age()= 271 user 2 doing a down DEBUG lockd: lock( serial ) DEBUG lockd: lock( mutex ) DEBUG down: for S count now is 1 DEBUG lockd: unlock( mutex ) DEBUG lockd: unlock( serial ) age()= 301 after down, user 2 napping for 1405 age()= 1718 user 2 doing an up DEBUG lockd: lock( mutex ) DEBUG up: for S count now is 2 DEBUG lockd: unlock( mutex ) age()= 1730 user 2 napping for 813 age()= 2338 user 3 doing a down DEBUG lockd: lock( serial ) DEBUG lockd: lock( mutex ) DEBUG down: for S count now is 1 DEBUG lockd: unlock( mutex ) DEBUG lockd: unlock( serial ) age()= 2351 after down, user 3 napping for 485 age()= 2508 user 1 doing a down DEBUG lockd: lock( serial ) DEBUG lockd: lock( mutex ) DEBUG down: for S count now is 0 DEBUG lockd: unlock( mutex ) DEBUG lockd: unlock( serial ) age()= 2516 after down, user 1 napping for 2468 age()= 2548 user 2 doing a down DEBUG lockd: lock( serial ) DEBUG lockd: lock( mutex ) DEBUG down: for S count now is -1 DEBUG lockd: unlock( mutex ) age()= 2838 user 3 doing an up DEBUG lockd: lock( mutex ) DEBUG up: for S count now is 0 DEBUG lockd: unlock( blocked ) DEBUG lockd: lock( blocked ) DEBUG lockd: unlock( mutex ) DEBUG lockd: unlock( serial ) age()= 2847 user 3 napping for 1753 age()= 2849 after down, user 2 napping for 3566 age()= 3338 user 5 doing a down DEBUG lockd: lock( serial ) DEBUG lockd: lock( mutex ) DEBUG down: for S count now is -1 DEBUG lockd: unlock( mutex ) age()= 3688 user 4 doing a down age()= 4608 user 3 doing a down age()= 4988 user 1 doing an up DEBUG lockd: lock( mutex ) DEBUG up: for S count now is 0 DEBUG lockd: unlock( blocked ) DEBUG lockd: lock( blocked ) DEBUG lockd: unlock( mutex ) DEBUG lockd: unlock( serial ) DEBUG lockd: lock( serial ) age()= 4998 user 1 napping for 2565 age()= 5000 after down, user 5 napping for 2760 DEBUG lockd: lock( mutex ) DEBUG down: for S count now is -1 DEBUG lockd: unlock( mutex ) age()= 6418 user 2 doing an up DEBUG lockd: lock( mutex ) DEBUG up: for S count now is 0 DEBUG lockd: unlock( blocked ) DEBUG lockd: lock( blocked ) DEBUG lockd: unlock( mutex ) DEBUG lockd: unlock( serial ) DEBUG lockd: lock( serial ) age()= 6429 user 2 napping for 853 age()= 6430 after down, user 4 napping for 2911 DEBUG lockd: lock( mutex ) DEBUG down: for S count now is -1 DEBUG lockd: unlock( mutex ) must stop now */