89 lines
2.5 KiB
Vala
89 lines
2.5 KiB
Vala
/** Fork pool used by the philosophers */
|
|
class Forks {
|
|
|
|
private bool[] fork = new bool[5]; // initially false, i.e. not used
|
|
|
|
private Cond cond = new Cond ();
|
|
private Mutex mutex = new Mutex ();
|
|
|
|
// Try to pick up the forks with the designated numbers
|
|
public void pick_up (int left, int right) {
|
|
mutex.lock ();
|
|
while (fork[left] || fork[right]) {
|
|
cond.wait (mutex);
|
|
}
|
|
fork[left] = true;
|
|
fork[right] = true;
|
|
mutex.unlock ();
|
|
}
|
|
|
|
// Lay down the forks with the designated numbers
|
|
public void lay_down (int left, int right) {
|
|
mutex.lock ();
|
|
fork[left] = false;
|
|
fork[right] = false;
|
|
cond.broadcast ();
|
|
mutex.unlock ();
|
|
}
|
|
}
|
|
|
|
/** A dining philosopher */
|
|
class Philosopher {
|
|
|
|
private int number; // this philosopher's number
|
|
private int think_delay; // how long does this philosopher think?
|
|
private int eat_delay; // how long does this philosopher eat?
|
|
private int left; // left fork number
|
|
private int right; // right fork number
|
|
private Forks forks; // forks used by all philosophers
|
|
|
|
public Philosopher (int number, int think_delay, int eat_delay, Forks forks) {
|
|
this.number = number;
|
|
this.think_delay = think_delay;
|
|
this.eat_delay = eat_delay;
|
|
this.forks = forks;
|
|
this.left = number == 0 ? 4 : number - 1;
|
|
this.right = (number + 1) % 5;
|
|
}
|
|
|
|
public void* run () {
|
|
while (true) {
|
|
Thread.usleep (think_delay);
|
|
forks.pick_up (left, right);
|
|
stdout.printf ("Philosopher %d starts eating...\n", number);
|
|
Thread.usleep (eat_delay);
|
|
forks.lay_down (left, right);
|
|
stdout.printf ("Philosopher %d stops eating...\n", number);
|
|
}
|
|
}
|
|
}
|
|
|
|
int main (string[] args) {
|
|
|
|
if (!Thread.supported ()) {
|
|
error ("Cannot run without thread support.");
|
|
}
|
|
|
|
var forks = new Forks ();
|
|
|
|
Philosopher[] philos = {
|
|
new Philosopher (0, 100000, 500000, forks),
|
|
new Philosopher (1, 200000, 400000, forks),
|
|
new Philosopher (2, 300000, 300000, forks),
|
|
new Philosopher (3, 400000, 200000, forks),
|
|
new Philosopher (4, 500000, 100000, forks)
|
|
};
|
|
|
|
try {
|
|
foreach (var philosopher in philos) {
|
|
Thread.create<void*> (philosopher.run, false);
|
|
}
|
|
} catch (ThreadError e) {
|
|
error ("%s\n", e.message);
|
|
}
|
|
|
|
new MainLoop ().run ();
|
|
|
|
return 0;
|
|
}
|