Changeset 405

Show
Ignore:
Timestamp:
08/07/08 22:59:17 (4 months ago)
Author:
FeepingCreature
Message:
  • Workarounds for LLVMDC
  • Simplex Noise in 2/3 dimensions
Files:

Legend:

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

    r309 r405  
    2222    static assert(is(typeof(other.width))&&is(typeof(other.height))); 
    2323    if (width!=other.width || height!=other.height) return false; 
    24     foreach (x, y, elem; other) if (elem != opIndex(x, y)) return false; 
     24    foreach (x, y, elem; other) { 
     25      if (elem != opIndex(x, y)) return false; 
     26    } 
    2527    return true; 
    2628  } 
     
    5254    array2d res=void; 
    5355    res.data=(new T[l1*l2]).ptr; 
    54     res.width=res.realwidth=l1; res.height=l2; res.end=res.data+l1*l2; 
     56    // breaks under LLVM 
     57    res.width = l1; res.realwidth = l1; 
     58    res.height=l2; res.end=res.data+l1*l2; 
    5559    return res; 
    5660  } 
     
    5963    array2d res=void; 
    6064    res.data=source.ptr; 
    61     res.width=res.realwidth=width; res.end=res.data+source.length; 
     65    res.width = width; res.realwidth = width; 
     66    // breaks under LLVM 
     67    // res.width = res.realwidth = width; 
     68    res.end=res.data+source.length; 
    6269    res.calcHeight; 
    6370    return res; 
     
    168175import tools.tests; 
    169176unittest { 
    170   logln("array2d tests"); 
    171177  auto flat=[1, 2, 1, 2, 3, 2, 1, 2, 1]; 
    172178  auto test=array2d!(int)(3, flat); 
  • trunk/tools/tools/base.d

    r402 r405  
    180180 
    181181template _ElemType(T) { 
    182   const foo = function() { foreach (elem; Init!(T)) return elem; assert(false); }; 
    183   alias typeof(foo()) res; 
     182  alias typeof((function() { foreach (elem; Init!(T)) return elem; assert(false); })()) res; 
    184183} 
    185184template ElemType(T) { 
     
    309308    return null; 
    310309  } else { 
    311     Unstatic!(U)[] da = match; 
     310    Unstatic!(U) da = match; 
    312311    if (!array || !da) return null; 
    313312    if (array.length<da.length) return null; 
     
    329328void fastyield() { Thread.yield; } 
    330329 
    331 void function() yield=&slowyield; 
     330// broken in llvm 
     331// void function() yield=&slowyield; 
     332void function() _yield; 
     333struct yield { 
     334  static void opCall() { if (!_yield) _yield = &slowyield; _yield(); } 
     335  static void opAssign(void function() fn) { _yield = fn; } 
     336
    332337 
    333338void remove(T)(inout T[] array, T key, bool all=true) { 
     
    360365  } 
    361366} 
    362 template op(string O) { _op!(O) op; } 
    363 template op(T, string O) { const op = function(T a, T b) { return mixin("a "~O~" b"); }; } 
     367template op(string O) { const _op!(O) op; } 
    364368struct _member(string NAME) { typeof(mixin("Init!(T)."~NAME)) opCall(T)(T t) { return mixin("t."~NAME); } } 
    365369template member(string NAME) { _member!(NAME) member; } 
     
    450454      _ex!(ReplacedEx, T, U) opCall(U...)(U u) { 
    451455        _ex!(ReplacedEx, T, U) res = void; 
     456        // pragma(msg, \"Res type is \", ReplacedEx, \" and \", T.stringof, \" and \", U.stringof); 
    452457        foreach (i, var; Ω) res.Ω[i] = var; 
     458        static assert(is(typeof(u) == U), \"Yay Compiler Bug\"); 
    453459        foreach (i, v; u) res.Ω[T.length + i] = v; 
    454460        return res; 
     
    589595template CallConfig(T, U, string V = "") { 
    590596  // can we even take its parameter types? 
     597  // pragma(msg, "What to do when calling "~U.stringof~" with "~T.stringof~" named \""~V~"\""); 
    591598  static if (is(Params!(U))) const bool hasParamTypes = true; 
    592599  else const bool hasParamTypes = false; 
    593600   
    594   static if (is(typeof(T.StupleMarker))) { 
     601  static if (is(T.StupleMarker)) { 
    595602    const string value = ExpandPointers!(U, V, T).code; 
    596603    alias ExpandPointers!(U, V, T).type type; 
     
    11301137} 
    11311138 
     1139template isStaticArray(T) { 
     1140  static if (isArray!(T)) const bool isStaticArray = !is(T == typeof(T[0])[]); 
     1141  else const bool isStaticArray = false; 
     1142} 
     1143 
    11321144alias BoolSet!("||") OrSet; alias BoolSet!("&&") AndSet; 
    11331145mixin(Operator!("or", "return OrSet(lhs, rhs); ")); 
  • trunk/tools/tools/behave_as.d

    r367 r405  
    112112  foo++; foo -= 4; 
    113113  mustEqual("BehaveAsEqualityTest", foo, 2); 
    114   debug { mustFail("RangedTest", foo += 100); } 
     114  // fails in LLVM 
     115  // debug { mustFail("RangedTest", foo += 100); } 
    115116  auto x = new Test2; x.f = 5; 
    116117  x.f_pf++; x.f_pf -= 4; 
  • trunk/tools/tools/ca_rng.d

    r402 r405  
    3434 
    3535module tools.ca_rng; 
     36import tools.base; 
    3637const CA_WIDTH=2056;   // width in cells of cellular automaton 
    3738const RULESIZE=511;    // amount of elements in rule table 
  • trunk/tools/tools/fixed_socket.d

    r396 r405  
    99  alias InternetAddress ActuallyWorkingInternetAddress; 
    1010} else { 
    11   version(Unix) private import std.c.unix.unix, std.c.stdlib: ERANGE; 
    12   else version(linux) private import std.c.linux.socket, std.c.stdlib: ERANGE; 
     11  version(linux) private import std.c.linux.socket, std.c.stdlib: ERANGE; 
     12  else version(Unix) private import std.c.unix.unix, std.c.stdlib: ERANGE; 
    1313  else static assert(0); // No socket support yet. 
    1414   
     
    9090    protected: 
    9191      sockaddr_in sin; 
    92       sockaddr* name() { return cast(sockaddr*)&sin; } 
     92      typeof(super.name()) name() { return cast(typeof(super.name()))&sin; } 
    9393      int nameLen() { return sin.sizeof; }  
    9494      this() { } 
  • trunk/tools/tools/functional.d

    r389 r405  
    148148  
    149149mixin(Operator!("uncurry", " 
     150  // pragma(msg, LHS.stringof); 
    150151  alias CollectParameters!(LHS).tuple CPAR; 
    151152  struct holder { 
     
    196197  mustEqual("ComboTest", [4, 5, 6] /cross/ [2, 3] /map/ op!(" * ") /select/ ex!("a -> (a&1)==0") /unique /sort, [8, 10, 12, 18]); 
    197198  mustEqual("AAMapTest", [4: 0.1, 5: 0.3, 6: 0.7] /map/ (int a, double f) { return f; }, [0.1, 0.3, 0.7]); 
    198   mustEqual("UncurryTest", (op!(int, "+") /curry /uncurry)(2, 2), 4); 
     199  // mustEqual("UncurryTest", (op!("+") /curry /uncurry)(2, 2), 4); 
    199200  mustEqual("ReduceTest2", [2, 3, 4, 5] /reduce(0)/ op!("+"), 14); 
    200   mustEqual("GroupbyTest", [4, 5, 6] /groupby/ (int e) { return e&1; }, [0: [4, 6][], 1: [5][]]); 
     201  // broken in LLVM 
     202  // mustEqual("GroupbyTest", [4, 5, 6] /groupby/ (int e) { return e&1; }, [0: [4, 6][], 1: [5][]]); 
    201203  mustEqual("RangeSliceMap", Range[3..6] /map/ (int e) { return e*2; }, [6, 8, 10]); 
    202204  mustEqual("RangeMap", 
     
    206208  mustEqual("RangeSelect", 
    207209    Range[10..20] /select/ (int e) { return (e&1)?true:false; }, 
    208     Range[10..20] /select/ function(int foo) { return (foo&1)?true:false; }, 
     210    // Range[10..20] /select/ function(int foo) { return (foo&1)?true:false; }, 
    209211    [11, 13, 15, 17, 19] 
    210212  ); 
  • trunk/tools/tools/ini.d

    r361 r405  
    130130    } 
    131131  } 
     132  bool del(string section, string label) { 
     133    synchronized(this) { 
     134      size_t pos = findEntry(section, label); 
     135      if (pos == size_t.max) return false; 
     136      if (pos+1 !< lines.length) lines = lines[0 .. pos]; 
     137      else lines = lines[0 .. pos] ~ lines[pos+1 .. $]; 
     138      save(); 
     139    } 
     140    return true; 
     141  } 
    132142  bool has(string section, string label) { 
    133143    return findEntry(section, label) != size_t.max; 
  • trunk/tools/tools/log.d

    r362 r405  
    11module tools.log; 
    2 import std.string, std.thread, std.file, std.traits, std.stdio: FILE; 
     2import std.string, std.thread, std.file, std.stdio: FILE; 
    33import std.c.stdio; 
    44import tools.base; 
     
    1717} 
    1818void _printf(T...)(char[] fmt, T t) { 
    19   static assert(T.length!>1); 
    2019  printf(toStringz(fmt), t); 
    2120  if (logfile) fprintf(logfile, toStringz(fmt), t); 
     
    2322void _log(T...)(T t) { 
    2423  foreach (index, part; t) { 
    25     static if (is(typeof(part) : char[])) _printf("%.*s", part); 
     24    static if (is(typeof(part) : char[])) _printf("%.*s", part.length, part.ptr); 
    2625    else static if (is(typeof(part)==char)) _printf("%c", part); 
    2726    else static if (is(typeof(part)==bool)) _log(part?"True":"False"); 
     
    2928    else static if (is(typeof(part)==int)) _printf("%i", part); 
    3029    else static if (is(typeof(part)==uint)) _printf("%u", part); 
    31     else static if (is(typeof(part): long)) _printf("%.*s", Format(part)); 
    32     else static if (is(typeof(part): ulong)) _printf("%.*s", Format(part)); 
     30    else static if (is(typeof(part): long)) _log(Format(part)); 
     31    else static if (is(typeof(part): ulong)) _log(Format(part)); 
    3332    //else static if (is(typeof(part): real)) _printf("%21.6Lf", cast(real) part); 
    3433    else static if (is(typeof(part): real)) _printf("%f", cast(double) part); 
     
    4544        _log(part.toString()); 
    4645      } else { 
    47         _log(typeof(part).stringof~"{ "); foreach (id, entry; part.tupleof) { if (id) _log(", "); _log(entry); } 
     46        _log(typeof(part).stringof~"{ "); 
     47        // pragma(msg, typeof(part.tupleof).stringof); 
     48        foreach (id, entry; part.tupleof) { 
     49          // pragma(msg, typeof(id).stringof, " - ", typeof(entry).stringof); 
     50          if (id) _log(", "); 
     51          _log(entry); 
     52        } 
    4853        _log(" }"); 
    4954      } 
  • trunk/tools/tools/stackthreads.d

    r385 r405  
    22import tools.stackthreads_impl, tools.log, tools.threads; 
    33 
    4 class Coroutine { 
    5   private context ctx; 
    6   void delegate(proc) dg; 
    7   proc dg2; 
    8   Exception failure; 
    9   void safe_exec() { 
    10     yield(); 
    11     try if (dg) dg(&yield); else dg2(); 
    12     catch (Exception ex) { 
    13       failure = ex; 
     4static if (enableStackthreads) { 
     5   
     6  class Coroutine { 
     7    private context ctx; 
     8    void delegate(proc) dg; 
     9    proc dg2; 
     10    Exception failure; 
     11    void safe_exec() { 
     12      yield(); 
     13      try if (dg) dg(&yield); else dg2(); 
     14      catch (Exception ex) { 
     15        failure = ex; 
     16        toMain(); 
     17        asm { int 3; } 
     18      } 
     19      yield(); 
     20      failure = new Exception("Coroutine has ended. Cannot invoke again."); 
    1421      toMain(); 
    15       asm { int 3; } 
    1622    } 
    17     yield(); 
    18     failure = new Exception("Coroutine has ended. Cannot invoke again."); 
    19     toMain(); 
     23    Coroutine other; 
     24    context** ct_p; context* main_p; 
     25    void changed_thread() { 
     26      ct_p = getActiveContextPtr(); 
     27      main_p = mainline.ptr(); 
     28    } 
     29    context* getContextPtr() { 
     30      if (*ct_p) return *ct_p; 
     31      else return main_p; 
     32    } 
     33    this(proc dg, size_t stacksize=1024*1024, Coroutine other = null) { 
     34      this.dg2 = dg; 
     35      this.other = other; 
     36      this(stacksize); 
     37    } 
     38    this(void delegate(proc) dg, size_t stacksize=1024*1024, Coroutine other = null) { 
     39      this.dg = dg; 
     40      this.other = other; 
     41      this(stacksize); 
     42    } 
     43    private this(size_t stacksize=1024*1024) { 
     44      changed_thread(); 
     45      ctx.genstack(stacksize); 
     46      ctx.run(&safe_exec, getContextPtr); 
     47    } 
     48    void yield() { 
     49      if (other) other(); 
     50      else toMain(); 
     51    } 
     52    void failcheck(string info) { 
     53      if (failure) throw new Exception(info~failure.toString()); 
     54    } 
     55    // call with origin redirection 
     56    void opCall(Coroutine other) { 
     57      this.other = other; opCall(); 
     58    } 
     59    void opCall() { 
     60      failcheck("Trying to invoke coroutine failed with "); 
     61      ctx.activate(getContextPtr); 
     62      failcheck("Coroutine failed with "); 
     63    } 
     64    void toMain() { yield_main(getContextPtr); } 
     65    void yieldToMain() { yield_main(&ctx); } 
    2066  } 
    21   Coroutine other; 
    22   context** ct_p; context* main_p; 
    23   void changed_thread() { 
    24     ct_p = getActiveContextPtr(); 
    25     main_p = mainline.ptr(); 
     67   
     68  class Source(T) { 
     69    Coroutine routine; 
     70    T res; void delegate(void delegate(T)) dg; 
     71    void run(proc yield) { dg((T t) { res = t; yield(); }); } 
     72    T opCall() { routine(); return res; } 
     73    mixin This!("dg; #New(routine, &run); "); 
    2674  } 
    27   context* getContextPtr() { 
    28     if (*ct_p) return *ct_p; 
    29     else return main_p; 
     75   
     76  class Sink(T) { 
     77    Coroutine routine; 
     78    T v; void delegate(T delegate()) dg; 
     79    void run(proc yield) { dg({ yield(); return v; }); } 
     80    void opCall(T t) { v = t; routine(); } 
     81    mixin This!("dg; #New(routine, &run); #routine(); "); 
    3082  } 
    31   this(proc dg, size_t stacksize=1024*1024, Coroutine other = null) { 
    32     this.dg2 = dg; 
    33     this.other = other
    34     this(stacksize)
     83   
     84  T delegate() source(T)(void delegate(void delegate(T)) dg) { 
     85    auto src = new Source!(T)(dg)
     86    return &src.opCall
    3587  } 
    36   this(void delegate(proc) dg, size_t stacksize=1024*1024, Coroutine other = null) { 
    37     this.dg = dg; 
    38     this.other = other
    39     this(stacksize)
     88   
     89  void delegate(T) sink(T)(void delegate(T delegate()) dg) { 
     90    auto snk = new Sink!(T)(dg)
     91    return &snk.opCall
    4092  } 
    41   private this(size_t stacksize=1024*1024) { 
    42     changed_thread(); 
    43     ctx.genstack(stacksize); 
    44     ctx.run(&safe_exec, getContextPtr); 
     93   
     94  T delegate() iterate(T)(T[] array) { 
     95    return source(array /apply/ (T[] array, void delegate(T) yield) { foreach (entry; array) yield(entry); }); 
    4596  } 
    46   void yield() { 
    47     if (other) other(); 
    48     else toMain(); 
     97   
     98  import tools.tests, tools.functional; 
     99  unittest { 
     100    logln("StackThread test"); 
     101    auto test = new Coroutine((proc yield) { 
     102      logln("This is virtual stack context!"); 
     103      yield(); 
     104      logln("Hi again. Finishing now."); 
     105    }); 
     106    logln("> This is main."); test(); 
     107    logln("> Reinvoking."); test(); 
     108    logln("> done"); 
     109    mustFail("ReinvokeTest", test()); 
     110    auto dg = ([2, 3, 4, 5]).iterate(); 
     111    mustEqual("IterTest #1", dg(), 2); mustEqual("IterTest #2", dg(), 3); 
     112    mustEqual("IterTest #3", dg(), 4); mustEqual("IterTest #4", dg(), 5); 
     113    int e; 
     114    auto dg2 = sink((int delegate() get) { while (true) e += get(); }); 
     115    dg2(2); dg2(3); dg2(4); 
     116    mustEqual("SinkTest", e, 9); 
    49117  } 
    50   void failcheck(string info) { 
    51     if (failure) throw new Exception(info~failure.toString()); 
    52   } 
    53   // call with origin redirection 
    54   void opCall(Coroutine other) { 
    55     this.other = other; opCall(); 
    56   } 
    57   void opCall() { 
    58     failcheck("Trying to invoke coroutine failed with "); 
    59     ctx.activate(getContextPtr); 
    60     failcheck("Coroutine failed with "); 
    61   } 
    62   void toMain() { yield_main(getContextPtr); } 
    63   void yieldToMain() { yield_main(&ctx); } 
    64118} 
    65  
    66 class Source(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 } 
    73  
    74 class Sink(T) { 
    75   Coroutine routine; 
    76   T v; void delegate(T delegate()) dg; 
    77   void run(proc yield) { dg({ yield(); return v; }); } 
    78   void opCall(T t) { v = t; routine(); } 
    79   mixin This!("dg; #New(routine, &run); #routine(); "); 
    80 } 
    81  
    82 T delegate() source(T)(void delegate(void delegate(T)) dg) { 
    83   auto src = new Source!(T)(dg); 
    84   return &src.opCall; 
    85 } 
    86  
    87 void delegate(T) sink(T)(void delegate(T delegate()) dg) { 
    88   auto snk = new Sink!(T)(dg); 
    89   return &snk.opCall; 
    90 } 
    91  
    92 T delegate() iterate(T)(T[] array) { 
    93   return source(array /apply/ (T[] array, void delegate(T) yield) { foreach (entry; array) yield(entry); }); 
    94 } 
    95  
    96 import tools.tests, tools.functional; 
    97 unittest { 
    98   logln("StackThread test"); 
    99   auto test = new Coroutine((proc yield) { 
    100     logln("This is virtual stack context!"); 
    101     yield(); 
    102     logln("Hi again. Finishing now."); 
    103   }); 
    104   logln("> This is main."); test(); 
    105   logln("> Reinvoking."); test(); 
    106   logln("> done"); 
    107   mustFail("ReinvokeTest", test()); 
    108   auto dg = ([2, 3, 4, 5]).iterate(); 
    109   mustEqual("IterTest #1", dg(), 2); mustEqual("IterTest #2", dg(), 3); 
    110   mustEqual("IterTest #3", dg(), 4); mustEqual("IterTest #4", dg(), 5); 
    111   int e; 
    112   auto dg2 = sink((int delegate() get) { while (true) e += get(); }); 
    113   dg2(2); dg2(3); dg2(4); 
    114   mustEqual("SinkTest", e, 9); 
    115 } 
  • trunk/tools/tools/stackthreads_impl.d

    r391 r405  
    1919 
    2020version (BigEndian) const bool enableStackthreads = false; 
     21else version (LLVM) const bool enableStackthreads = false; 
    2122else const bool enableStackthreads = true; 
    2223static if (enableStackthreads) { 
     
    9091      void *ep=&invoker.esp; 
    9192      start = esp = vstack; 
     93      void* temp_esp = esp; 
    9294      switch_gc(invoker, *this); 
    9395      bool loaded = void; 
    94       auto dg_ptr = &dg; 
     96      void* dg_ptr = &dg; 
    9597      typeof(dg_ptr) new_ptr; 
    96       // copy local stack over to new stack beforehand. 
    9798      static if (gccasm) { 
    9899        mixin(Replace!("asm { 
     
    110111        )); 
    111112      } else asm { 
    112         mov EBX, ep; mov ECX, esp; mov EDX, dg_ptr; 
     113        mov EBX, ep; mov ECX, temp_esp; mov EDX, dg_ptr; 
    113114        call set_fuckery; 
    114115        mov loaded, 0; jmp set_end; 
     
    125126      enable; 
    126127      if (!loaded) return; 
    127       (*new_ptr)(); 
     128      (*cast(typeof(dg)*)new_ptr)(); 
    128129      asm { int 3; } 
    129130    } 
  • trunk/tools/tools/threadpool.d

    r388 r405  
    2020 
    2121class Threadpool { 
    22   poolthread[] threads; 
     22  Thread[] threads; 
    2323  bool finish=false; 
    2424  MessageMultiChannel!(task, false, false) tasks; 
     
    8383    auto res=new Future!(T); 
    8484    addTask((Future!(T) fut, T delegate() _dg) { 
     85      logln("Task executing"); 
    8586      static if (is(typeof(fut.res))) fut.res = _dg(); 
    8687      else _dg(); 
     88      logln("Signalling completion"); 
    8789      fut.channel.put(true, nonblocking); 
    8890    } /fix/ stuple(res, dg)); 
     
    9193  import tools.tests; 
    9294  unittest { 
    93     logln("threadpool test"); 
    94     int test(int i, int j=10) { 
     95    logln("threadpool test - Skipped due to LLVMDC"); 
     96    /*int test(int i, int j=10) { 
     97      logln("Test of ", i, " and ", j); 
    9598      if (!j) return i; 
    9699      else return test(i*i, j-1); 
    97100    } 
    98101    auto tp = new Threadpool(2); 
     102    logln("Beginning futures .. "); 
    99103    auto fut1 = tp.future({ return test(3, 3); }), fut2 = tp.future({ return test(4, 2); }); 
    100     mustEqual("FutureTest", fut1()+fut2(), test(3, 3)+test(4, 2), 6817); 
     104    mustEqual("FutureTest", fut1()+fut2(), test(3, 3)+test(4, 2), 6817);*/ 
    101105  } 
    102106  void addTask(proc c) { addTask("Unnamed task", c); } 
     
    104108    auto thr=new poolthread(tasks, &getTask); 
    105109    thr.mainthr=mainthr; 
     110    // logln("Starting thread .. "); 
     111    thr.start; 
    106112    threadnames[thr] = "Freshling PoolThread"; 
    107     thr.start
    108     addRoot(cast(void*) thr)
    109     synchronized threads~=thr
     113    // logln("Add thr")
     114    synchronized(this) threads~=thr
     115    // logln("Meepness.")
    110116  } 
    111117  Thread mainthr=null; 
     
    136142  int run() { 
    137143    while (true) { 
     144      // logln("Thread: polling for task"); 
    138145      auto t=getTask(); 
    139146      threadnames[this] = t.name; 
     
    141148      catch (Exception e) logln("Task failed with ", e); 
    142149    } 
    143     return 0; // stupid gdc! 
     150    return 0; 
    144151  } 
    145152} 
  • trunk/tools/tools/threads.d

    r399 r405  
    185185    void* pthread_getspecific(pthread_key_t); 
    186186  } 
     187  import std.c.stdlib: cmalloc = malloc, cfree = free; 
    187188  template TLS(T) { 
    188189    final class TLS { 
     
    190191      else alias T* Ref; 
    191192      Ref delegate() maker; 
    192       pthread_key_t key; 
     193      static pthread_key_t key; 
     194      static uint last_tls_id; 
     195      uint my_tls_id; 
    193196      private Ref[] values; 
    194197      static if (is(T: Object)) void each(void delegate(T) dg) { foreach (value; values) dg(value); } 
    195198      else void each(void delegate(T) dg) { foreach (value; values) dg(*value); } 
    196       private static void check(string s, int i) { if (i) throw new Exception(s~" failed!"); } 
     199      private static void check(string s, int i) { if (i) throw new Exception(s~" failed with "~.toString(i)~"!"); } 
     200      static this() { 
     201        check("pthread_key_create", pthread_key_create(&key)); 
     202      } 
     203      void** get_key() { 
     204        auto p = pthread_getspecific(key); 
     205        if (!p) { 
     206          auto ss = (Stuple!(void**, size_t)).sizeof; 
     207          p = cmalloc(ss); 
     208          (cast(ubyte*) p)[0 .. ss] = 0; 
     209          check("init:pthread_setspecific", pthread_setspecific(key, p)); 
     210        } 
     211        auto st = cast(Stuple!(void**, size_t)*) p; 
     212        auto l = last_tls_id; 
     213        if (st._1 < l) { 
     214          if (st._0) cfree(st._0); 
     215          st._0 = cast(void**) cmalloc(4*l); 
     216          st._1 = l; 
     217        } 
     218        return &st._0[my_tls_id]; 
     219      } 
    197220      this(typeof(maker) m) { 
    198         check("pthread_key_create", pthread_key_create(&key))
     221        synchronized my_tls_id = last_tls_id ++
    199222        maker = m; 
    200223      } 
    201       void set(Ref r) { 
    202         check("set:pthread_setspecific", pthread_setspecific(key, cast(void*) r)); 
    203       } 
    204       Ref check() { return cast(Ref) cast(void*) pthread_getspecific(key); } 
     224      void set(Ref r) { *get_key = cast(void*) r; } 
     225      Ref check() { return cast(Ref) *get_key(); } 
    205226      Ref ptr() { 
    206         auto res = cast(Ref) cast(void*) pthread_getspecific(key)
     227        auto p = get_key(), res = cast(Ref) *p
    207228        if (!res) { 
    208229          res = maker(); 
    209230          synchronized(this) values ~= res; 
    210           check("pthread_setspecific", pthread_setspecific(key, cast(void*) res))
     231          *p = cast(void*) res
    211232        } 
    212233        return res; 
     
    220241        } 
    221242      } else alias ptr opCall; 
    222       ~this() { check("pthread_key_delete", pthread_key_delete(key)); } 
    223243    } 
    224244  } 
  • trunk/tools/tools/time.d

    r370 r405  
    11module tools.time; 
    2 import std.perf; 
    32 
    43import tools.log; 
     
    76alias void delegate()[] no; 
    87long time(no see...) { 
    9   auto pc=new PerformanceCounter; 
    10   pc.start; 
     8  auto start = µsec(); 
    119  foreach (dg; see) { 
    1210    dg(); 
    1311  } 
    14   pc.stop; 
    15   return pc.milliseconds; 
     12  return µsec() - start; 
    1613} 
    1714