about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-06-28 17:58:44 -0700
committerEric Holk <eholk@mozilla.com>2011-06-30 11:32:10 -0700
commitb4a145e60f4bbc90dc780239cc49c024b9f52ca8 (patch)
tree020734b92aa7fea2269b3915d45d1d9730c4192c
parent441c7e06109772f7ff942682fb6d0a7535f03666 (diff)
downloadrust-b4a145e60f4bbc90dc780239cc49c024b9f52ca8.tar.gz
rust-b4a145e60f4bbc90dc780239cc49c024b9f52ca8.zip
Added a nanosecond timer to time.rs, support for some floating point casts, and a commandline-driven mode for pfib.rs
-rw-r--r--src/comp/middle/trans.rs17
-rw-r--r--src/lib/time.rs13
-rw-r--r--src/rt/rust_builtin.cpp6
-rw-r--r--src/rt/rustrt.def.in1
-rw-r--r--src/rt/sync/timer.cpp15
-rw-r--r--src/rt/sync/timer.h3
-rw-r--r--src/test/bench/shootout/pfib.rs71
7 files changed, 94 insertions, 32 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index c14938a5b61..01ae30bf4e1 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -5113,7 +5113,22 @@ fn trans_cast(&@block_ctxt cx, &@ast::expr e, ast::node_id id) -> result {
                     int_cast(e_res.bcx, lldsttype, llsrctype, e_res.val,
                              ty::type_is_signed(cx.fcx.lcx.ccx.tcx, t)));
         }
-    } else { cx.fcx.lcx.ccx.sess.unimpl("fp cast"); }
+    } 
+    else { 
+        if (ty::type_is_integral(cx.fcx.lcx.ccx.tcx,
+                                 ty::expr_ty(cx.fcx.lcx.ccx.tcx, e))) {
+            if (ty::type_is_signed(cx.fcx.lcx.ccx.tcx,
+                                   ty::expr_ty(cx.fcx.lcx.ccx.tcx, e))) {
+                e_res = rslt(e_res.bcx,
+                             e_res.bcx.build.SIToFP(e_res.val, lldsttype));
+            }
+            else {
+                e_res = rslt(e_res.bcx,
+                             e_res.bcx.build.UIToFP(e_res.val, lldsttype));
+            }
+        }
+        else { cx.fcx.lcx.ccx.sess.unimpl("fp cast"); }
+    }
     ret e_res;
 }
 
diff --git a/src/lib/time.rs b/src/lib/time.rs
index 65d02616294..d2c61b74e98 100644
--- a/src/lib/time.rs
+++ b/src/lib/time.rs
@@ -2,6 +2,7 @@
 
 native "rust" mod rustrt {
     fn get_time(&mutable u32 sec, &mutable u32 usec);
+    fn nano_time(&mutable u64 ns);
 }
 
 type timeval = rec(u32 sec, u32 usec);
@@ -11,4 +12,14 @@ fn get_time() -> timeval {
     auto usec = 0u32;
     rustrt::get_time(sec, usec);
     ret rec(sec=sec, usec=usec);
-}
\ No newline at end of file
+}
+
+fn precise_time_ns() -> u64 {
+    auto ns = 0u64;
+    rustrt::nano_time(ns);
+    ret ns;
+}
+
+fn precise_time_s() -> float {
+    ret (precise_time_ns() as float) / 1000000000.;
+}
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 5b5844fc135..0ccc83435f7 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -612,6 +612,12 @@ get_time(rust_task *task, uint32_t *sec, uint32_t *usec) {
 }
 #endif
 
+extern "C" CDECL void
+nano_time(rust_task *task, uint64_t *ns) {
+    timer t;
+    *ns = t.nano_time();
+}
+
 /**
  * Preallocates the exact number of bytes in the given interior vector.
  */
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 38c51513190..444faccef26 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -15,6 +15,7 @@ ivec_on_heap
 ivec_reserve
 ivec_to_ptr
 last_os_error
+nano_time
 pin_task
 unpin_task
 rand_free
diff --git a/src/rt/sync/timer.cpp b/src/rt/sync/timer.cpp
index e6fe3688893..3af441c3950 100644
--- a/src/rt/sync/timer.cpp
+++ b/src/rt/sync/timer.cpp
@@ -9,7 +9,7 @@ timer::timer() {
 #if __WIN32__
     uint64_t ticks_per_second;
     QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second);
