README: document nit_env.sh
[nit.git] / lib / realtime.nit
index 960a3cb..8cfa4da 100644 (file)
@@ -10,7 +10,7 @@
 # You  are  allowed  to  redistribute it and sell it, alone or is a part of
 # another product.
 
-# Provides the Clock utility class to keep time of real time flow
+# Services to keep time of the wall clock time
 module realtime is ldflags "-lrt"
 
 in "C header" `{
@@ -21,6 +21,28 @@ in "C header" `{
 #include <time.h>
 `}
 
+in "C" `{
+
+#ifdef __MACH__
+/* OS X does not have clock_gettime, mascarade it and use clock_get_time
+ * cf http://stackoverflow.com/questions/11680461/monotonic-clock-on-osx
+*/
+#include <mach/clock.h>
+#include <mach/mach.h>
+#define CLOCK_REALTIME CALENDAR_CLOCK
+#define CLOCK_MONOTONIC SYSTEM_CLOCK
+void clock_gettime(clock_t clock_name, struct timespec *ts) {
+       clock_serv_t cclock;
+       mach_timespec_t mts;
+       host_get_clock_service(mach_host_self(), clock_name, &cclock);
+       clock_get_time(cclock, &mts);
+       mach_port_deallocate(mach_task_self(), cclock);
+       ts->tv_sec = mts.tv_sec;
+       ts->tv_nsec = mts.tv_nsec;
+}
+#endif
+`}
+
 # Elapsed time representation.
 extern class Timespec `{struct timespec*`}
 
@@ -72,8 +94,23 @@ extern class Timespec `{struct timespec*`}
                return self->tv_nsec;
        `}
 
-       # Seconds in Float
-       # Loss of precision but great to print
+       # Elapsed time in microseconds, with both whole seconds and the rest
+       #
+       # May cause an `Int` overflow, use only with a low number of seconds.
+       fun microsec: Int `{
+               return self->tv_sec*1000000 + self->tv_nsec/1000;
+       `}
+
+       # Elapsed time in milliseconds, with both whole seconds and the rest
+       #
+       # May cause an `Int` overflow, use only with a low number of seconds.
+       fun millisec: Int `{
+               return self->tv_sec*1000 + self->tv_nsec/1000000;
+       `}
+
+       # 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
 
        redef fun to_s do return "{to_f}s"
@@ -90,7 +127,18 @@ class Clock
        # Smallest time frame reported by clock
        fun resolution : Timespec `{
                struct timespec* tv = malloc( sizeof(struct timespec) );
+#ifdef __MACH__
+               clock_serv_t cclock;
+               int nsecs;
+               mach_msg_type_number_t count;
+               host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
+               clock_get_attributes(cclock, CLOCK_GET_TIME_RES, (clock_attr_t)&nsecs, &count);
+               mach_port_deallocate(mach_task_self(), cclock);
+               tv->tv_sec = 0;
+               tv->tv_nsec = nsecs;
+#else
                clock_getres( CLOCK_MONOTONIC, tv );
+#endif
                return tv;
        `}