1 /** Fiber abstractions. 2 * 3 * See_Also: http://ddili.org/ders/d.en/fibers.html 4 * See_Also: https://dlang.org/migrate-to-shared.html#shared 5 */ 6 module nxt.fibers; 7 8 template isFiberParameter(T) 9 { 10 import std.traits : hasAliasing; 11 enum isFiberParameter = !hasAliasing!T; 12 } 13 14 unittest 15 { 16 static assert(isFiberParameter!int); 17 static assert(!isFiberParameter!(int*)); 18 static assert(isFiberParameter!string); 19 } 20 21 import core.internal.traits : allSatisfy; 22 import core.thread : Fiber; 23 import std.stdio; 24 25 static immutable maxFiberCount = 100; 26 static immutable chunkFiberCount = 10; 27 28 size_t fiberCounter = 0; // thread global (in TLS) 29 30 /** Function-like fiber. 31 * 32 * Arguments must all fulfill `isFiberParameter`. 33 */ 34 class TestFiber : Fiber 35 { 36 this(size_t counter) 37 { 38 writeln("this:", counter); 39 _counter = counter; 40 super(&run); 41 } 42 private: 43 void run() 44 { 45 while (fiberCounter + chunkFiberCount < maxFiberCount) 46 { 47 foreach (immutable i; 0 .. chunkFiberCount) 48 { 49 writeln("loop:", _counter); 50 auto subFiber = new TestFiber(fiberCounter); 51 subFiber.call(); 52 fiberCounter += 1; 53 } 54 } 55 } 56 size_t _counter; 57 } 58 59 /// 60 unittest 61 { 62 auto rootFiber = new TestFiber(0); 63 rootFiber.call(); 64 65 // foreach (immutable i; 0 .. maxFiberCount) 66 // { 67 // // create instances of each type 68 // auto derived = new TestFiber(i); 69 // // Fiber composed = new Fiber(&fiberFunc, i); 70 71 // // call both fibers once 72 // derived.call(); 73 // // composed.call(); 74 // // printf("Execution returned to calling context.\n"); 75 // // composed.call(); 76 77 // // since each fiber has run to completion, each should have state TERM 78 // assert(derived.state == Fiber.State.TERM); 79 // // assert(composed.state == Fiber.State.TERM); 80 // } 81 } 82 83 /** Function-like fiber. 84 * 85 * Arguments must all fulfill `isFiberParameter`. 86 */ 87 class FunFiber(Args...) : Fiber 88 if (allSatisfy!(isFiberParameter, Args)) 89 { 90 this(Args args) // TODO make args const? 91 { 92 _args = args; 93 super(&run); 94 } 95 private: 96 void run() 97 { 98 writeln(_args); 99 } 100 Args _args; 101 }