hitimes 1.0.4-x86-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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