ruby-prof 1.6.3 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +11 -0
  3. data/ext/ruby_prof/rp_allocation.c +342 -342
  4. data/ext/ruby_prof/rp_call_tree.c +1 -1
  5. data/ext/ruby_prof/rp_call_tree.h +1 -1
  6. data/ext/ruby_prof/rp_call_trees.c +2 -2
  7. data/ext/ruby_prof/rp_call_trees.h +2 -2
  8. data/ext/ruby_prof/rp_measure_allocations.c +1 -1
  9. data/ext/ruby_prof/rp_measure_memory.c +46 -46
  10. data/ext/ruby_prof/rp_measure_process_time.c +1 -1
  11. data/ext/ruby_prof/rp_measure_wall_time.c +1 -1
  12. data/ext/ruby_prof/rp_measurement.c +364 -364
  13. data/ext/ruby_prof/rp_method.c +26 -25
  14. data/ext/ruby_prof/rp_method.h +5 -2
  15. data/ext/ruby_prof/rp_profile.c +2 -2
  16. data/ext/ruby_prof/rp_profile.h +36 -36
  17. data/ext/ruby_prof/rp_stack.c +1 -1
  18. data/ext/ruby_prof/rp_thread.c +1 -1
  19. data/ext/ruby_prof/ruby_prof.c +1 -1
  20. data/ext/ruby_prof/ruby_prof.h +34 -34
  21. data/ext/ruby_prof/vc/ruby_prof.vcxproj +5 -7
  22. data/lib/ruby-prof/compatibility.rb +10 -10
  23. data/lib/ruby-prof/exclude_common_methods.rb +9 -3
  24. data/lib/ruby-prof/method_info.rb +87 -85
  25. data/lib/ruby-prof/version.rb +1 -1
  26. data/ruby-prof.gemspec +2 -1
  27. data/test/crash2.rb +144 -0
  28. data/test/enumerable_test.rb +5 -5
  29. data/test/exclude_methods_test.rb +197 -86
  30. data/test/line_number_test.rb +254 -99
  31. data/test/measure_allocations_test.rb +422 -1
  32. data/test/measure_memory_test.rb +433 -1
  33. data/test/measure_process_time_test.rb +882 -15
  34. data/test/measure_wall_time_test.rb +195 -47
  35. data/test/method_info_test.rb +1 -1
  36. data/test/recursive_test.rb +198 -1
  37. data/test/thread_test.rb +0 -4
  38. metadata +20 -5
