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 }