hitimes 1.0.4-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/HISTORY +60 -0
  2. data/LICENSE +13 -0
  3. data/README +134 -0
  4. data/Rakefile +66 -0
  5. data/examples/benchmarks.rb +113 -0
  6. data/examples/stats.rb +31 -0
  7. data/ext/hitimes/extconf.rb +17 -0
  8. data/ext/hitimes/hitimes_ext.c +21 -0
  9. data/ext/hitimes/hitimes_instant_clock_gettime.c +28 -0
  10. data/ext/hitimes/hitimes_instant_osx.c +16 -0
  11. data/ext/hitimes/hitimes_instant_windows.c +27 -0
  12. data/ext/hitimes/hitimes_interval.c +362 -0
  13. data/ext/hitimes/hitimes_interval.h +73 -0
  14. data/ext/hitimes/hitimes_stats.c +269 -0
  15. data/ext/hitimes/hitimes_stats.h +30 -0
  16. data/gemspec.rb +60 -0
  17. data/lib/hitimes.rb +31 -0
  18. data/lib/hitimes/1.8/hitimes_ext.so +0 -0
  19. data/lib/hitimes/1.9/hitimes_ext.so +0 -0
  20. data/lib/hitimes/metric.rb +112 -0
  21. data/lib/hitimes/mutexed_stats.rb +28 -0
  22. data/lib/hitimes/paths.rb +53 -0
  23. data/lib/hitimes/stats.rb +54 -0
  24. data/lib/hitimes/timed_metric.rb +177 -0
  25. data/lib/hitimes/timed_value_metric.rb +235 -0
  26. data/lib/hitimes/value_metric.rb +72 -0
  27. data/lib/hitimes/version.rb +57 -0
  28. data/spec/interval_spec.rb +133 -0
  29. data/spec/metric_spec.rb +30 -0
  30. data/spec/mutex_stats_spec.rb +34 -0
  31. data/spec/paths_spec.rb +13 -0
  32. data/spec/spec_helper.rb +5 -0
  33. data/spec/stats_spec.rb +100 -0
  34. data/spec/timed_metric_spec.rb +155 -0
  35. data/spec/timed_value_metric_spec.rb +172 -0
  36. data/spec/value_metric_spec.rb +110 -0
  37. data/spec/version_spec.rb +33 -0
  38. data/tasks/announce.rake +42 -0
  39. data/tasks/config.rb +108 -0
  40. data/tasks/distribution.rake +77 -0
  41. data/tasks/documentation.rake +32 -0
  42. data/tasks/extension.rake +92 -0
  43. data/tasks/rspec.rake +31 -0
  44. data/tasks/rubyforge.rake +55 -0
  45. data/tasks/utils.rb +80 -0
  46. metadata +150 -0