@@ -1,364 +1,364 @@
1
- /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
- Please see the LICENSE file for copyright and distribution information */
3
-
4
- #include "rp_measurement.h"
5
-
6
- VALUE mMeasure;
7
- VALUE cRpMeasurement;
8
-
9
- prof_measurer_t* prof_measurer_allocations(bool track_allocations);
10
- prof_measurer_t* prof_measurer_memory(bool track_allocations);
11
- prof_measurer_t* prof_measurer_process_time(bool track_allocations);
12
- prof_measurer_t* prof_measurer_wall_time(bool track_allocations);
13
-
14
- void rp_init_measure_allocations(void);
15
- void rp_init_measure_memory(void);
16
- void rp_init_measure_process_time(void);
17
- void rp_init_measure_wall_time(void);
18
-
19
- prof_measurer_t* prof_measurer_create(prof_measure_mode_t measure, bool track_allocations)
20
- {
21
- switch (measure)
22
- {
23
- case MEASURE_WALL_TIME:
24
- return prof_measurer_wall_time(track_allocations);
25
- case MEASURE_PROCESS_TIME:
26
- return prof_measurer_process_time(track_allocations);
27
- case MEASURE_ALLOCATIONS:
28
- return prof_measurer_allocations(track_allocations);
29
- case MEASURE_MEMORY:
30
- return prof_measurer_memory(track_allocations);
31
- default:
32
- rb_raise(rb_eArgError, "Unknown measure mode: %d", measure);
33
- }
34
- };
35
-
36
- double prof_measure(prof_measurer_t* measurer, rb_trace_arg_t* trace_arg)
37
- {
38
- double measurement = measurer->measure(trace_arg);
39
- return measurement * measurer->multiplier;
40
- }
41
-
42
- /* ======= prof_measurement_t ========*/
43
- prof_measurement_t* prof_measurement_create(void)
44
- {
45
- prof_measurement_t* result = ALLOC(prof_measurement_t);
46
- result->owner = OWNER_C;
47
- result->total_time = 0;
48
- result->self_time = 0;
49
- result->wait_time = 0;
50
- result->called = 0;
51
- result->object = Qnil;
52
- return result;
53
- }
54
-
55
- /* call-seq:
56
- new(total_time, self_time, wait_time, called) -> Measurement
57
-
58
- Creates a new measuremen instance. */
59
- static VALUE prof_measurement_initialize(VALUE self, VALUE total_time, VALUE self_time, VALUE wait_time, VALUE called)
60
- {
61
- prof_measurement_t* result = prof_get_measurement(self);
62
-
63
- result->total_time = NUM2DBL(total_time);
64
- result->self_time = NUM2DBL(self_time);
65
- result->wait_time = NUM2DBL(wait_time);
66
- result->called = NUM2INT(called);
67
- result->object = self;
68
- return self;
69
- }
70
-
71
- prof_measurement_t* prof_measurement_copy(prof_measurement_t* other)
72
- {
73
- prof_measurement_t* result = prof_measurement_create();
74
- result->called = other->called;
75
- result->total_time = other->total_time;
76
- result->self_time = other->self_time;
77
- result->wait_time = other->wait_time;
78
-
79
- return result;
80
- }
81
-
82
- static VALUE prof_measurement_initialize_copy(VALUE self, VALUE other)
83
- {
84
- // This object was created by Ruby either via Measurment#clone or Measurement#dup
85
- // and thus prof_measurement_allocate was called so the object is owned by Ruby
86
-
87
- if (self == other)
88
- return self;
89
-
90
- prof_measurement_t* self_ptr = prof_get_measurement(self);
91
- prof_measurement_t* other_ptr = prof_get_measurement(other);
92
-
93
- self_ptr->called = other_ptr->called;
94
- self_ptr->total_time = other_ptr->total_time;
95
- self_ptr->self_time = other_ptr->self_time;
96
- self_ptr->wait_time = other_ptr->wait_time;
97
-
98
- return self;
99
- }
100
-
101
- void prof_measurement_mark(void* data)
102
- {
103
- if (!data) return;
104
-
105
- prof_measurement_t* measurement = (prof_measurement_t*)data;
106
-
107
- if (measurement->object != Qnil)
108
- rb_gc_mark_movable(measurement->object);
109
- }
110
-
111
- void prof_measurement_compact(void* data)
112
- {
113
- prof_measurement_t* measurement = (prof_measurement_t*)data;
114
- measurement->object = rb_gc_location(measurement->object);
115
- }
116
-
117
- void prof_measurement_free(prof_measurement_t* measurement)
118
- {
119
- /* Has this measurement object been accessed by Ruby? If
120
- yes clean it up so to avoid a segmentation fault. */
121
- if (measurement->object != Qnil)
122
- {
123
- RTYPEDDATA(measurement->object)->data = NULL;
124
- measurement->object = Qnil;
125
- }
126
-
127
- xfree(measurement);
128
- }
129
-
130
- static void prof_measurement_ruby_gc_free(void* data)
131
- {
132
- prof_measurement_t* measurement = (prof_measurement_t*)data;
133
-
134
- if (!measurement)
135
- {
136
- // Object has already been freed by C code
137
- return;
138
- }
139
- else if (measurement->owner == OWNER_RUBY)
140
- {
141
- // Ruby owns this object, we need to free the underlying C struct
142
- prof_measurement_free(measurement);
143
- }
144
- else
145
- {
146
- // The Ruby object is being freed, but not the underlying C structure. So unlink the two.
147
- measurement->object = Qnil;
148
- }
149
- }
150
-
151
- size_t prof_measurement_size(const void* data)
152
- {
153
- return sizeof(prof_measurement_t);
154
- }
155
-
156
- static const rb_data_type_t measurement_type =
157
- {
158
- .wrap_struct_name = "Measurement",
159
- .function =
160
- {
161
- .dmark = prof_measurement_mark,
162
- .dfree = prof_measurement_ruby_gc_free,
163
- .dsize = prof_measurement_size,
164
- .dcompact = prof_measurement_compact
165
- },
166
- .data = NULL,
167
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
168
- };
169
-
170
- VALUE prof_measurement_wrap(prof_measurement_t* measurement)
171
- {
172
- if (measurement->object == Qnil)
173
- {
174
- measurement->object = TypedData_Wrap_Struct(cRpMeasurement, &measurement_type, measurement);
175
- }
176
- return measurement->object;
177
- }
178
-
179
- static VALUE prof_measurement_allocate(VALUE klass)
180
- {
181
- prof_measurement_t* measurement = prof_measurement_create();
182
- // This object is being created by Ruby
183
- measurement->owner = OWNER_RUBY;
184
- measurement->object = prof_measurement_wrap(measurement);
185
- return measurement->object;
186
- }
187
-
188
- prof_measurement_t* prof_get_measurement(VALUE self)
189
- {
190
- /* Can't use Data_Get_Struct because that triggers the event hook
191
- ending up in endless recursion. */
192
- prof_measurement_t* result = RTYPEDDATA_DATA(self);
193
-
194
- if (!result)
195
- rb_raise(rb_eRuntimeError, "This RubyProf::Measurement instance has already been freed, likely because its profile has been freed.");
196
-
197
- return result;
198
- }
199
-
200
- /* call-seq:
201
- total_time -> float
202
-
203
- Returns the total amount of time spent in this method and its children. */
204
- static VALUE prof_measurement_total_time(VALUE self)
205
- {
206
- prof_measurement_t* result = prof_get_measurement(self);
207
- return rb_float_new(result->total_time);
208
- }
209
-
210
- /* call-seq:
211
- total_time=value -> value
212
-
213
- Sets the call count to n. */
214
- static VALUE prof_measurement_set_total_time(VALUE self, VALUE value)
215
- {
216
- prof_measurement_t* result = prof_get_measurement(self);
217
- result->total_time = NUM2DBL(value);
218
- return value;
219
- }
220
-
221
- /* call-seq:
222
- self_time -> float
223
-
224
- Returns the total amount of time spent in this method. */
225
- static VALUE
226
- prof_measurement_self_time(VALUE self)
227
- {
228
- prof_measurement_t* result = prof_get_measurement(self);
229
-
230
- return rb_float_new(result->self_time);
231
- }
232
-
233
- /* call-seq:
234
- self_time=value -> value
235
-
236
- Sets the call count to value. */
237
- static VALUE prof_measurement_set_self_time(VALUE self, VALUE value)
238
- {
239
- prof_measurement_t* result = prof_get_measurement(self);
240
- result->self_time = NUM2DBL(value);
241
- return value;
242
- }
243
-
244
- /* call-seq:
245
- wait_time -> float
246
-
247
- Returns the total amount of time this method waited for other threads. */
248
- static VALUE prof_measurement_wait_time(VALUE self)
249
- {
250
- prof_measurement_t* result = prof_get_measurement(self);
251
-
252
- return rb_float_new(result->wait_time);
253
- }
254
-
255
- /* call-seq:
256
- wait_time=value -> value
257
-
258
- Sets the wait time to value. */
259
- static VALUE prof_measurement_set_wait_time(VALUE self, VALUE value)
260
- {
261
- prof_measurement_t* result = prof_get_measurement(self);
262
- result->wait_time = NUM2DBL(value);
263
- return value;
264
- }
265
-
266
- /* call-seq:
267
- called -> int
268
-
269
- Returns the total amount of times this method was called. */
270
- static VALUE prof_measurement_called(VALUE self)
271
- {
272
- prof_measurement_t* result = prof_get_measurement(self);
273
- return INT2NUM(result->called);
274
- }
275
-
276
- /* call-seq:
277
- called=value -> value
278
-
279
- Sets the call count to value. */
280
- static VALUE prof_measurement_set_called(VALUE self, VALUE value)
281
- {
282
- prof_measurement_t* result = prof_get_measurement(self);
283
- result->called = NUM2INT(value);
284
- return value;
285
- }
286
-
287
- /* :nodoc: */
288
- void prof_measurement_merge_internal(prof_measurement_t* self, prof_measurement_t* other)
289
- {
290
- self->called += other->called;
291
- self->total_time += other->total_time;
292
- self->self_time += other->self_time;
293
- self->wait_time += other->wait_time;
294
- }
295
-
296
- /* call-seq:
297
- merge(other)
298
-
299
- Adds the content of other measurement to this measurement */
300
- VALUE prof_measurement_merge(VALUE self, VALUE other)
301
- {
302
- prof_measurement_t* self_ptr = prof_get_measurement(self);
303
- prof_measurement_t* other_ptr = prof_get_measurement(other);
304
- prof_measurement_merge_internal(self_ptr, other_ptr);
305
- return self;
306
- }
307
-
308
- /* :nodoc: */
309
- static VALUE prof_measurement_dump(VALUE self)
310
- {
311
- prof_measurement_t* measurement_data = prof_get_measurement(self);
312
- VALUE result = rb_hash_new();
313
-
314
- rb_hash_aset(result, ID2SYM(rb_intern("owner")), INT2FIX(measurement_data->owner));
315
- rb_hash_aset(result, ID2SYM(rb_intern("total_time")), rb_float_new(measurement_data->total_time));
316
- rb_hash_aset(result, ID2SYM(rb_intern("self_time")), rb_float_new(measurement_data->self_time));
317
- rb_hash_aset(result, ID2SYM(rb_intern("wait_time")), rb_float_new(measurement_data->wait_time));
318
- rb_hash_aset(result, ID2SYM(rb_intern("called")), INT2FIX(measurement_data->called));
319
-
320
- return result;
321
- }
322
-
323
- /* :nodoc: */
324
- static VALUE
325
- prof_measurement_load(VALUE self, VALUE data)
326
- {
327
- prof_measurement_t* measurement = prof_get_measurement(self);
328
- measurement->object = self;
329
-
330
- measurement->owner = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("owner"))));
331
- measurement->total_time = rb_num2dbl(rb_hash_aref(data, ID2SYM(rb_intern("total_time"))));
332
- measurement->self_time = rb_num2dbl(rb_hash_aref(data, ID2SYM(rb_intern("self_time"))));
333
- measurement->wait_time = rb_num2dbl(rb_hash_aref(data, ID2SYM(rb_intern("wait_time"))));
334
- measurement->called = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("called"))));
335
-
336
- return data;
337
- }
338
-
339
- void rp_init_measure()
340
- {
341
- mMeasure = rb_define_module_under(mProf, "Measure");
342
- rp_init_measure_wall_time();
343
- rp_init_measure_process_time();
344
- rp_init_measure_allocations();
345
- rp_init_measure_memory();
346
-
347
- cRpMeasurement = rb_define_class_under(mProf, "Measurement", rb_cObject);
348
- rb_define_alloc_func(cRpMeasurement, prof_measurement_allocate);
349
-
350
- rb_define_method(cRpMeasurement, "initialize", prof_measurement_initialize, 4);
351
- rb_define_method(cRpMeasurement, "initialize_copy", prof_measurement_initialize_copy, 1);
352
- rb_define_method(cRpMeasurement, "merge!", prof_measurement_merge, 1);
353
- rb_define_method(cRpMeasurement, "called", prof_measurement_called, 0);
354
- rb_define_method(cRpMeasurement, "called=", prof_measurement_set_called, 1);
355
- rb_define_method(cRpMeasurement, "total_time", prof_measurement_total_time, 0);
356
- rb_define_method(cRpMeasurement, "total_time=", prof_measurement_set_total_time, 1);
357
- rb_define_method(cRpMeasurement, "self_time", prof_measurement_self_time, 0);
358
- rb_define_method(cRpMeasurement, "self_time=", prof_measurement_set_self_time, 1);
359
- rb_define_method(cRpMeasurement, "wait_time", prof_measurement_wait_time, 0);
360
- rb_define_method(cRpMeasurement, "wait_time=", prof_measurement_set_wait_time, 1);
361
-
362
- rb_define_method(cRpMeasurement, "_dump_data", prof_measurement_dump, 0);
363
- rb_define_method(cRpMeasurement, "_load_data", prof_measurement_load, 1);
364
- }
1
+ /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
+ Please see the LICENSE file for copyright and distribution information */
3
+
4
+ #include "rp_measurement.h"
5
+
6
+ VALUE mMeasure;
7
+ VALUE cRpMeasurement;
8
+
9
+ prof_measurer_t* prof_measurer_allocations(bool track_allocations);
10
+ prof_measurer_t* prof_measurer_memory(bool track_allocations);
11
+ prof_measurer_t* prof_measurer_process_time(bool track_allocations);
12
+ prof_measurer_t* prof_measurer_wall_time(bool track_allocations);
13
+
14
+ void rp_init_measure_allocations(void);
15
+ void rp_init_measure_memory(void);
16
+ void rp_init_measure_process_time(void);
17
+ void rp_init_measure_wall_time(void);
18
+
19
+ prof_measurer_t* prof_measurer_create(prof_measure_mode_t measure, bool track_allocations)
20
+ {
21
+ switch (measure)
22
+ {
23
+ case MEASURE_WALL_TIME:
24
+ return prof_measurer_wall_time(track_allocations);
25
+ case MEASURE_PROCESS_TIME:
26
+ return prof_measurer_process_time(track_allocations);
27
+ case MEASURE_ALLOCATIONS:
28
+ return prof_measurer_allocations(track_allocations);
29
+ case MEASURE_MEMORY:
30
+ return prof_measurer_memory(track_allocations);
31
+ default:
32
+ rb_raise(rb_eArgError, "Unknown measure mode: %d", measure);
33
+ }
34
+ };
35
+
36
+ double prof_measure(prof_measurer_t* measurer, rb_trace_arg_t* trace_arg)
37
+ {
38
+ double measurement = measurer->measure(trace_arg);
39
+ return measurement * measurer->multiplier;
40
+ }
41
+
42
+ /* ======= prof_measurement_t ========*/
43
+ prof_measurement_t* prof_measurement_create(void)
44
+ {
45
+ prof_measurement_t* result = ALLOC(prof_measurement_t);
46
+ result->owner = OWNER_C;
47
+ result->total_time = 0;
48
+ result->self_time = 0;
49
+ result->wait_time = 0;
50
+ result->called = 0;
51
+ result->object = Qnil;
52
+ return result;
53
+ }
54
+
55
+ /* call-seq:
56
+ new(total_time, self_time, wait_time, called) -> Measurement
57
+
58
+ Creates a new measuremen instance. */
59
+ static VALUE prof_measurement_initialize(VALUE self, VALUE total_time, VALUE self_time, VALUE wait_time, VALUE called)
60
+ {
61
+ prof_measurement_t* result = prof_get_measurement(self);
62
+
63
+ result->total_time = NUM2DBL(total_time);
64
+ result->self_time = NUM2DBL(self_time);
65
+ result->wait_time = NUM2DBL(wait_time);
66
+ result->called = NUM2INT(called);
67
+ result->object = self;
68
+ return self;
69
+ }
70
+
71
+ prof_measurement_t* prof_measurement_copy(prof_measurement_t* other)
72
+ {
73
+ prof_measurement_t* result = prof_measurement_create();
74
+ result->called = other->called;
75
+ result->total_time = other->total_time;
76
+ result->self_time = other->self_time;
77
+ result->wait_time = other->wait_time;
78
+
79
+ return result;
80
+ }
81
+
82
+ static VALUE prof_measurement_initialize_copy(VALUE self, VALUE other)
83
+ {
84
+ // This object was created by Ruby either via Measurment#clone or Measurement#dup
85
+ // and thus prof_measurement_allocate was called so the object is owned by Ruby
86
+
87
+ if (self == other)
88
+ return self;
89
+
90
+ prof_measurement_t* self_ptr = prof_get_measurement(self);
91
+ prof_measurement_t* other_ptr = prof_get_measurement(other);
92
+
93
+ self_ptr->called = other_ptr->called;
94
+ self_ptr->total_time = other_ptr->total_time;
95
+ self_ptr->self_time = other_ptr->self_time;
96
+ self_ptr->wait_time = other_ptr->wait_time;
97
+
98
+ return self;
99
+ }
100
+
101
+ void prof_measurement_mark(void* data)
102
+ {
103
+ if (!data) return;
104
+
105
+ prof_measurement_t* measurement = (prof_measurement_t*)data;
106
+
107
+ if (measurement->object != Qnil)
108
+ rb_gc_mark_movable(measurement->object);
109
+ }
110
+
111
+ void prof_measurement_compact(void* data)
112
+ {
113
+ prof_measurement_t* measurement = (prof_measurement_t*)data;
114
+ measurement->object = rb_gc_location(measurement->object);
115
+ }
116
+
117
+ void prof_measurement_free(prof_measurement_t* measurement)
118
+ {
119
+ /* Has this measurement object been accessed by Ruby? If
120
+ yes clean it up so to avoid a segmentation fault. */
121
+ if (measurement->object != Qnil)
122
+ {
123
+ RTYPEDDATA(measurement->object)->data = NULL;
124
+ measurement->object = Qnil;
125
+ }
126
+
127
+ xfree(measurement);
128
+ }
129
+
130
+ static void prof_measurement_ruby_gc_free(void* data)
131
+ {
132
+ prof_measurement_t* measurement = (prof_measurement_t*)data;
133
+
134
+ if (!measurement)
135
+ {
136
+ // Object has already been freed by C code
137
+ return;
138
+ }
139
+ else if (measurement->owner == OWNER_RUBY)
140
+ {
141
+ // Ruby owns this object, we need to free the underlying C struct
142
+ prof_measurement_free(measurement);
143
+ }
144
+ else
145
+ {
146
+ // The Ruby object is being freed, but not the underlying C structure. So unlink the two.
147
+ measurement->object = Qnil;
148
+ }
149
+ }
150
+
151
+ size_t prof_measurement_size(const void* data)
152
+ {
153
+ return sizeof(prof_measurement_t);
154
+ }
155
+
156
+ static const rb_data_type_t measurement_type =
157
+ {
158
+ .wrap_struct_name = "Measurement",
159
+ .function =
160
+ {
161
+ .dmark = prof_measurement_mark,
162
+ .dfree = prof_measurement_ruby_gc_free,
163
+ .dsize = prof_measurement_size,
164
+ .dcompact = prof_measurement_compact
165
+ },
166
+ .data = NULL,
167
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
168
+ };
169
+
170
+ VALUE prof_measurement_wrap(prof_measurement_t* measurement)
171
+ {
172
+ if (measurement->object == Qnil)
173
+ {
174
+ measurement->object = TypedData_Wrap_Struct(cRpMeasurement, &measurement_type, measurement);
175
+ }
176
+ return measurement->object;
177
+ }
178
+
179
+ static VALUE prof_measurement_allocate(VALUE klass)
180
+ {
181
+ prof_measurement_t* measurement = prof_measurement_create();
182
+ // This object is being created by Ruby
183
+ measurement->owner = OWNER_RUBY;
184
+ measurement->object = prof_measurement_wrap(measurement);
185
+ return measurement->object;
186
+ }
187
+
188
+ prof_measurement_t* prof_get_measurement(VALUE self)
189
+ {
190
+ /* Can't use Data_Get_Struct because that triggers the event hook
191
+ ending up in endless recursion. */
192
+ prof_measurement_t* result = RTYPEDDATA_DATA(self);
193
+
194
+ if (!result)
195
+ rb_raise(rb_eRuntimeError, "This RubyProf::Measurement instance has already been freed, likely because its profile has been freed.");
196
+
197
+ return result;
198
+ }
199
+
200
+ /* call-seq:
201
+ total_time -> float
202
+
203
+ Returns the total amount of time spent in this method and its children. */
204
+ static VALUE prof_measurement_total_time(VALUE self)
205
+ {
206
+ prof_measurement_t* result = prof_get_measurement(self);
207
+ return rb_float_new(result->total_time);
208
+ }
209
+
210
+ /* call-seq:
211
+ total_time=value -> value
212
+
213
+ Sets the call count to n. */
214
+ static VALUE prof_measurement_set_total_time(VALUE self, VALUE value)
215
+ {
216
+ prof_measurement_t* result = prof_get_measurement(self);
217
+ result->total_time = NUM2DBL(value);
218
+ return value;
219
+ }
220
+
221
+ /* call-seq:
222
+ self_time -> float
223
+
224
+ Returns the total amount of time spent in this method. */
225
+ static VALUE
226
+ prof_measurement_self_time(VALUE self)
227
+ {
228
+ prof_measurement_t* result = prof_get_measurement(self);
229
+
230
+ return rb_float_new(result->self_time);
231
+ }
232
+
233
+ /* call-seq:
234
+ self_time=value -> value
235
+
236
+ Sets the call count to value. */
237
+ static VALUE prof_measurement_set_self_time(VALUE self, VALUE value)
238
+ {
239
+ prof_measurement_t* result = prof_get_measurement(self);
240
+ result->self_time = NUM2DBL(value);
241
+ return value;
242
+ }
243
+
244
+ /* call-seq:
245
+ wait_time -> float
246
+
247
+ Returns the total amount of time this method waited for other threads. */
248
+ static VALUE prof_measurement_wait_time(VALUE self)
249
+ {
250
+ prof_measurement_t* result = prof_get_measurement(self);
251
+
252
+ return rb_float_new(result->wait_time);
253
+ }
254
+
255
+ /* call-seq:
256
+ wait_time=value -> value
257
+
258
+ Sets the wait time to value. */
259
+ static VALUE prof_measurement_set_wait_time(VALUE self, VALUE value)
260
+ {
261
+ prof_measurement_t* result = prof_get_measurement(self);
262
+ result->wait_time = NUM2DBL(value);
263
+ return value;
264
+ }
265
+
266
+ /* call-seq:
267
+ called -> int
268
+
269
+ Returns the total amount of times this method was called. */
270
+ static VALUE prof_measurement_called(VALUE self)
271
+ {
272
+ prof_measurement_t* result = prof_get_measurement(self);
273
+ return INT2NUM(result->called);
274
+ }
275
+
276
+ /* call-seq:
277
+ called=value -> value
278
+
279
+ Sets the call count to value. */
280
+ static VALUE prof_measurement_set_called(VALUE self, VALUE value)
281
+ {
282
+ prof_measurement_t* result = prof_get_measurement(self);
283
+ result->called = NUM2INT(value);
284
+ return value;
285
+ }
286
+
287
+ /* :nodoc: */
288
+ void prof_measurement_merge_internal(prof_measurement_t* self, prof_measurement_t* other)
289
+ {
290
+ self->called += other->called;
291
+ self->total_time += other->total_time;
292
+ self->self_time += other->self_time;
293
+ self->wait_time += other->wait_time;
294
+ }
295
+
296
+ /* call-seq:
297
+ merge(other)
298
+
299
+ Adds the content of other measurement to this measurement */
300
+ VALUE prof_measurement_merge(VALUE self, VALUE other)
301
+ {
302
+ prof_measurement_t* self_ptr = prof_get_measurement(self);
303
+ prof_measurement_t* other_ptr = prof_get_measurement(other);
304
+ prof_measurement_merge_internal(self_ptr, other_ptr);
305
+ return self;
306
+ }
307
+
308
+ /* :nodoc: */
309
+ static VALUE prof_measurement_dump(VALUE self)
310
+ {
311
+ prof_measurement_t* measurement_data = prof_get_measurement(self);
312
+ VALUE result = rb_hash_new();
313
+
314
+ rb_hash_aset(result, ID2SYM(rb_intern("owner")), INT2FIX(measurement_data->owner));
315
+ rb_hash_aset(result, ID2SYM(rb_intern("total_time")), rb_float_new(measurement_data->total_time));
316
+ rb_hash_aset(result, ID2SYM(rb_intern("self_time")), rb_float_new(measurement_data->self_time));
317
+ rb_hash_aset(result, ID2SYM(rb_intern("wait_time")), rb_float_new(measurement_data->wait_time));
318
+ rb_hash_aset(result, ID2SYM(rb_intern("called")), INT2FIX(measurement_data->called));
319
+
320
+ return result;
321
+ }
322
+
323
+ /* :nodoc: */
324
+ static VALUE
325
+ prof_measurement_load(VALUE self, VALUE data)
326
+ {
327
+ prof_measurement_t* measurement = prof_get_measurement(self);
328
+ measurement->object = self;
329
+
330
+ measurement->owner = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("owner"))));
331
+ measurement->total_time = rb_num2dbl(rb_hash_aref(data, ID2SYM(rb_intern("total_time"))));
332
+ measurement->self_time = rb_num2dbl(rb_hash_aref(data, ID2SYM(rb_intern("self_time"))));
333
+ measurement->wait_time = rb_num2dbl(rb_hash_aref(data, ID2SYM(rb_intern("wait_time"))));
334
+ measurement->called = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("called"))));
335
+
336
+ return data;
337
+ }
338
+
339
+ void rp_init_measure(void)
340
+ {
341
+ mMeasure = rb_define_module_under(mProf, "Measure");
342
+ rp_init_measure_wall_time();
343
+ rp_init_measure_process_time();
344
+ rp_init_measure_allocations();
345
+ rp_init_measure_memory();
346
+
347
+ cRpMeasurement = rb_define_class_under(mProf, "Measurement", rb_cObject);
348
+ rb_define_alloc_func(cRpMeasurement, prof_measurement_allocate);
349
+
350
+ rb_define_method(cRpMeasurement, "initialize", prof_measurement_initialize, 4);
351
+ rb_define_method(cRpMeasurement, "initialize_copy", prof_measurement_initialize_copy, 1);
352
+ rb_define_method(cRpMeasurement, "merge!", prof_measurement_merge, 1);
353
+ rb_define_method(cRpMeasurement, "called", prof_measurement_called, 0);
354
+ rb_define_method(cRpMeasurement, "called=", prof_measurement_set_called, 1);
355
+ rb_define_method(cRpMeasurement, "total_time", prof_measurement_total_time, 0);
356
+ rb_define_method(cRpMeasurement, "total_time=", prof_measurement_set_total_time, 1);
357
+ rb_define_method(cRpMeasurement, "self_time", prof_measurement_self_time, 0);
358
+ rb_define_method(cRpMeasurement, "self_time=", prof_measurement_set_self_time, 1);
359
+ rb_define_method(cRpMeasurement, "wait_time", prof_measurement_wait_time, 0);
360
+ rb_define_method(cRpMeasurement, "wait_time=", prof_measurement_set_wait_time, 1);
361
+
362
+ rb_define_method(cRpMeasurement, "_dump_data", prof_measurement_dump, 0);
363
+ rb_define_method(cRpMeasurement, "_load_data", prof_measurement_load, 1);
364
+ }