1 module mecca.reactor.tests.wekapp_53937;
2 
3 // Licensed under the Boost license. Full copyright information in the AUTHORS file
4 
5 version(unittest):
6 
7 import std..string;
8 
9 import mecca.log;
10 import mecca.reactor;
11 import mecca.reactor.fls;
12 import mecca.reactor.sync.barrier;
13 import mecca.runtime.ut;
14 
15 unittest {
16     META!"UT for testing GC's scanning of local fiber variables"();
17     enum numRuns = 128;
18 
19     Barrier exitBarrier;
20 
21     void collector() {
22         scope(success) exitBarrier.markDone();
23 
24 
25         int[] array;
26         array.length=100;
27         array[] = 100;
28 
29         DEBUG!"%s array %s"(theReactor.currentFiberId, &array);
30 
31         theReactor.requestGCCollection();
32 
33         // Make sure that post GC everything is still here
34         uint verified;
35         foreach( i, a; array ) {
36             assert(a==100, "Comparison failed %s [%s]%s!=%s".format(theReactor.currentFiberId, i, a, 100));
37             verified++;
38         }
39 
40         assert(verified == 100);
41     }
42 
43     void testBody() {
44         enum ARR_SIZE = 573;
45         enum MAGIC_BYTE = 17;
46         byte[] array;
47         array.length = ARR_SIZE;
48         array[] = MAGIC_BYTE;
49 
50         void verify() {
51             // Verify that the original array is all there
52             uint size;
53             foreach( elem; array ) {
54                 assert(elem==MAGIC_BYTE);
55                 size++;
56             }
57 
58             assert(size==ARR_SIZE);
59         }
60 
61         verify();
62 
63         foreach(i; 0..numRuns) {
64             theReactor.spawnFiber( &collector );
65             exitBarrier.addWaiter();
66         }
67 
68         verify();
69 
70         exitBarrier.waitAll();
71 
72         verify();
73     }
74 
75     testWithReactor(&testBody);
76 }
77 
78 unittest {
79     META!"UT for testing GC's scanning of fiber local variables"();
80     enum numRuns = 128;
81     enum ARR_LENGTH = 493;
82 
83     Barrier entryBarrier, exitBarrier;
84 
85     alias utGcArray = FiberLocal!(ubyte[]);
86 
87     static void allocate() {
88         pragma(inline, false);
89         utGcArray.length = ARR_LENGTH;
90         utGcArray[] = cast(ubyte)theReactor.currentFiberId.value;
91     }
92 
93     static void verify() {
94         ubyte expected = cast(ubyte)theReactor.currentFiberId.value;
95         uint verified;
96 
97         foreach( i, a; utGcArray ) {
98             assert(a==expected, "Comparison failed %s %s[%s] %s!=%s".format(theReactor.currentFiberId, &(utGcArray()), i,
99                     a, expected));
100             verified++;
101         }
102 
103         assert(verified==ARR_LENGTH);
104     }
105 
106     void allocator() {
107         scope(exit) exitBarrier.markDone();
108 
109         allocate();
110 
111         DEBUG!"Pre GC verify"();
112         verify();
113 
114         entryBarrier.markDoneAndWaitAll();
115 
116         theReactor.requestGCCollection();
117         DEBUG!"Post GC verify"();
118         verify();
119     }
120 
121     void testBody() {
122         foreach(i; 0..numRuns) {
123             theReactor.spawnFiber( &allocator );
124             entryBarrier.addWaiter();
125             exitBarrier.addWaiter();
126         }
127 
128         exitBarrier.waitAll();
129     }
130 
131     testWithReactor(&testBody);
132 }