lib/realtime: intro micro|millisec
[nit.git] / lib / realtime.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # This file is free software, which comes along with NIT. This software is
6 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 # is kept unaltered, and a notification of the changes is added.
10 # You are allowed to redistribute it and sell it, alone or is a part of
11 # another product.
12
13 # Provides the Clock utility class to keep time of real time flow
14 module realtime is ldflags "-lrt"
15
16 in "C header" `{
17 #ifdef _POSIX_C_SOURCE
18 #undef _POSIX_C_SOURCE
19 #endif
20 #define _POSIX_C_SOURCE 199309L
21 #include <time.h>
22 `}
23
24 # Elapsed time representation.
25 extern class Timespec `{struct timespec*`}
26
27 # Init a new Timespec from `s` seconds and `ns` nanoseconds.
28 new ( s, ns : Int ) `{
29 struct timespec* tv = malloc( sizeof(struct timespec) );
30 tv->tv_sec = s; tv->tv_nsec = ns;
31 return tv;
32 `}
33
34 # Init a new Timespec from now.
35 new monotonic_now `{
36 struct timespec* tv = malloc( sizeof(struct timespec) );
37 clock_gettime( CLOCK_MONOTONIC, tv );
38 return tv;
39 `}
40
41 # Init a new Timespec copied from another.
42 new copy_of( other : Timespec ) `{
43 struct timespec* tv = malloc( sizeof(struct timespec) );
44 tv->tv_sec = other->tv_sec;
45 tv->tv_nsec = other->tv_nsec;
46 return tv;
47 `}
48
49 # Update `self` clock.
50 fun update `{
51 clock_gettime(CLOCK_MONOTONIC, self);
52 `}
53
54 # Substract a Timespec from `self`.
55 fun - ( o : Timespec ) : Timespec
56 do
57 var s = sec - o.sec
58 var ns = nanosec - o.nanosec
59 if ns > nanosec then s += 1
60 return new Timespec( s, ns )
61 end
62
63 # Number of whole seconds of elapsed time.
64 fun sec : Int `{
65 return self->tv_sec;
66 `}
67
68 # Rest of the elapsed time (a fraction of a second).
69 #
70 # Number of nanoseconds.
71 fun nanosec : Int `{
72 return self->tv_nsec;
73 `}
74
75 # Elapsed time in microseconds, with both whole seconds and the rest
76 #
77 # May cause an `Int` overflow, use only with a low number of seconds.
78 fun microsec: Int `{
79 return self->tv_sec*1000000 + self->tv_nsec/1000;
80 `}
81
82 # Elapsed time in milliseconds, with both whole seconds and the rest
83 #
84 # May cause an `Int` overflow, use only with a low number of seconds.
85 fun millisec: Int `{
86 return self->tv_sec*1000 + self->tv_nsec/1000000;
87 `}
88
89 # Number of seconds as a `Float`
90 #
91 # Incurs a loss of precision, but the result is pretty to print.
92 fun to_f: Float do return sec.to_f + nanosec.to_f / 1000000000.0
93
94 redef fun to_s do return "{to_f}s"
95 end
96
97 # Keeps track of real time
98 class Clock
99 # Time at instanciation
100 protected var time_at_beginning = new Timespec.monotonic_now
101
102 # Time at last time a lapse method was called
103 protected var time_at_last_lapse = new Timespec.monotonic_now
104
105 # Smallest time frame reported by clock
106 fun resolution : Timespec `{
107 struct timespec* tv = malloc( sizeof(struct timespec) );
108 clock_getres( CLOCK_MONOTONIC, tv );
109 return tv;
110 `}
111
112 # Return timelapse since instanciation of this instance
113 fun total : Timespec
114 do
115 return new Timespec.monotonic_now - time_at_beginning
116 end
117
118 # Return timelapse since last call to lapse
119 fun lapse : Timespec
120 do
121 var nt = new Timespec.monotonic_now
122 var dt = nt - time_at_last_lapse
123 time_at_last_lapse = nt
124 return dt
125 end
126 end