diff options
Diffstat (limited to 'mcs/class/Mono.Tasklets')
-rw-r--r-- | mcs/class/Mono.Tasklets/Makefile | 4 | ||||
-rw-r--r-- | mcs/class/Mono.Tasklets/Mono.Tasklets_test.dll.sources | 1 | ||||
-rw-r--r-- | mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs | 175 |
3 files changed, 179 insertions, 1 deletions
diff --git a/mcs/class/Mono.Tasklets/Makefile b/mcs/class/Mono.Tasklets/Makefile index 8883dbaf834..19a6cc1ceed 100644 --- a/mcs/class/Mono.Tasklets/Makefile +++ b/mcs/class/Mono.Tasklets/Makefile @@ -3,7 +3,9 @@ SUBDIRS = include ../../build/rules.make LIBRARY = Mono.Tasklets.dll -NO_TEST = yes + +LIB_MCS_FLAGS = +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) include ../../build/library.make diff --git a/mcs/class/Mono.Tasklets/Mono.Tasklets_test.dll.sources b/mcs/class/Mono.Tasklets/Mono.Tasklets_test.dll.sources new file mode 100644 index 00000000000..f994ee35b3d --- /dev/null +++ b/mcs/class/Mono.Tasklets/Mono.Tasklets_test.dll.sources @@ -0,0 +1 @@ +Mono.Tasklets/ContinuationsTest.cs diff --git a/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs b/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs new file mode 100644 index 00000000000..d0b2de65429 --- /dev/null +++ b/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs @@ -0,0 +1,175 @@ +using NUnit.Framework; + +using System; +using Mono.Tasklets; + +namespace MonoTests.System +{ + [TestFixture] + public class ContinuationsTest { + + private Continuation _contA = new Continuation(); + + private int total = 0; + + [Test] + public void TestContinuationsLoop() { + _contA.Mark(); + int value = 0; + int ret = _contA.Store(0); + for(int i = ret; i < 10; i++) { + value += i; + } + + if(value > 0) { + total += value; + _contA.Restore(ret + 1); + } + + Assert.AreEqual(total,330); + } + + private int yields = 0; + + [Test] + public void Yielding() { + Continuation baseCont = new Continuation(); + Continuation taskCont = new Continuation(); + + baseCont.Mark(); + taskCont.Mark(); + + // Store the base continuation to start the task + if (baseCont.Store(0) == 0) { + bool done = false; + int count = 0; + + while (!done) { + // Do stuff for the task. + ++count; + + // This task is counting to 100. + if (count == 100) { + done = true; + } + + // Yield every 10 loops + else if (count % 10 == 0) { + + // To yield, store the task continuation then restore + // the base continuation. + if (taskCont.Store(0) == 0) { + baseCont.Restore(1); + } + } + } + } + // When restored, 'Store' will return what was passed to Restore, in this case 1 so fall here. + else { + // Count the yields, then go back to the task. + ++yields; + taskCont.Restore(1); + } + + Assert.AreEqual(9, yields); + } + + + public class MicroThread { + + public void Yield() { + if (MyThread.Store(0) == 0) { + MainThread.Restore(1); + } + } + + public void Resume() { + if (MainThread.Store(0) == 0) { + MyThread.Restore(1); + } + } + + public void DoWork(Action action) { + if (MainThread.Store(0) == 0) { + action(); + Done = true; + MainThread.Restore(1); + } + } + + public bool Done = false; + public Continuation MainThread = new Continuation(); + public Continuation MyThread = new Continuation(); + } + + public class MicroBJob { + private int _Count = 0; + public int Count { + get { return _Count; } + set { _Count = value;} + } + + public MicroThread MicroThread; + public void Work() { + while (Count < 100) { + ++Count; + if (Count % 10 == 0) { + MicroThread.Yield(); + } + } + } + } + + [Test] + public void MicroThreadTest() { + MicroThread microA = new MicroThread(); + MicroThread microB = new MicroThread(); + + microA.MainThread.Mark(); + microA.MyThread.Mark(); + microB.MainThread.Mark(); + microB.MyThread.Mark(); + + Assert.AreEqual(false,microA.Done); + Assert.AreEqual(false,microB.Done); + + microA.DoWork( () => { + int count = 0; + while (count < 100) { + ++count; + if (count % 10 == 0) { + microA.Yield(); + } + } + }); + + MicroBJob jobB = new MicroBJob(); + jobB.MicroThread = microB; + + microB.DoWork(jobB.Work); + + Assert.AreEqual(false,microA.Done); + Assert.AreEqual(false,microB.Done); + + int yields = 0; + while (yields < 20) { + if (!microA.Done) microA.Resume(); + if (!microB.Done) microB.Resume(); + if (microA.Done && microB.Done) break; + ++yields; + } + + Assert.AreEqual(true,microA.Done); + Assert.AreEqual(true,microB.Done); + Assert.AreEqual(100,jobB.Count); + Assert.AreEqual(9,yields); + } + } +} + +// vim: noexpandtab +// Local Variables: +// tab-width: 4 +// c-basic-offset: 4 +// indent-tabs-mode: t +// End: |