Changeset 368

Show
Ignore:
Timestamp:
06/25/08 14:19:30 (5 months ago)
Author:
FeepingCreature
Message:
  • Further sped up coroutines
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/tools/tools/stackthreads.d

    r367 r368  
    33 
    44class Coroutine { 
    5   static TLS!(Exception) failures; 
    6   static this() { New(failures, { return cast(Exception) null; }); } 
    75  private context ctx; 
    86  proc dg; 
     7  Exception failure; 
    98  void safe_exec() { 
    10     toMain(); 
     9    yield(); 
    1110    try dg(); 
    1211    catch (Exception ex) { 
    13       failures.set(ex)
     12      failure = ex
    1413      toMain(); 
    1514      asm { int 3; } 
    1615    } 
    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; 
    1919    toMain(); 
    2020  } 
    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) { 
    2232    this.dg = dg; 
     33    this.other = other; 
     34    changed_thread(); 
    2335    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(); 
    2541  } 
    2642  void failcheck(string info) { 
    27     if (auto ex = failures()) throw new Exception(info~ex.toString()); 
     43    if (failure) throw new Exception(info~failure.toString()); 
    2844  } 
    2945  void opCall() { 
    3046    failcheck("Trying to invoke coroutine failed with "); 
    31     ctx.activate(getActiveContext()); 
     47    ctx.activate(getContextPtr); 
    3248    failcheck("Coroutine failed with "); 
    3349  } 
    34   static void toMain() { yield_main(getActiveContext()); } 
     50  void toMain() { yield_main(getContextPtr); } 
     51  void yieldToMain() { yield_main(&ctx); } 
    3552} 
    3653 
  • trunk/tools/tools/stackthreads_impl.d

    r367 r368  
    1212  struct djmpinfo() { 
    1313    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) { 
    1516      auto thr = Thread.getThis(); 
    1617      disable; // don't enable it again until you've switched over 
     
    1819      thr.stackBottom = to.start; 
    1920      auto esp = getESP(); 
    20       if (esp < from.start) addRange(esp, from.start); // this range is now static and not being updated on collection 
    21       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); 
    2223      // 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); 
    2725      // I hope I didn't forget anything. 
    2826    } 
     
    6664    } 
    6765    void set(void* vstack, ref djmpinfo invoker, void delegate() dg) { 
    68       switch_gc(invoker, *this); 
    6966      void *ep=&invoker.esp; 
    7067      start = esp = vstack; 
     68      switch_gc(invoker, *this); 
    7169      bool loaded = void; 
    7270      auto dg_ptr = &dg; 
     
    124122  context* getActiveContext() { 
    125123    auto res = active.ptr(); 
    126     if (!res || !*res) return mainline.ptr(); 
     124    if (!*res) return mainline.ptr(); 
    127125    else return *res; 
     126  } 
     127  context** getActiveContextPtr() { 
     128    return active.ptr(); 
    128129  } 
    129130   
     
    141142    // size_t size() { return vstack.length/uint.sizeof; } 
    142143    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(); 
    148145      return (esp>=vstack.ptr) && (esp < vstack.ptr+vstack.length); 
    149146    } 
  • trunk/tools/tools/threads.d

    r367 r368  
    8686        check("set:TlsSetValue", TlsSetValue(key, cast(void*) r)); 
    8787      } 
     88      Ref check() { return cast(Ref) cast(void*) TlsGetValue(key); } 
    8889      Ref ptr() { 
    8990        auto res = cast(Ref) cast(void*) TlsGetValue(key); 
     
    203204        check("set:pthread_setspecific", pthread_setspecific(key, cast(void*) r)); 
    204205      } 
     206      Ref check() { return cast(Ref) cast(void*) pthread_getspecific(key); } 
    205207      Ref ptr() { 
    206208        auto res = cast(Ref) cast(void*) pthread_getspecific(key);