Changeset 370
- Timestamp:
- 06/29/08 16:51:15 (5 months ago)
- Files:
-
- trunk/tools/tools/stackthreads.d (modified) (6 diffs)
- trunk/tools/tools/stackthreads_impl.d (modified) (3 diffs)
- trunk/tools/tools/time.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/tools/tools/stackthreads.d
r368 r370 4 4 class Coroutine { 5 5 private context ctx; 6 proc dg; 6 void delegate(proc) dg; 7 proc dg2; 7 8 Exception failure; 8 9 void safe_exec() { 9 10 yield(); 10 try dg();11 try if (dg) dg(&yield); else dg2(); 11 12 catch (Exception ex) { 12 13 failure = ex; … … 16 17 yield(); 17 18 failure = new Exception("Coroutine has ended. Cannot invoke again."); 18 failed = true;19 19 toMain(); 20 20 } … … 30 30 } 31 31 this(proc dg, size_t stacksize=1024*1024, Coroutine other = null) { 32 this.dg2 = dg; 33 this.other = other; 34 this(stacksize); 35 } 36 this(void delegate(proc) dg, size_t stacksize=1024*1024, Coroutine other = null) { 32 37 this.dg = dg; 33 38 this.other = other; 39 this(stacksize); 40 } 41 private this(size_t stacksize=1024*1024) { 34 42 changed_thread(); 35 43 ctx.genstack(stacksize); … … 43 51 if (failure) throw new Exception(info~failure.toString()); 44 52 } 53 // call with origin redirection 54 void opCall(Coroutine other) { 55 this.other = other; opCall(); 56 } 45 57 void opCall() { 46 58 failcheck("Trying to invoke coroutine failed with "); … … 52 64 } 53 65 54 import tools.tests; 66 class Generator(T) { 67 Coroutine routine; 68 T res; void delegate(void delegate(T)) dg; 69 void run(proc yield) { dg((T t) { res = t; yield(); }); } 70 T opCall() { routine(); return res; } 71 mixin This!("dg; #New(routine, &run); "); 72 /*this(void delegate(void delegate(T)) dg) { 73 this.dg = dg; 74 New(routine, &run); 75 }*/ 76 } 77 78 T delegate() generator(T)(void delegate(void delegate(T)) dg) { 79 auto gen = new Generator!(T)(dg); 80 return &gen.opCall; 81 } 82 83 T delegate() iterate(T)(T[] array) { 84 return generator(array /apply/ (T[] array, void delegate(T) yield) { foreach (entry; array) yield(entry); }); 85 } 86 87 import tools.tests, tools.functional; 55 88 unittest { 56 89 logln("StackThread test"); 57 auto test = new Coroutine( {90 auto test = new Coroutine((proc yield) { 58 91 logln("This is virtual stack context!"); 59 Coroutine.toMain();92 yield(); 60 93 logln("Hi again. Finishing now."); 61 94 }); … … 64 97 logln("> done"); 65 98 mustFail("ReinvokeTest", test()); 66 asm { int 3; } 99 /*auto dg = (int i, proc yield) { while (true) { logln(i, ": active"); yield(); } }; 100 auto tri = Range[3] /map/ fix(dg) /map/ (void delegate(proc) dg) { return new Coroutine(dg); }; 101 tri[0].other = tri[1]; tri[1].other = tri[2]; tri[2].other = tri[0]; 102 tri[0]();*/ 103 auto dg = iterate([2, 3, 4, 5][]); 104 mustEqual("IterTest #1", dg(), 2); mustEqual("IterTest #2", dg(), 3); 105 mustEqual("IterTest #3", dg(), 4); mustEqual("IterTest #4", dg(), 5); 67 106 } trunk/tools/tools/stackthreads_impl.d
r368 r370 4 4 static if (size_t.sizeof==8) const string regsize="r"; 5 5 else const string regsize="e"; 6 7 import std.gc; 8 const bool hasPatch = is(typeof(addRange(null, null, null))); 9 static if (!hasPatch) pragma(msg, "Patch not found. Context switches will be an order of magnitude slower. Poke W. to get this fixed."); 6 10 7 11 version (BigEndian) const bool enableStackthreads = false; … … 12 16 struct djmpinfo() { 13 17 void* esp, start; // start is for the GC 14 s ize_t range_index = -1;18 static if (hasPatch) size_t range_index = -1; 15 19 static void switch_gc(ref djmpinfo from, ref djmpinfo to) { 16 20 auto thr = Thread.getThis(); … … 19 23 thr.stackBottom = to.start; 20 24 auto esp = getESP(); 21 if (esp < from.start) addRange(esp, from.start, &from.range_index); // this range is now static and not being updated on collection 22 else addRange(from.start, esp, &from.range_index); 23 // remove to's range from the scanlist because it's going Active 24 if (to.range_index != -1) removeRange(to.range_index); 25 static if (hasPatch) { 26 if (esp < from.start) addRange(esp, from.start, &from.range_index); // this range is now static and not being updated on collection 27 else addRange(from.start, esp, &from.range_index); 28 // remove to's range from the scanlist because it's going Active 29 if (to.range_index != -1) removeRange(to.range_index); 30 } else { 31 if (esp < from.start) { 32 addRange(esp, from.start); 33 removeRange(to.esp); 34 } else { 35 addRange(from.start, esp); 36 removeRange(to.start); 37 } 38 } 25 39 // I hope I didn't forget anything. 26 40 } trunk/tools/tools/time.d
r359 r370 47 47 } 48 48 49 /*struct SchedTask { 50 int delegate() dg; 51 enum Mode { 52 Repeat; 53 54 class Scheduler { 55 alias int delegate() SchedTask; 56 SchedTask[] tasks; 57 58 }*/ 49 void sleep(float s) { 50 auto start = sec(); 51 while (sec() < start + s) slowyield(); 52 }
