resource philosopher import dining_server body philosopher(i : int; dcap : cap dining_server; thinking, eating: int) printf("comment ") # animator write("philosopher", i, "alive, max think eat delays", thinking, eating) procedure think() var napping : int napping := int(random(1000*thinking)) printf("comment ") # animator writes("age=",age(),", philosopher ",i," thinking for ",napping," ms\n") nap(napping) end think procedure eat() var napping : int napping := int(random(1000*eating)) printf("comment ") # animator writes("age=",age(),", philosopher ",i," eating for ",napping," ms\n") printf("color %d blue\n", i) # animator printf("fill %d solid\n", i) # animator nap(napping) end eat process phil do true -> think() printf("comment ") # animator writes("age=", age(), ", philosopher ", i, " is hungry\n") printf("color %d green\n", i) # animator printf("fill %d solid\n", i) # animator dcap.take_forks(i) printf("comment ") # animator writes("age=", age(), ", philosopher ", i, " has taken forks\n") eat() dcap.put_forks(i) printf("comment ") # animator writes("age=", age(), ", philosopher ", i, " has returned forks\n") printf("fill %d outline\n", i) # animator printf("color %d black\n", i) # animator od end phil end philosopher resource dining_server op take_forks(i : int), put_forks(i : int) body dining_server(num_phil : int) printf("comment ") # animator write("dining server for", num_phil, "philosophers is alive") sem mutex := 1 type states = enum(thinking, hungry, eating) var state[1:num_phil] : states := ([num_phil] thinking) sem phil[1:num_phil] := ([num_phil] 0) procedure left(i : int) returns lft : int if i=1 -> lft := num_phil [] else -> lft := i-1 fi end left procedure right(i : int) returns rgh : int if i=num_phil -> rgh := 1 [] else -> rgh := i+1 fi end right procedure test(i : int) if state[i] = hungry and state[left(i)] ~= eating and state[right(i)] ~= eating -> state[i] := eating V(phil[i]) fi end test proc take_forks(i) P(mutex) state[i] := hungry test(i) V(mutex) P(phil[i]) end take_forks proc put_forks(i) P(mutex) state[i] := thinking test(left(i)); test(right(i)) V(mutex) end put_forks end dining_server resource start() import philosopher, dining_server var num_phil : int := 5, run_time : int := 60 getarg(1, num_phil); getarg(2, run_time) var max_think_delay[1:num_phil] : int := ([num_phil] 5) var max_eat_delay[1:num_phil] : int := ([num_phil] 2) fa i := 1 to num_phil -> getarg(2*i+1, max_think_delay[i]); getarg(2*i+2, max_eat_delay[i]) af var dcap : cap dining_server printf("comment ") # animator write(num_phil, "dining philosophers running", run_time, "seconds") printf("coords -1.5 -1.5 1.5 1.5\n") # animator printf("circle 1000 0.0 0.0 1.0 black outline\n") # animator printf("circle 1001 -1.4 -1.0 0.05 black outline\n") # animator printf("text 1002 -1.3 -1.025 0 black THINKING\n") # animator printf("circle 1003 -1.4 -1.2 0.05 green solid\n") # animator printf("text 1004 -1.3 -1.225 0 black HUNGRY\n") # animator printf("circle 1005 -1.4 -1.4 0.05 blue solid\n") # animator printf("text 1006 -1.3 -1.425 0 black EATING\n") # animator dcap := create dining_server(num_phil) const TWO_PI := 2.0*acos(-1.0) # animator fa i := 1 to num_phil -> printf("circle %d %7.2f %7.2f 0.1 black outline\n", # animator i, sin(i*(TWO_PI/num_phil)), cos(i*(TWO_PI/num_phil))) # animator printf("text %d %7.2f %7.2f 1 black %d\n", # animator 1010+i, sin(i*(TWO_PI/num_phil))+0.1, # animator cos(i*(TWO_PI/num_phil))+0.1, i) # animator create philosopher(i, dcap, max_think_delay[i], max_eat_delay[i]) af nap(1000*run_time); printf("comment "); write("must stop now"); stop end start /* ............... Example compile and run(s) % sr -o din_phil din_phil.sr % ./din_phil 5 3 comment 5 dining philosophers running 3 seconds coords -1.5 -1.5 1.5 1.5 circle 1000 0.0 0.0 1.0 black outline circle 1001 -1.4 -1.0 0.05 black outline text 1002 -1.3 -1.025 0 black THINKING circle 1003 -1.4 -1.2 0.05 green solid text 1004 -1.3 -1.225 0 black HUNGRY circle 1005 -1.4 -1.4 0.05 blue solid text 1006 -1.3 -1.425 0 black EATING comment dining server for 5 philosophers is alive circle 1 0.95 0.31 0.1 black outline text 1011 1.05 0.41 1 black 1 comment philosopher 1 alive, max think eat delays 5 2 comment age=70, philosopher 1 thinking for 4557 ms circle 2 0.59 -0.81 0.1 black outline text 1012 0.69 -0.71 1 black 2 comment philosopher 2 alive, max think eat delays 5 2 comment age=94, philosopher 2 thinking for 2019 ms circle 3 -0.59 -0.81 0.1 black outline text 1013 -0.49 -0.71 1 black 3 comment philosopher 3 alive, max think eat delays 5 2 comment age=117, philosopher 3 thinking for 758 ms circle 4 -0.95 0.31 0.1 black outline text 1014 -0.85 0.41 1 black 4 comment philosopher 4 alive, max think eat delays 5 2 comment age=141, philosopher 4 thinking for 4206 ms circle 5 -0.00 1.00 0.1 black outline text 1015 0.10 1.10 1 black 5 comment philosopher 5 alive, max think eat delays 5 2 comment age=165, philosopher 5 thinking for 4084 ms comment age=887, philosopher 3 is hungry color 3 green fill 3 solid comment age=899, philosopher 3 has taken forks comment age=903, philosopher 3 eating for 1603 ms color 3 blue fill 3 solid comment age=2127, philosopher 2 is hungry color 2 green fill 2 solid comment age=2518, philosopher 3 has returned forks fill 3 outline color 3 black comment age=2527, philosopher 3 thinking for 2381 ms comment age=2532, philosopher 2 has taken forks comment age=2537, philosopher 2 eating for 1954 ms color 2 blue fill 2 solid comment must stop now % ./din_phil 5 10 | animator Press RUN ANIMATION button to begin XTANGO Version 1.52 5 dining philosophers running 10 seconds dining server for 5 philosophers is alive philosopher 1 alive, max think eat delays 5 2 age=40, philosopher 1 thinking for 1708 ms philosopher 2 alive, max think eat delays 5 2 age=51, philosopher 2 thinking for 4904 ms philosopher 3 alive, max think eat delays 5 2 age=82, philosopher 3 thinking for 3533 ms philosopher 4 alive, max think eat delays 5 2 age=93, philosopher 4 thinking for 832 ms philosopher 5 alive, max think eat delays 5 2 age=134, philosopher 5 thinking for 836 ms age=942, philosopher 4 is hungry age=944, philosopher 4 has taken forks age=945, philosopher 4 eating for 1506 ms age=976, philosopher 5 is hungry age=1757, philosopher 1 is hungry age=1760, philosopher 1 has taken forks age=1761, philosopher 1 eating for 687 ms age=2457, philosopher 1 has returned forks age=2459, philosopher 1 thinking for 96 ms age=2463, philosopher 4 has returned forks age=2465, philosopher 4 thinking for 2294 ms age=2466, philosopher 5 has taken forks age=2470, philosopher 5 eating for 656 ms age=2559, philosopher 1 is hungry age=3138, philosopher 5 has returned forks age=3140, philosopher 5 thinking for 4016 ms age=3141, philosopher 1 has taken forks age=3142, philosopher 1 eating for 551 ms age=3620, philosopher 3 is hungry age=3622, philosopher 3 has taken forks age=3623, philosopher 3 eating for 221 ms age=3697, philosopher 1 has returned forks age=3699, philosopher 1 thinking for 1524 ms age=3849, philosopher 3 has returned forks age=3851, philosopher 3 thinking for 1049 ms age=4781, philosopher 4 is hungry age=4797, philosopher 4 has taken forks age=4798, philosopher 4 eating for 1215 ms age=4945, philosopher 3 is hungry age=4957, philosopher 2 is hungry age=4959, philosopher 2 has taken forks age=4960, philosopher 2 eating for 1169 ms age=5227, philosopher 1 is hungry age=6027, philosopher 4 has returned forks age=6029, philosopher 4 thinking for 4183 ms age=6141, philosopher 2 has returned forks age=6149, philosopher 2 thinking for 2860 ms age=6150, philosopher 3 has taken forks age=6151, philosopher 3 eating for 1200 ms age=6153, philosopher 1 has taken forks age=6154, philosopher 1 eating for 1822 ms age=7197, philosopher 5 is hungry age=7365, philosopher 3 has returned forks age=7377, philosopher 3 thinking for 3983 ms age=7992, philosopher 1 has returned forks age=8009, philosopher 1 thinking for 2440 ms age=8010, philosopher 5 has taken forks age=8011, philosopher 5 eating for 1558 ms age=9011, philosopher 2 is hungry age=9013, philosopher 2 has taken forks age=9014, philosopher 2 eating for 298 ms age=9318, philosopher 2 has returned forks age=9320, philosopher 2 thinking for 1550 ms age=9588, philosopher 5 has returned forks age=9590, philosopher 5 thinking for 2647 ms must stop now */