@@ -0,0 +1,28 @@
1
+ #ifdef USE_INSTANT_CLOCK_GETTIME
2
+
3
+ #include "hitimes_interval.h"
4
+
5
+ #include <time.h>
6
+ #ifndef CLOCK_MONOTONIC
7
+ # include <sys/time.h>
8
+ # ifndef CLOCK_MONOTONIC
9
+ # ifdef __linux__
10
+ # include <linux/time.h>
11
+ # endif
12
+ # endif
13
+ #endif
14
+
15
+ hitimes_instant_t hitimes_get_current_instant( )
16
+ {
17
+ struct timespec time;
18
+ int rc;
19
+
20
+ rc = clock_gettime( CLOCK_MONOTONIC, &time);
21
+ if ( 0 != rc ) {
22
+ char* e = strerror( rc );
23
+ rb_raise(eH_Error, "Unable to retrieve time for CLOCK_MONOTONIC : %s", e );
24
+ }
25
+
26
+ return ( ( NANOSECONDS_PER_SECOND * (long)time.tv_sec ) + time.tv_nsec );
27
+ }
28
+ #endif
@@ -0,0 +1,16 @@
1
+ #ifdef USE_INSTANT_OSX
2
+
3
+ #include "hitimes_interval.h"
4
+ #include <CoreServices/CoreServices.h>
5
+
6
+ /*
7
+ * returns the number of nanoseconds since the machine was booted
8
+ */
9
+ hitimes_instant_t hitimes_get_current_instant( )
10
+ {
11
+ Nanoseconds nano = AbsoluteToNanoseconds( UpTime() );
12
+
13
+ return *( hitimes_instant_t *)&nano;
14
+ }
15
+
16
+ #endif
@@ -0,0 +1,27 @@
1
+ #ifdef USE_INSTANT_WINDOWS
2
+
3
+ #include "hitimes_interval.h"
4
+
5
+
6
+ /*
7
+ * returns the conversion factor, this value is used to convert
8
+ * the value from hitimes_get_current_instant() into seconds
9
+ */
10
+ long double hitimes_instant_conversion_factor()
11
+ {
12
+ LARGE_INTEGER ticks_per_second;
13
+ QueryPerformanceFrequency( &ticks_per_second );
14
+ return (double)ticks_per_second.QuadPart;
15
+ }
16
+
17
+ /*
18
+ * returns the number of ticks
19
+ */
20
+ hitimes_instant_t hitimes_get_current_instant()
21
+ {
22
+ LARGE_INTEGER tick;
23
+ QueryPerformanceCounter(&tick);
24
+ return (hitimes_instant_t)tick.QuadPart;
25
+ }
26
+
27
+ #endif
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Copyright (c) 2008 Jeremy Hinegardner
3
+ * All rights reserved. See LICENSE and/or COPYING for details.
4
+ *
5
+ * vim: shiftwidth=4
6
+ */
7
+
8
+ #include "hitimes_interval.h"
9
+
10
+ /* Modules and Classes -- defined here */
11
+ VALUE cH_Interval; /* class Hitimes::Interval */
12
+
13
+ /**
14
+ * Allocator and Deallocator for Interval classes
15
+ */
16
+
17
+ VALUE hitimes_interval_free(hitimes_interval_t* i)
18
+ {
19
+ xfree( i );
20
+ return Qnil;
21
+ }
22
+
23
+ VALUE hitimes_interval_alloc(VALUE klass)
24
+ {
25
+ VALUE obj;
26
+ hitimes_interval_t* i = xmalloc( sizeof( hitimes_interval_t ) );
27
+
28
+ i->start_instant = 0L;
29
+ i->stop_instant = 0L;
30
+ i->duration = -1.0l;
31
+
32
+ obj = Data_Wrap_Struct(klass, NULL, hitimes_interval_free, i);
33
+ return obj;
34
+ }
35
+
36
+ /**
37
+ * call-seq:
38
+ * Interval.now -> Interval
39
+ *
40
+ * Create an interval that has already started
41
+ */
42
+ VALUE hitimes_interval_now( VALUE self )
43
+ {
44
+ VALUE obj;
45
+ hitimes_interval_t *i = xmalloc( sizeof( hitimes_interval_t ) );
46
+
47
+ i->start_instant = hitimes_get_current_instant( );
48
+ i->stop_instant = 0L;
49
+ i->duration = -1.0l;
50
+
51
+ obj = Data_Wrap_Struct(cH_Interval, NULL, hitimes_interval_free, i);
52
+
53
+ return obj;
54
+ }
55
+
56
+ /**
57
+ * call-seq:
58
+ * Interval.measure { } -> Float
59
+ *
60
+ * Times the execution of the block returning the number of seconds it took
61
+ */
62
+ VALUE hitimes_interval_measure( VALUE self )
63
+ {
64
+ hitimes_instant_t before;
65
+ hitimes_instant_t after;
66
+ long double duration;
67
+
68
+ if ( !rb_block_given_p() ) {
69
+ rb_raise(eH_Error, "No block given to Interval.measure" );
70
+ }
71
+
72
+ before = hitimes_get_current_instant( );
73
+ rb_yield( Qnil );
74
+ after = hitimes_get_current_instant( );
75
+
76
+ duration = ( after - before ) / HITIMES_INSTANT_CONVERSION_FACTOR;
77
+ return rb_float_new( duration );
78
+ }
79
+
80
+ /**
81
+ * call-seq:
82
+ * interval.split -> Interval
83
+ *
84
+ * Immediately stop the current interval and start a new interval that has a
85
+ * start_instant equivalent to the stop_interval of self.
86
+ */
87
+ VALUE hitimes_interval_split( VALUE self )
88
+ {
89
+ hitimes_interval_t *first;
90
+ hitimes_interval_t *second = xmalloc( sizeof( hitimes_interval_t ) );
91
+ VALUE obj;
92
+
93
+ Data_Get_Struct( self, hitimes_interval_t, first );
94
+ first->stop_instant = hitimes_get_current_instant( );
95
+
96
+ second->start_instant = first->stop_instant;
97
+ second->stop_instant = 0L;
98
+ second->duration = -1.0l;
99
+
100
+ obj = Data_Wrap_Struct(cH_Interval, NULL, hitimes_interval_free, second);
101
+
102
+ return obj;
103
+ }
104
+
105
+
106
+ /**
107
+ * call-seq:
108
+ * interval.start -> boolean
109
+ *
110
+ * mark the start of the interval. Calling start on an already started
111
+ * interval has no effect. An interval can only be started once. If the
112
+ * interval is truely started +true+ is returned otherwise +false+.
113
+ */
114
+ VALUE hitimes_interval_start( VALUE self )
115
+ {
116
+ hitimes_interval_t *i;
117
+ VALUE rc = Qfalse;
118
+
119
+ Data_Get_Struct( self, hitimes_interval_t, i );
120
+ if ( 0L == i->start_instant ) {
121
+ i->start_instant = hitimes_get_current_instant( );
122
+ i->stop_instant = 0L;
123
+ i->duration = -1.0l;
124
+
125
+ rc = Qtrue;
126
+ }
127
+
128
+ return rc;
129
+ }
130
+
131
+
132
+ /**
133
+ * call-seq:
134
+ * interval.stop -> bool or Float
135
+ *
136
+ * mark the stop of the interval. Calling stop on an already stopped interval
137
+ * has no effect. An interval can only be stopped once. If the interval is
138
+ * truely stopped then the duration is returned, otherwise +false+.
139
+ */
140
+ VALUE hitimes_interval_stop( VALUE self )
141
+ {
142
+ hitimes_interval_t *i;
143
+ VALUE rc = Qfalse;
144
+
145
+ Data_Get_Struct( self, hitimes_interval_t, i );
146
+ if ( 0L == i->start_instant ) {
147
+ rb_raise(eH_Error, "Attempt to stop an interval that has not started.\n" );
148
+ }
149
+
150
+ if ( 0L == i->stop_instant ) {
151
+ i->stop_instant = hitimes_get_current_instant( );
152
+ i->duration = ( i->stop_instant - i->start_instant ) / HITIMES_INSTANT_CONVERSION_FACTOR;
153
+ rc = rb_float_new( i->duration );
154
+ }
155
+
156
+ return rc;
157
+ }
158
+
159
+ /**
160
+ * call-seq:
161
+ * interval.duration_so_far -> Float or false
162
+ *
163
+ * return how the duration so far. This will return the duration from the time
164
+ * the Interval was started if the interval is running, otherwise it will return
165
+ * false.
166
+ */
167
+ VALUE hitimes_interval_duration_so_far( VALUE self )
168
+ {
169
+ hitimes_interval_t *i;
170
+ VALUE rc = Qfalse;
171
+
172
+ Data_Get_Struct( self, hitimes_interval_t, i );
173
+ if ( 0L == i->start_instant ) {
174
+ return rc;
175
+ }
176
+
177
+ if ( 0L == i->stop_instant ) {
178
+ long double d;
179
+ hitimes_instant_t now = hitimes_get_current_instant( );
180
+ d = ( now - i->start_instant ) / HITIMES_INSTANT_CONVERSION_FACTOR;
181
+ rc = rb_float_new( d );
182
+ }
183
+ return rc;
184
+ }
185
+
186
+
187
+ /**
188
+ * call-seq:
189
+ * interval.started? -> boolean
190
+ *
191
+ * returns whether or not the interval has been started
192
+ */
193
+ VALUE hitimes_interval_started( VALUE self )
194
+ {
195
+ hitimes_interval_t *i;
196
+
197
+ Data_Get_Struct( self, hitimes_interval_t, i );
198
+
199
+ return ( 0L == i->start_instant ) ? Qfalse : Qtrue;
200
+ }
201
+
202
+
203
+ /**
204
+ * call-seq:
205
+ * interval.stopped? -> boolean
206
+ *
207
+ * returns whether or not the interval has been stopped
208
+ */
209
+ VALUE hitimes_interval_stopped( VALUE self )
210
+ {
211
+ hitimes_interval_t *i;
212
+
213
+ Data_Get_Struct( self, hitimes_interval_t, i );
214
+
215
+ return ( 0L == i->stop_instant ) ? Qfalse : Qtrue;
216
+ }
217
+
218
+ /**
219
+ * call-seq:
220
+ * interval.running? -> boolean
221
+ *
222
+ * returns whether or not the interval is running or not. This means that it
223
+ * has started, but not stopped.
224
+ */
225
+ VALUE hitimes_interval_running( VALUE self )
226
+ {
227
+ hitimes_interval_t *i;
228
+ VALUE rc = Qfalse;
229
+
230
+ Data_Get_Struct( self, hitimes_interval_t, i );
231
+ if ( ( 0L != i->start_instant ) && ( 0L == i->stop_instant ) ) {
232
+ rc = Qtrue;
233
+ }
234
+
235
+ return rc;
236
+ }
237
+
238
+
239
+ /**
240
+ * call-seq:
241
+ * interval.start_instant -> Integer
242
+ *
243
+ * The integer representing the start instant of the Interval. This value
244
+ * is not useful on its own. It is a platform dependent value.
245
+ */
246
+ VALUE hitimes_interval_start_instant( VALUE self )
247
+ {
248
+ hitimes_interval_t *i;
249
+
250
+ Data_Get_Struct( self, hitimes_interval_t, i );
251
+
252
+ return ULL2NUM( i->start_instant );
253
+ }
254
+
255
+
256
+ /**
257
+ * call-seq:
258
+ * interval.stop_instant -> Integer
259
+ *
260
+ * The integer representing the stop instant of the Interval. This value
261
+ * is not useful on its own. It is a platform dependent value.
262
+ */
263
+ VALUE hitimes_interval_stop_instant( VALUE self )
264
+ {
265
+ hitimes_interval_t *i;
266
+
267
+ Data_Get_Struct( self, hitimes_interval_t, i );
268
+
269
+ return ULL2NUM( i->stop_instant );
270
+ }
271
+
272
+
273
+
274
+ /**
275
+ * call-seq:
276
+ * interval.duration -> Float
277
+ * interval.to_f -> Float
278
+ * interval.to_seconds -> Float
279
+ * interval.length -> Float
280
+ *
281
+ * Returns the Float value of the interval, the value is in seconds. If the
282
+ * interval has not had stop called yet, it will report the number of seconds
283
+ * in the interval up to the current point in time.
284
+ */
285
+ VALUE hitimes_interval_duration ( VALUE self )
286
+ {
287
+ hitimes_interval_t *i;
288
+
289
+ Data_Get_Struct( self, hitimes_interval_t, i );
290
+
291
+ /**
292
+ * if stop has not yet been called, then return the amount of time so far
293
+ */
294
+ if ( 0L == i->stop_instant ) {
295
+ long double d;
296
+ hitimes_instant_t now = hitimes_get_current_instant( );
297
+ d = ( now - i->start_instant ) / HITIMES_INSTANT_CONVERSION_FACTOR;
298
+ return rb_float_new( d );
299
+ }
300
+
301
+ /*
302
+ * stop has been called, calculate the duration and save the result
303
+ */
304
+ if ( i->duration < 0.0 ) {
305
+ i->duration = ( i->stop_instant - i->start_instant ) / HITIMES_INSTANT_CONVERSION_FACTOR;
306
+ }
307
+
308
+ return rb_float_new( i->duration );
309
+ }
310
+
311
+
312
+ /**
313
+ * Document-class: Hitimes::Interval
314
+ *
315
+ * This is the lowest level timing mechanism available. It allows for easy
316
+ * measuring based upon a block:
317
+ *
318
+ * duration = Interval.measure { ... }
319
+ *
320
+ * Or measuring something specifically
321
+ *
322
+ * interval = Interval.new
323
+ * interval.start
324
+ * duration = interval.stop
325
+ *
326
+ * Allocating and starting an interval can be done in one method call with
327
+ *
328
+ * interval = Interval.now
329
+ *
330
+ * Interval is useful when you only need to track a single interval of time, or
331
+ * if you do not want to track statistics about an operation.
332
+ *
333
+ */
334
+ void Init_hitimes_interval()
335
+ {
336
+ mH = rb_define_module("Hitimes");
337
+
338
+ cH_Interval = rb_define_class_under( mH, "Interval", rb_cObject );
339
+ rb_define_alloc_func( cH_Interval, hitimes_interval_alloc );
340
+
341
+ rb_define_module_function( cH_Interval, "now", hitimes_interval_now, 0 ); /* in hitimes_interval.c */
342
+ rb_define_module_function( cH_Interval, "measure", hitimes_interval_measure, 0 ); /* in hitimes_interval.c */
343
+
344
+ rb_define_method( cH_Interval, "duration", hitimes_interval_duration, 0 ); /* in hitimes_interval.c */
345
+ rb_define_method( cH_Interval, "length", hitimes_interval_duration, 0 );
346
+ rb_define_method( cH_Interval, "to_f", hitimes_interval_duration, 0 );
347
+ rb_define_method( cH_Interval, "to_seconds", hitimes_interval_duration, 0 );
348
+
349
+ rb_define_method( cH_Interval, "duration_so_far", hitimes_interval_duration_so_far, 0); /* in hitimes_interval.c */
350
+
351
+ rb_define_method( cH_Interval, "started?", hitimes_interval_started, 0 ); /* in hitimes_interval.c */
352
+ rb_define_method( cH_Interval, "running?", hitimes_interval_running, 0 ); /* in hitimes_interval.c */
353
+ rb_define_method( cH_Interval, "stopped?", hitimes_interval_stopped, 0 ); /* in hitimes_interval.c */
354
+
355
+ rb_define_method( cH_Interval, "start_instant", hitimes_interval_start_instant, 0 ); /* in hitimes_interval.c */
356
+ rb_define_method( cH_Interval, "stop_instant", hitimes_interval_stop_instant, 0 ); /* in hitimes_interval.c */
357
+
358
+ rb_define_method( cH_Interval, "start", hitimes_interval_start, 0); /* in hitimes_interval.c */
359
+ rb_define_method( cH_Interval, "stop", hitimes_interval_stop, 0); /* in hitimes_interval.c */
360
+ rb_define_method( cH_Interval, "split", hitimes_interval_split, 0); /* in hitimes_interval.c */
361
+
362
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Copyright (c) 2008 Jeremy Hinegardner
3
+ * All rights reserved. See LICENSE and/or COPYING for details.
4
+ *
5
+ * vim: shiftwidth=4
6
+ */
7
+
8
+ #ifndef __HITIMES_INTERVAL_H__
9
+ #define __HITIMES_INTERVAL_H__
10
+
11
+ #include <ruby.h>
12
+
13
+ #define NANOSECONDS_PER_SECOND 1e9l
14
+
15
+ #ifdef USE_INSTANT_CLOCK_GETTIME
16
+ # define HITIMES_U64INT unsigned long long int
17
+ # define HITIMES_INSTANT_CONVERSION_FACTOR 1e9l
18
+ #elif USE_INSTANT_OSX
19
+ # define HITIMES_U64INT unsigned long long int
20
+ # define HITIMES_INSTANT_CONVERSION_FACTOR 1e9l
21
+ #elif USE_INSTANT_WINDOWS
22
+ # define HITIMES_U64INT unsigned __int64
23
+ # define HITIMES_INSTANT_CONVERSION_FACTOR hitimes_instant_conversion_factor()
24
+ #else
25
+ # error "Unable to build hitimes, no Instance backend available"
26
+ #endif
27
+
28
+
29
+ /* an alias for a 64bit unsigned integer. The various sytem dependenent
30
+ * files must define hitimes_u64int_t
31
+ */
32
+ typedef HITIMES_U64INT hitimes_instant_t;
33
+
34
+ typedef struct hitimes_interval {
35
+ hitimes_instant_t start_instant;
36
+ hitimes_instant_t stop_instant;
37
+ long double duration;
38
+ } hitimes_interval_t;
39
+
40
+ /* all the backends must define this method */
41
+ hitimes_instant_t hitimes_get_current_instant( );
42
+ long double hitimes_instant_conversion_factor( );
43
+
44
+ /* init methods */
45
+ void Init_hitimes_stats();
46
+ void Init_hitimes_interval();
47
+
48
+
49
+ /* Module and Classes -- defined at the top level */
50
+ extern VALUE mH; /* module Hitimes */
51
+ extern VALUE eH_Error; /* class Hitimes::Error */
52
+ extern VALUE cH_Interval; /* class Hitimes::Interval */
53
+
54
+
55
+ /**
56
+ * Methods for Interval
57
+ */
58
+
59
+ VALUE hitimes_interval_free(hitimes_interval_t* i) ;
60
+ VALUE hitimes_interval_alloc(VALUE klass);
61
+ VALUE hitimes_interval_now( VALUE self );
62
+ VALUE hitimes_interval_measure( VALUE self );
63
+ VALUE hitimes_interval_split( VALUE self );
64
+ VALUE hitimes_interval_start( VALUE self );
65
+ VALUE hitimes_interval_stop( VALUE self );
66
+ VALUE hitimes_interval_started( VALUE self );
67
+ VALUE hitimes_interval_stopped( VALUE self );
68
+ VALUE hitimes_interval_running( VALUE self );
69
+ VALUE hitimes_interval_start_instant( VALUE self );
70
+ VALUE hitimes_interval_stop_instant( VALUE self );
71
+ VALUE hitimes_interval_duration ( VALUE self );
72
+
73
+ #endif