Created
April 4, 2011 20:14
-
-
Save mrmonday/902318 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
// Copyright Robert Clipsham 2011. | |
// Distributed under the Boost Software License, Version 1.0. | |
// (See accompanying file LICENSE_1_0.txt or copy at | |
// http://www.boost.org/LICENSE_1_0.txt) | |
module main; | |
import core.thread; | |
import std.conv; | |
import std.datetime; | |
import std.exception; | |
import std.stdio; | |
class Person | |
{ | |
struct Nutrients | |
{ | |
int Fiber; | |
int Calcium; | |
int Iron; | |
} | |
int mNumNutrients; | |
Nutrients mNutrients; | |
this(int numNutrients) | |
{ | |
mNumNutrients = numNutrients; | |
} | |
bool satisfied() const nothrow @property | |
{ | |
return mNutrients == Nutrients(mNumNutrients, mNumNutrients, mNumNutrients); | |
} | |
} | |
class FeedThread : Thread | |
{ | |
Person mPerson; | |
this(Person p) | |
{ | |
mPerson = p; | |
super(&run); | |
} | |
void run() | |
{ | |
while(!mPerson.satisfied) | |
{ | |
mPerson.mNutrients.Fiber++; | |
mPerson.mNutrients.Calcium++; | |
mPerson.mNutrients.Iron++; | |
} | |
} | |
} | |
void feedWithThreads(int numPeople, int numNutrients) | |
{ | |
auto threads = new FeedThread[numPeople]; | |
foreach(ref t; threads) | |
{ | |
t = new FeedThread(new Person(numNutrients)); | |
} | |
foreach(t; threads) | |
{ | |
t.start(); | |
} | |
foreach(t; threads) | |
{ | |
t.join(); | |
} | |
} | |
class FeedFiber : Fiber | |
{ | |
Person mPerson; | |
this(Person p) | |
{ | |
mPerson = p; | |
super(&run); | |
} | |
void run() | |
{ | |
while(!mPerson.satisfied) | |
{ | |
mPerson.mNutrients.Fiber++; | |
mPerson.mNutrients.Calcium++; | |
mPerson.mNutrients.Iron++; | |
Fiber.yield(); | |
} | |
} | |
} | |
void feedWithFibers(int numPeople, int numNutrients) | |
{ | |
size_t terminated; | |
auto fibers = new FeedFiber[numPeople]; | |
foreach (ref f; fibers) | |
{ | |
f = new FeedFiber(new Person(numNutrients)); | |
} | |
while (terminated != fibers.length) | |
{ | |
foreach (ref f; fibers) | |
{ | |
if (f) | |
{ | |
if (f.state == Fiber.State.TERM) | |
{ | |
terminated++; | |
f = null; | |
continue; | |
} | |
f.call(); | |
} | |
} | |
} | |
} | |
void main(string[] args) | |
{ | |
enforce(args.length == 3); | |
int numPeople = to!int(args[1]); | |
int numNutrients = to!int(args[2]); | |
StopWatch sw; | |
sw.start(); | |
feedWithThreads(numPeople, numNutrients); | |
sw.stop(); | |
writef("%s, ", sw.peek().usecs); | |
sw.reset(); | |
sw.start(); | |
feedWithFibers(numPeople, numNutrients); | |
sw.stop(); | |
writefln("%s", sw.peek().usecs); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment