in "C" `{
-#ifdef __MACH__
+#if defined(__MACH__) && !defined(CLOCK_REALTIME)
/* OS X does not have clock_gettime, mascarade it and use clock_get_time
* cf http://stackoverflow.com/questions/11680461/monotonic-clock-on-osx
*/
`}
# Subtract `other` from `self`
- fun -(other: Timespec): Timespec
- do
- var s = sec - other.sec
- var ns = nanosec - other.nanosec
- if ns < 0 then
- s -= 1
- ns += 1000000000
- end
- return new Timespec(s, ns)
- end
+ fun -(other: Timespec): Timespec `{
+ time_t s = self->tv_sec - other->tv_sec;
+ long ns = self->tv_nsec - other->tv_nsec;
+ if (ns < 0) {
+ s -= 1;
+ ns += 1000000000l;
+ }
+ struct timespec* tv = malloc(sizeof(struct timespec));
+ tv->tv_sec = s; tv->tv_nsec = ns;
+ return tv;
+ `}
# Number of whole seconds of elapsed time.
fun sec : Int `{
# Number of seconds as a `Float`
#
# Incurs a loss of precision, but the result is pretty to print.
- fun to_f: Float do return sec.to_f + nanosec.to_f / 1000000000.0
+ fun to_f: Float `{
+ return (double)self->tv_sec + 0.000000001 * self->tv_nsec;
+ `}
redef fun to_s do return "{to_f}s"
end
# Keeps track of real time
+#
+# ~~~
+# var clock = new Clock
+#
+# # sleeping at least 1s
+# 1.0.sleep
+# assert clock.total >= 1.0
+# assert clock.lapse >= 1.0
+#
+# # sleeping at least 5ms
+# 0.005.sleep
+# assert clock.total >= 1.005
+# assert clock.lapse >= 0.005
+# ~~~
class Clock
- # Time at instanciation
+ super FinalizableOnce
+
+ # TODO use less mallocs
+
+ # Time at creation
protected var time_at_beginning = new Timespec.monotonic_now
# Time at last time a lapse method was called
protected var time_at_last_lapse = new Timespec.monotonic_now
# Smallest time frame reported by clock
- fun resolution : Timespec `{
+ fun resolution: Timespec `{
struct timespec* tv = malloc( sizeof(struct timespec) );
-#ifdef __MACH__
+#if defined(__MACH__) && !defined(CLOCK_REALTIME)
clock_serv_t cclock;
int nsecs;
mach_msg_type_number_t count;
return tv;
`}
- # Return timelapse since instanciation of this instance
- fun total : Timespec
+ # Seconds since the creation of this instance
+ fun total: Float
do
- return new Timespec.monotonic_now - time_at_beginning
+ var now = new Timespec.monotonic_now
+ var diff = now - time_at_beginning
+ var r = diff.to_f
+ diff.free
+ now.free
+ return r
end
- # Return timelapse since last call to lapse
- fun lapse : Timespec
+ # Seconds since the last call to `lapse`
+ fun lapse: Float
do
var nt = new Timespec.monotonic_now
var dt = nt - time_at_last_lapse
+ var r = dt.to_f
+ dt.free
+ time_at_last_lapse.free
time_at_last_lapse = nt
- return dt
+ return r
end
# Seconds since the last call to `lapse`, without resetting the lapse counter
dt.free
return r
end
+
+ redef fun finalize_once
+ do
+ time_at_beginning.free
+ time_at_last_lapse.free
+ end
end