1 module ThreadFiberGCStress;
2 import tango.io.Stdout;
3 import tango.core.Thread;
4 import tango.core.sync.Mutex;
5 import tango.core.Memory:GC;
6 import tango.stdc.stringz;
7 import tango.stdc.stdio;
8 import tango.core.tools.TraceExceptions;
9 
10 __gshared Mutex tttt;
11 
12 void printESP(const(char)[] name){
13 	size_t esp;
14 	esp=cast(size_t)&esp;
15     synchronized(tttt){ // here one can also use synchronized(tttt)
16     	printf("%s %p %p\n",toStringz(name),esp,esp & 0xF);
17     }
18 }
19 
20 class Tr{
21     int count;
22     Mutex m;
23     char[1] s;
24     Fiber[] fibers;
25     int nfib;
26     this(){
27         count=500;
28         m=new Mutex();
29         s[0]='0';
30         fibers=[new Fiber(&fib1,1024*1024),new Fiber(&fib2,1024*1024)];
31         nfib=2;
32     }
33     void fib1(){
34         while(1){
35             workers2("f1");
36             Fiber.yield();
37         }
38     }
39     void fib2(){
40         while(1){
41             workers2("f2");
42             Fiber.yield();
43         }
44     }
45     void workers(){
46 		printESP("workers "~Thread.getThis().name);
47         try{
48             while(count>0){
49                 Fiber ff;
50                 synchronized(m){
51                     --count;
52                     assert(nfib>0);
53                     s[0]=cast(char)(Thread.getThis().name[0]);
54                     GC.collect();
55                     assert(s[0]==cast(char)(Thread.getThis().name[0]),"error");
56                     ff=fibers[0];
57                     fibers[0]=fibers[1];
58                     --nfib;
59                     fibers[1]=null;
60                 }
61                 ff.call();
62                 synchronized(m){
63                     fibers[nfib]=ff;
64                     nfib++;
65                 }
66                 Thread.yield();
67             }
68         } catch (Exception e){
69             Stdout("\nERROR, failing").newline;
70             Stdout(e).newline;
71         }
72 		printESP("workers "~Thread.getThis().name~"end");
73     }
74     void workers2(const(char)[] fName){
75 		printESP(fName~Thread.getThis().name);
76         try{
77             synchronized(m){
78                 s[0]=cast(char)(Thread.getThis().name[0]+2);
79                 GC.collect();
80                 assert(s[0]==cast(char)(Thread.getThis().name[0]+2),"error");
81             }
82         } catch (Exception e){
83             Stdout("\nERROR, failing").newline;
84             Stdout(e).newline;
85         }
86 		printESP(fName~Thread.getThis().name~"end");
87         
88     }
89 }
90 
91 void main(){
92     tttt=new Mutex();
93 	printESP("main");
94     Tr glob=new Tr();
95     Thread ta=new Thread(&glob.workers,1024*1024);
96     ta.name="a";
97     Thread tb=new Thread(&glob.workers,1024*1024);
98     tb.name="b";
99     ta.start();
100     tb.start();
101     
102     ta.join();
103     tb.join();
104 	printESP("mainEnd");
105 	synchronized(tttt){
106         printf("End!\n");
107     }
108 }
109