diff options
-rw-r--r-- | mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs | 346 | ||||
-rw-r--r-- | mono/mini/mini-runtime.c | 2 | ||||
-rw-r--r-- | mono/mini/tasklets.c | 51 | ||||
-rwxr-xr-x | scripts/ci/run-test-default.sh | 1 |
4 files changed, 232 insertions, 168 deletions
diff --git a/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs b/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs index d0b2de65429..6fa67a901d5 100644 --- a/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs +++ b/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs @@ -6,170 +6,184 @@ 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); - } - } + public class ContinuationsTest + { + [TestFixtureSetUp] + public void FixtureSetUp () + { + try { + var temp = new Continuation (); + } catch (NotImplementedException) { + Assert.Ignore ("This platform doesn't support Tasklets."); + } + } + + int total = 0; + + [Test] + public void TestContinuationsLoop() + { + Continuation _contA = new Continuation(); + + _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: diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 83420c52244..7c03fb2949b 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -3684,9 +3684,7 @@ mini_init (const char *filename, const char *runtime_version) mono_simd_intrinsics_init (); #endif -#if MONO_SUPPORT_TASKLETS mono_tasklets_init (); -#endif register_trampolines (domain); diff --git a/mono/mini/tasklets.c b/mono/mini/tasklets.c index 08deb0c00f2..7d035aa3b2c 100644 --- a/mono/mini/tasklets.c +++ b/mono/mini/tasklets.c @@ -150,6 +150,57 @@ void mono_tasklets_cleanup (void) { } +#else +static +void continuations_not_supported (void) +{ + mono_set_pending_exception (mono_get_exception_not_implemented ("Tasklets are not implemented on this platform.")); +} + +static void* +continuation_alloc (void) +{ + continuations_not_supported (); + return NULL; +} + +static void +continuation_free (MonoContinuation *cont) +{ + continuations_not_supported (); +} + +static MonoException* +continuation_mark_frame (MonoContinuation *cont) +{ + continuations_not_supported (); + return NULL; +} + +static int +continuation_store (MonoContinuation *cont, int state, MonoException **e) +{ + continuations_not_supported (); + return 0; +} + +static MonoException* +continuation_restore (MonoContinuation *cont, int state) +{ + continuations_not_supported (); + return NULL; +} + +void +mono_tasklets_init(void) +{ + mono_add_internal_call ("Mono.Tasklets.Continuation::alloc", continuation_alloc); + mono_add_internal_call ("Mono.Tasklets.Continuation::free", continuation_free); + mono_add_internal_call ("Mono.Tasklets.Continuation::mark", continuation_mark_frame); + mono_add_internal_call ("Mono.Tasklets.Continuation::store", continuation_store); + mono_add_internal_call ("Mono.Tasklets.Continuation::restore", continuation_restore); + +} #endif diff --git a/scripts/ci/run-test-default.sh b/scripts/ci/run-test-default.sh index bcce919fa7d..298eac6adfa 100755 --- a/scripts/ci/run-test-default.sh +++ b/scripts/ci/run-test-default.sh @@ -38,6 +38,7 @@ ${TESTCMD} --label=Microsoft.Build.Framework --timeout=5m make -w -C mcs/class/M ${TESTCMD} --label=Microsoft.Build.Tasks --timeout=5m make -w -C mcs/class/Microsoft.Build.Tasks run-test ${TESTCMD} --label=Microsoft.Build.Utilities --timeout=5m make -w -C mcs/class/Microsoft.Build.Utilities run-test ${TESTCMD} --label=Mono.C5 --timeout=5m make -w -C mcs/class/Mono.C5 run-test +${TESTCMD} --label=Mono.Tasklets --timeout=5m make -w -C mcs/class/Mono.Tasklets run-test ${TESTCMD} --label=System.Configuration --timeout=5m make -w -C mcs/class/System.Configuration run-test ${TESTCMD} --label=System.Transactions --timeout=5m make -w -C mcs/class/System.Transactions run-test ${TESTCMD} --label=System.Web.Extensions --timeout=5m make -w -C mcs/class/System.Web.Extensions run-test |