-
-
Save beardhatcode/d085244c8cf6430ac3fdb6cfca2ebef3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use "time" | |
use "random" | |
use "collections" | |
primitive Eating | |
primitive Thinking | |
class iso Stick | |
var taken:Bool = false | |
let id:USize val | |
new create(id':USize)=> | |
id = id' | |
actor Table | |
let _env: Env val | |
let _sticks: Array[(Stick iso|None)] ref | |
new create(env: Env, num: USize) => | |
_sticks = Array[(Stick iso|None)]() | |
for i in Range(0,num) do | |
_sticks.push(recover Stick(i) end) | |
end | |
_env = env | |
be takeStick(num: USize, who:Philosopher,number:USize)=> | |
try | |
who.stick(num, _sticks.update(num,None)?) | |
else | |
who.stick(num, None.create()) | |
end | |
be realeaseStick(num: USize,stick:Stick) => | |
try | |
_sticks.update(num,consume stick)? | |
end | |
actor Philosopher | |
var state: Bool val = true | |
let _env: Env val | |
let _sticks:(USize,USize) | |
var _sticksOwn:((Stick iso|None),(Stick iso|None)) | |
var _sticksPending:(Bool,Bool) | |
let _table:Table tag | |
let number:USize val | |
let rand:Rand = Rand() | |
new create(number': USize, env: Env, table: Table tag, left_stick:USize, right_stick:USize) => | |
number = number' | |
_sticks = (left_stick,right_stick) | |
_sticksOwn = (None.create(),None.create()) | |
_sticksPending = (false,false) | |
_table = table | |
_env = env | |
fun ref eat() => | |
state = true | |
_env.out.print("@EATING " + number.string()) | |
let l:Philosopher tag = this | |
let timers = Timers | |
let timer = Timer(recover iso object is TimerNotify | |
fun ref apply(timer: Timer ref, count: U64 val) : Bool val=> state = false; l.returnSticks(); false | |
fun ref cancel( timer: Timer ref) => None.create() | |
end end | |
, rand.next()/36893487000, 0) | |
timers(consume timer) | |
be stick(num:USize, s: (Stick iso|None)) => | |
if ((_sticksPending._1 == false) and (_sticksPending._2 == false)) then return end | |
match s | |
| Stick(_sticks._1) => _sticksOwn = (consume s as Stick iso, _sticksOwn._2);_sticksPending = (false,_sticksPending._2) | |
| Stick(_sticks._2) => _sticksOwn = (_sticksOwn._1, consume s);_sticksPending = (_sticksPending._1, false) | |
| None => _sticksPending = (if num == _sticks._1 then false else _sticksPending._1 end, if num == _sticks._2 then false else _sticksPending._2 end) | |
end | |
_env.out.print("Stick got "+number.string()+" ("+_sticksOwn._1.string()+_sticksOwn._2.string()+")") | |
if (_sticksOwn._1 and _sticksOwn._2) then | |
this.eat() | |
else | |
if ((_sticksPending._1 == false) and (_sticksPending._2 == false)) then | |
this.returnSticks() | |
end | |
end | |
be returnSticks() => | |
_env.out.print("return sticks "+number.string()) | |
(var stick1,var stick2) = _sticksOwn = (false,false) | |
match stick1 | |
| Stick => _table.realeaseStick(consume stick1, this) | |
| None => true | |
end | |
match stick2 | |
| Stick => _table.realeaseStick(consume stick2, this) | |
| None => true | |
end | |
this() | |
be requestSticks()=> | |
_env.out.print("Request sticks " + number.string()) | |
_sticksPending = (true,true) | |
_table.takeStick(_sticks._1,this,number) | |
_table.takeStick(_sticks._2,this,number) | |
be apply() => | |
let l:Philosopher tag = this | |
_env.out.print("@THINK " + number.string()) | |
let timers = Timers | |
let timer = Timer(recover iso object is TimerNotify | |
fun ref apply(timer: Timer ref, count: U64 val) : Bool val=> | |
l.requestSticks() | |
false | |
fun ref cancel( timer: Timer ref) => None.create() | |
end end | |
, rand.next()/36893487000, 0) | |
timers(consume timer) | |
actor Main | |
new create(env: Env) => | |
env.out.print("Let's eat2!") | |
let table = Table(env,4) | |
for i in Range(0, 4) do | |
Philosopher(i,env, table, i, (i+1) % 4)() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment