You've already forked linux-packaging-mono
Imported Upstream version 4.8.0.309
Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
parent
ee1447783b
commit
94b2861243
189
mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs
Normal file
189
mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs
Normal file
@@ -0,0 +1,189 @@
|
||||
using NUnit.Framework;
|
||||
|
||||
using System;
|
||||
using Mono.Tasklets;
|
||||
|
||||
namespace MonoTests.System
|
||||
{
|
||||
[TestFixture]
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user