-    _ticks_per_us = ticks_per_second / 1000000;
+    _ticks_per_ns = ticks_per_second / 1000;
 #endif
     reset(0);
 }
@@ -41,7 +41,7 @@ timer::has_timed_out() {
 }
 
 uint64_t
-timer::get_time() {
+timer::nano_time() {
 #ifdef __APPLE__
     uint64_t time = mach_absolute_time();
     mach_timebase_info_data_t info = {0, 0};
@@ -49,18 +49,23 @@ timer::get_time() {
         mach_timebase_info(&info);
     }
     uint64_t time_nano = time * (info.numer / info.denom);
-    return time_nano / 1000;
+    return time_nano;
 #elif __WIN32__
     uint64_t ticks;
     QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
-    return ticks / _ticks_per_us;
+    return ticks / _ticks_per_ns;
 #else
     timespec ts;
     clock_gettime(CLOCK_MONOTONIC, &ts);
-    return (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
+    return (ts.tv_sec * 1000000000LL + ts.tv_nsec);
 #endif
 }
 
+uint64_t
+timer::get_time() {
+    return nano_time() / 1000;
+}
+
 timer::~timer() {
     // Nop.
 }
diff --git a/src/rt/sync/timer.h b/src/rt/sync/timer.h
index aae098a1119..6d833396cf9 100644
--- a/src/rt/sync/timer.h
+++ b/src/rt/sync/timer.h
@@ -11,7 +11,7 @@ private:
     uint64_t _timeout;
     uint64_t get_time();
 #if __WIN32__
-    uint64_t _ticks_per_us;
+    uint64_t _ticks_per_ns;
 #endif
 public:
     timer();
@@ -20,6 +20,7 @@ public:
     double get_elapsed_time_in_ms();
     int64_t get_timeout();
     bool has_timed_out();
+    uint64_t nano_time();
     virtual ~timer();
 };
 
diff --git a/src/test/bench/shootout/pfib.rs b/src/test/bench/shootout/pfib.rs
index f7fda8b8110..cbe0813efc4 100644
--- a/src/test/bench/shootout/pfib.rs
+++ b/src/test/bench/shootout/pfib.rs
@@ -4,38 +4,61 @@
   A parallel version of fibonacci numbers.
 */
 
+use std;
+
+import std::vec;
+import std::uint;
+import std::time;
+import std::str;
+
 fn recv[T](&port[T] p) -> T {
-  let T x;
-  p |> x;
-  ret x;
+    let T x;
+    p |> x;
+    ret x;
 }
 
 fn fib(int n) -> int {
-  fn pfib(chan[int] c, int n) {
-    if (n == 0) {
-      c <| 0;
-    }
-    else if (n <= 2) {
-      c <| 1;
-    }
-    else {
-      let port[int] p = port();
+    fn pfib(chan[int] c, int n) {
+        if (n == 0) {
+            c <| 0;
+        }
+        else if (n <= 2) {
+            c <| 1;
+        }
+        else {
+            let port[int] p = port();
       
-      auto t1 = spawn pfib(chan(p), n - 1);
-      auto t2 = spawn pfib(chan(p), n - 2);
+            auto t1 = spawn pfib(chan(p), n - 1);
+            auto t2 = spawn pfib(chan(p), n - 2);
 
-      c <| recv(p) + recv(p);
+            c <| recv(p) + recv(p);
+        }
     }
-  }
 
-  let port[int] p = port();
-  auto t = spawn pfib(chan(p), n);
-  ret recv(p);
+    let port[int] p = port();
+    auto t = spawn pfib(chan(p), n);
+    ret recv(p);
 }
 
-fn main() {
-  assert (fib(8) == 21);
-  assert (fib(15) == 610);
-  log fib(8);
-  log fib(15);
+fn main(vec[str] argv) {
+    if(vec::len(argv) == 1u) {
+        assert (fib(8) == 21);
+        assert (fib(15) == 610);
+        log fib(8);
+        log fib(15);
+    }
+    else {
+        // Interactive mode! Wooo!!!!
+
+        auto n = uint::parse_buf(str::bytes(argv.(1)), 10u) as int;
+        auto start = time::precise_time_ns();
+        auto fibn = fib(n);
+        auto stop = time::precise_time_ns();
+
+        auto elapsed = (stop - start) as int;
+        auto us_task = elapsed / fibn / 1000; 
+
+        log_err #fmt("Determined that fib(%d) = %d in %d ns (%d us / task)",
+                     n, fibn, elapsed, us_task);
+    }
 }