Changeset 368
- Timestamp:
- 06/25/08 14:19:30 (5 months ago)
- Files:
-
- trunk/tools/tools/stackthreads.d (modified) (1 diff)
- trunk/tools/tools/stackthreads_impl.d (modified) (5 diffs)
- trunk/tools/tools/threads.d (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/tools/tools/stackthreads.d
r367 r368 3 3 4 4 class Coroutine { 5 static TLS!(Exception) failures;6 static this() { New(failures, { return cast(Exception) null; }); }7 5 private context ctx; 8 6 proc dg; 7 Exception failure; 9 8 void safe_exec() { 10 toMain();9 yield(); 11 10 try dg(); 12 11 catch (Exception ex) { 13 failure s.set(ex);12 failure = ex; 14 13 toMain(); 15 14 asm { int 3; } 16 15 } 17 toMain(); 18 failures.set(new Exception("Coroutine has ended. Cannot invoke again.")); 16 yield(); 17 failure = new Exception("Coroutine has ended. Cannot invoke again."); 18 failed = true; 19 19 toMain(); 20 20 } 21 this(proc dg, size_t stacksize=1024*1024) { 21 Coroutine other; 22 context** ct_p; context* main_p; 23 void changed_thread() { 24 ct_p = getActiveContextPtr(); 25 main_p = mainline.ptr(); 26 } 27 context* getContextPtr() { 28 if (*ct_p) return *ct_p; 29 else return main_p; 30 } 31 this(proc dg, size_t stacksize=1024*1024, Coroutine other = null) { 22 32 this.dg = dg; 33 this.other = other; 34 changed_thread(); 23 35 ctx.genstack(stacksize); 24 ctx.run(&safe_exec, getActiveContext()); 36 ctx.run(&safe_exec, getContextPtr); 37 } 38 void yield() { 39 if (other) other(); 40 else toMain(); 25 41 } 26 42 void failcheck(string info) { 27 if ( auto ex = failures()) throw new Exception(info~ex.toString());43 if (failure) throw new Exception(info~failure.toString()); 28 44 } 29 45 void opCall() { 30 46 failcheck("Trying to invoke coroutine failed with "); 31 ctx.activate(get ActiveContext());47 ctx.activate(getContextPtr); 32 48 failcheck("Coroutine failed with "); 33 49 } 34 static void toMain() { yield_main(getActiveContext()); } 50 void toMain() { yield_main(getContextPtr); } 51 void yieldToMain() { yield_main(&ctx); } 35 52 } 36 53 trunk/tools/tools/stackthreads_impl.d
r367 r368 12 12 struct djmpinfo() { 13 13 void* esp, start; // start is for the GC 14 static void switch_gc(ref djmpinfo from, djmpinfo to) { 14 size_t range_index = -1; 15 static void switch_gc(ref djmpinfo from, ref djmpinfo to) { 15 16 auto thr = Thread.getThis(); 16 17 disable; // don't enable it again until you've switched over … … 18 19 thr.stackBottom = to.start; 19 20 auto esp = getESP(); 20 if (esp < from.start) addRange(esp, from.start ); // this range is now static and not being updated on collection21 else addRange(from.start, esp );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); 22 23 // remove to's range from the scanlist because it's going Active 23 with (to) if (esp) { 24 if (esp < start) removeRange(esp); 25 else if (start < esp) removeRange(start); 26 } 24 if (to.range_index != -1) removeRange(to.range_index); 27 25 // I hope I didn't forget anything. 28 26 } … … 66 64 } 67 65 void set(void* vstack, ref djmpinfo invoker, void delegate() dg) { 68 switch_gc(invoker, *this);69 66 void *ep=&invoker.esp; 70 67 start = esp = vstack; 68 switch_gc(invoker, *this); 71 69 bool loaded = void; 72 70 auto dg_ptr = &dg; … … 124 122 context* getActiveContext() { 125 123 auto res = active.ptr(); 126 if (! res || !*res) return mainline.ptr();124 if (!*res) return mainline.ptr(); 127 125 else return *res; 126 } 127 context** getActiveContextPtr() { 128 return active.ptr(); 128 129 } 129 130 … … 141 142 // size_t size() { return vstack.length/uint.sizeof; } 142 143 bool runsMe() { 143 void *esp; 144 static if (gccasm) 145 const string stmt="asm { \"mov %%\"~regsize~\"sp, %0\" : \"=a\" esp; }"; 146 else const string stmt="asm { mov esp, ESP; }"; 147 mixin(stmt); 144 auto esp = getESP(); 148 145 return (esp>=vstack.ptr) && (esp < vstack.ptr+vstack.length); 149 146 } trunk/tools/tools/threads.d
r367 r368 86 86 check("set:TlsSetValue", TlsSetValue(key, cast(void*) r)); 87 87 } 88 Ref check() { return cast(Ref) cast(void*) TlsGetValue(key); } 88 89 Ref ptr() { 89 90 auto res = cast(Ref) cast(void*) TlsGetValue(key); … … 203 204 check("set:pthread_setspecific", pthread_setspecific(key, cast(void*) r)); 204 205 } 206 Ref check() { return cast(Ref) cast(void*) pthread_getspecific(key); } 205 207 Ref ptr() { 206 208 auto res = cast(Ref) cast(void*) pthread_getspecific(key);
