ruby-prof 0.11.3 → 0.12.1

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 (58) hide show
  1. data/CHANGES +27 -0
  2. data/README.rdoc +14 -14
  3. data/bin/ruby-prof +275 -266
  4. data/ext/ruby_prof/rp_call_info.c +33 -24
  5. data/ext/ruby_prof/rp_call_info.h +2 -1
  6. data/ext/ruby_prof/rp_measure.c +1 -1
  7. data/ext/ruby_prof/rp_measure.h +1 -1
  8. data/ext/ruby_prof/rp_measure_allocations.c +1 -1
  9. data/ext/ruby_prof/rp_measure_cpu_time.c +1 -1
  10. data/ext/ruby_prof/rp_measure_gc_runs.c +1 -1
  11. data/ext/ruby_prof/rp_measure_gc_time.c +1 -1
  12. data/ext/ruby_prof/rp_measure_memory.c +1 -1
  13. data/ext/ruby_prof/rp_measure_process_time.c +2 -2
  14. data/ext/ruby_prof/rp_measure_wall_time.c +2 -2
  15. data/ext/ruby_prof/rp_method.c +11 -24
  16. data/ext/ruby_prof/rp_method.h +2 -3
  17. data/ext/ruby_prof/rp_stack.c +48 -7
  18. data/ext/ruby_prof/rp_stack.h +3 -3
  19. data/ext/ruby_prof/rp_thread.c +26 -17
  20. data/ext/ruby_prof/rp_thread.h +3 -3
  21. data/ext/ruby_prof/ruby_prof.c +7 -86
  22. data/ext/ruby_prof/ruby_prof.h +1 -1
  23. data/ext/ruby_prof/vc/ruby_prof.sln +12 -6
  24. data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +110 -0
  25. data/ext/ruby_prof/vc/{ruby_prof.vcxproj → ruby_prof_19.vcxproj} +4 -1
  26. data/ext/ruby_prof/vc/ruby_prof_20.vcxproj +112 -0
  27. data/ext/ruby_prof/version.h +4 -4
  28. data/lib/ruby-prof.rb +1 -0
  29. data/lib/ruby-prof/call_info.rb +1 -1
  30. data/lib/ruby-prof/call_info_visitor.rb +4 -2
  31. data/lib/ruby-prof/compatibility.rb +6 -1
  32. data/lib/ruby-prof/method_info.rb +1 -1
  33. data/lib/ruby-prof/printers/call_info_printer.rb +1 -1
  34. data/lib/ruby-prof/printers/call_stack_printer.rb +3 -3
  35. data/lib/ruby-prof/printers/dot_printer.rb +1 -1
  36. data/lib/ruby-prof/printers/flat_printer.rb +4 -4
  37. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +2 -2
  38. data/lib/ruby-prof/printers/graph_html_printer.rb +3 -3
  39. data/lib/ruby-prof/printers/graph_printer.rb +15 -15
  40. data/lib/ruby-prof/thread.rb +22 -0
  41. data/ruby-prof.gemspec +2 -1
  42. data/test/basic_test.rb +77 -45
  43. data/test/call_info_test.rb +78 -0
  44. data/test/call_info_visitor_test.rb +1 -1
  45. data/test/dynamic_method_test.rb +14 -8
  46. data/test/measure_cpu_time_test.rb +23 -12
  47. data/test/measure_process_time_test.rb +21 -170
  48. data/test/measure_wall_time_test.rb +59 -13
  49. data/test/method_elimination_test.rb +30 -19
  50. data/test/pause_resume_test.rb +129 -22
  51. data/test/prime.rb +0 -1
  52. data/test/printers_test.rb +7 -18
  53. data/test/recursive_test.rb +4 -48
  54. data/test/test_helper.rb +30 -10
  55. data/test/test_suite.rb +1 -2
  56. metadata +23 -5
  57. data/test/pause_test.rb +0 -57
  58. data/test/prime_test.rb +0 -13
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #include "ruby_prof.h"
@@ -10,7 +10,6 @@ VALUE cCallInfo;
10
10
 
11
11
  // Forward declarations
12
12
  st_table * call_info_table_create();
13
- void call_info_table_free(st_table *table);
14
13
 
15
14
 
16
15
  /* ======= prof_call_info_t ========*/
@@ -31,9 +30,8 @@ prof_call_info_create(prof_method_t* method, prof_call_info_t* parent)
31
30
  result->line = 0;
32
31
  return result;
33
32
  }
34
-
35
33
  static void
36
- prof_call_info_free(prof_call_info_t *call_info)
34
+ prof_call_info_ruby_gc_free(prof_call_info_t *call_info)
37
35
  {
38
36
  /* Has this thread object been accessed by Ruby? If
39
37
  yes clean it up so to avoid a segmentation fault. */
@@ -44,8 +42,13 @@ prof_call_info_free(prof_call_info_t *call_info)
44
42
  RDATA(call_info->object)->dmark = NULL;
45
43
  }
46
44
  call_info->object = Qnil;
45
+ }
47
46
 
48
- call_info_table_free(call_info->call_infos);
47
+ static void
48
+ prof_call_info_free(prof_call_info_t *call_info)
49
+ {
50
+ prof_call_info_ruby_gc_free(call_info);
51
+ xfree(call_info->call_infos);
49
52
  xfree(call_info);
50
53
  }
51
54
 
@@ -53,10 +56,13 @@ static void
53
56
  prof_call_info_mark(prof_call_info_t *call_info)
54
57
  {
55
58
  if (call_info->object)
56
- rb_gc_mark(call_info->children);
59
+ rb_gc_mark(call_info->object);
57
60
 
58
61
  if (call_info->children)
59
62
  rb_gc_mark(call_info->children);
63
+
64
+ /* We don't mark the call info child table since that will be done
65
+ via the appropriate method */
60
66
  }
61
67
 
62
68
  VALUE
@@ -64,7 +70,7 @@ prof_call_info_wrap(prof_call_info_t *call_info)
64
70
  {
65
71
  if (call_info->object == Qnil)
66
72
  {
67
- call_info->object = Data_Wrap_Struct(cCallInfo, prof_call_info_mark, prof_call_info_free, call_info);
73
+ call_info->object = Data_Wrap_Struct(cCallInfo, prof_call_info_mark, prof_call_info_ruby_gc_free, call_info);
68
74
  }
69
75
  return call_info->object;
70
76
  }
@@ -89,20 +95,6 @@ call_info_table_create()
89
95
  return st_init_table(&type_method_hash);
90
96
  }
91
97
 
92
- /*static int
93
- call_info_table_free_iterator(st_data_t key, st_data_t value, st_data_t dummy)
94
- {
95
- prof_call_info_free((prof_call_info_t*)value);
96
- return ST_CONTINUE;
97
- }*/
98
-
99
- void
100
- call_info_table_free(st_table *table)
101
- {
102
- //st_foreach(table, call_info_table_free_iterator, 0);
103
- st_free_table(table);
104
- }
105
-
106
98
  size_t
107
99
  call_info_table_insert(st_table *table, const prof_method_key_t *key, prof_call_info_t *val)
108
100
  {
@@ -337,11 +329,29 @@ prof_call_infos_create()
337
329
  return result;
338
330
  }
339
331
 
332
+ void
333
+ prof_call_infos_mark(prof_call_infos_t *call_infos)
334
+ {
335
+ prof_call_info_t **call_info;
336
+
337
+ if (call_infos->object)
338
+ rb_gc_mark(call_infos->object);
339
+
340
+ for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
341
+ {
342
+ prof_call_info_mark(*call_info);
343
+ }
344
+ }
345
+
340
346
  void
341
347
  prof_call_infos_free(prof_call_infos_t *call_infos)
342
348
  {
343
- xfree(call_infos->start);
344
- xfree(call_infos);
349
+ prof_call_info_t **call_info;
350
+
351
+ for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
352
+ {
353
+ prof_call_info_free(*call_info);
354
+ }
345
355
  }
346
356
 
347
357
  void
@@ -375,7 +385,6 @@ prof_call_infos_wrap(prof_call_infos_t *call_infos)
375
385
  return call_infos->object;
376
386
  }
377
387
 
378
-
379
388
  void rp_init_call_info()
380
389
  {
381
390
  /* CallInfo */
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #ifndef __RP_CALL_INFO_H__
@@ -37,6 +37,7 @@ typedef struct prof_call_infos_t
37
37
 
38
38
  void rp_init_call_info(void);
39
39
  prof_call_infos_t* prof_call_infos_create();
40
+ void prof_call_infos_mark(prof_call_infos_t *call_infos);
40
41
  void prof_call_infos_free(prof_call_infos_t *call_infos);
41
42
  void prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info);
42
43
  VALUE prof_call_infos_wrap(prof_call_infos_t *call_infos);
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #include "ruby_prof.h"
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #ifndef __RP_MEASUREMENT_H__
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  /* :nodoc: */
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #include "ruby_prof.h"
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  /* :nodoc: */
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  /* :nodoc: */
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  /* :nodoc: */
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #include "ruby_prof.h"
@@ -12,7 +12,7 @@ measure_process_time()
12
12
  #if defined(__linux__)
13
13
  struct timespec clock;
14
14
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID , &clock);
15
- return (clock.tv_sec * 1000000000 + clock.tv_nsec) / 1000000000.0;
15
+ return clock.tv_sec + (clock.tv_nsec/1000000000.0);
16
16
  #elif defined(_win32)
17
17
  FILETIME createTime;
18
18
  FILETIME exitTime;
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  /* :nodoc: */
@@ -11,7 +11,7 @@ measure_wall_time()
11
11
  {
12
12
  struct timeval tv;
13
13
  gettimeofday(&tv, NULL);
14
- return (tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.0;
14
+ return tv.tv_sec + (tv.tv_usec/1000000.0);
15
15
  }
16
16
 
17
17
  prof_measurer_t* prof_measurer_wall_time()
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #include "ruby_prof.h"
@@ -98,10 +98,12 @@ method_name(ID mid)
98
98
  {
99
99
  VALUE result;
100
100
 
101
- if (mid == ID_ALLOCATOR)
102
- result = rb_str_new2("allocate");
103
- else if (mid == 0)
101
+ if (mid == 0)
104
102
  result = rb_str_new2("[No method]");
103
+ #ifdef ID_ALLOCATOR
104
+ else if (mid == ID_ALLOCATOR)
105
+ result = rb_str_new2("allocate");
106
+ #endif
105
107
  else
106
108
  result = rb_String(ID2SYM(mid));
107
109
 
@@ -139,7 +141,6 @@ prof_method_create(VALUE klass, ID mid, const char* source_file, int line)
139
141
  prof_method_t *result = ALLOC(prof_method_t);
140
142
  result->object = Qnil;
141
143
  result->call_infos = prof_call_infos_create();
142
- result->call_infos2 = Qnil;
143
144
 
144
145
  result->key = ALLOC(prof_method_key_t);
145
146
  method_key(result->key, klass, mid);
@@ -188,6 +189,7 @@ prof_method_free(prof_method_t* method)
188
189
  {
189
190
  prof_method_ruby_gc_free(method);
190
191
  prof_call_infos_free(method->call_infos);
192
+ xfree(method->call_infos);
191
193
 
192
194
  xfree(method->key);
193
195
  method->key = NULL;
@@ -195,28 +197,13 @@ prof_method_free(prof_method_t* method)
195
197
  xfree(method);
196
198
  }
197
199
 
198
- /*static int
199
- mark_call_infos(st_data_t key, st_data_t value, st_data_t result)
200
- {
201
- prof_call_info_t *call_info = (prof_call_info_t *) value;
202
- prof_call_info_mark(call_info);
203
- return ST_CONTINUE;
204
- }
205
- */
206
-
207
200
  void
208
201
  prof_method_mark(prof_method_t *method)
209
202
  {
210
203
  if (method->object)
211
204
  rb_gc_mark(method->object);
212
205
 
213
- if (method->call_infos2)
214
- rb_gc_mark(method->call_infos2);
215
-
216
- if (method->call_infos->object)
217
- rb_gc_mark(method->call_infos->object);
218
-
219
- //st_foreach(method->call_info_table, mark_call_infos, NULL);
206
+ prof_call_infos_mark(method->call_infos);
220
207
  }
221
208
 
222
209
  VALUE
@@ -409,11 +396,11 @@ static VALUE
409
396
  prof_method_call_infos(VALUE self)
410
397
  {
411
398
  prof_method_t *method = get_prof_method(self);
412
- if (method->call_infos2 == Qnil)
399
+ if (method->call_infos->object == Qnil)
413
400
  {
414
- method->call_infos2 = prof_call_infos_wrap(method->call_infos);
401
+ method->call_infos->object = prof_call_infos_wrap(method->call_infos);
415
402
  }
416
- return method->call_infos2;
403
+ return method->call_infos->object;
417
404
  }
418
405
 
419
406
  void rp_init_method_info()
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #ifndef __RP_METHOD_INFO__
@@ -31,9 +31,8 @@ typedef struct
31
31
  prof_method_key_t *key; /* Method key */
32
32
  const char *source_file; /* The method's source file */
33
33
  int line; /* The method's line number. */
34
- struct prof_call_infos_t *call_infos; /* Call info objects for this method */
34
+ struct prof_call_infos_t *call_infos; /* Call info objects for this method */
35
35
  VALUE object; /* Cached ruby object */
36
- VALUE call_infos2; /* Cached array of RubyProf::CallInfo */
37
36
  } prof_method_t;
38
37
 
39
38
  void rp_init_method_info(void);
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #include "rp_stack.h"
@@ -43,7 +43,7 @@ prof_stack_free(prof_stack_t *stack)
43
43
  }
44
44
 
45
45
  prof_frame_t *
46
- prof_stack_push(prof_stack_t *stack)
46
+ prof_stack_push(prof_stack_t *stack, double measurement)
47
47
  {
48
48
  prof_frame_t* result = NULL;
49
49
 
@@ -64,7 +64,9 @@ prof_stack_push(prof_stack_t *stack)
64
64
  result->child_time = 0;
65
65
  result->switch_time = 0;
66
66
  result->wait_time = 0;
67
+ result->dead_time = 0;
67
68
  result->depth = (int)(stack->ptr - stack->start); // shortening of 64 bit into 32
69
+ result->start_time = measurement;
68
70
 
69
71
  // Increment the stack ptr for next time
70
72
  stack->ptr++;
@@ -74,12 +76,51 @@ prof_stack_push(prof_stack_t *stack)
74
76
  }
75
77
 
76
78
  prof_frame_t *
77
- prof_stack_pop(prof_stack_t *stack)
79
+ prof_stack_pop(prof_stack_t *stack, double measurement)
78
80
  {
79
- if (stack->ptr == stack->start)
80
- return NULL;
81
- else
82
- return --stack->ptr;
81
+ prof_frame_t *frame = NULL;
82
+ prof_frame_t* parent_frame = NULL;
83
+ prof_call_info_t *call_info;
84
+
85
+ double total_time;
86
+ double self_time;
87
+ #ifdef _MSC_VER
88
+ BOOL frame_paused;
89
+ #else
90
+ _Bool frame_paused;
91
+ #endif
92
+
93
+ /* Frame can be null. This can happen if RubProf.start is called from
94
+ a method that exits. And it can happen if an exception is raised
95
+ in code that is being profiled and the stack unwinds (RubyProf is
96
+ not notified of that by the ruby runtime. */
97
+ if (stack->ptr == stack->start)
98
+ return NULL;
99
+
100
+ frame = --stack->ptr;
101
+
102
+ /* Calculate the total time this method took */
103
+ prof_frame_unpause(frame, measurement);
104
+ total_time = measurement - frame->start_time - frame->dead_time;
105
+ self_time = total_time - frame->child_time - frame->wait_time;
106
+
107
+ /* Update information about the current method */
108
+ call_info = frame->call_info;
109
+ call_info->called++;
110
+ call_info->total_time += total_time;
111
+ call_info->self_time += self_time;
112
+ call_info->wait_time += frame->wait_time;
113
+
114
+ parent_frame = prof_stack_peek(stack);
115
+ if (parent_frame)
116
+ {
117
+ parent_frame->child_time += total_time;
118
+ parent_frame->dead_time += frame->dead_time;
119
+
120
+ call_info->line = parent_frame->line;
121
+ }
122
+
123
+ return frame;
83
124
  }
84
125
 
85
126
  prof_frame_t *
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #ifndef __RP_STACK__
@@ -44,8 +44,8 @@ typedef struct
44
44
 
45
45
  prof_stack_t * prof_stack_create();
46
46
  void prof_stack_free(prof_stack_t *stack);
47
- prof_frame_t * prof_stack_push(prof_stack_t *stack);
48
- prof_frame_t * prof_stack_pop(prof_stack_t *stack);
47
+ prof_frame_t * prof_stack_push(prof_stack_t *stack, double measurement);
48
+ prof_frame_t * prof_stack_pop(prof_stack_t *stack, double measurement);
49
49
  prof_frame_t * prof_stack_peek(prof_stack_t *stack);
50
50
 
51
51
  #endif //__RP_STACK__
@@ -1,4 +1,4 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
4
  #include "ruby_prof.h"
@@ -12,7 +12,6 @@ thread_data_create()
12
12
  thread_data_t* result = ALLOC(thread_data_t);
13
13
  result->stack = prof_stack_create();
14
14
  result->method_table = method_table_create();
15
- result->top = NULL;
16
15
  result->object = Qnil;
17
16
  result->methods = Qnil;
18
17
  return result;
@@ -42,7 +41,6 @@ static void
42
41
  thread_data_free(thread_data_t* thread_data)
43
42
  {
44
43
  thread_data_ruby_gc_free(thread_data);
45
- thread_data->top = NULL;
46
44
  method_table_free(thread_data->method_table);
47
45
  prof_stack_free(thread_data->stack);
48
46
 
@@ -68,7 +66,9 @@ prof_thread_mark(thread_data_t *thread)
68
66
  if (thread->methods != Qnil)
69
67
  rb_gc_mark(thread->methods);
70
68
 
71
- prof_method_mark(thread->top);
69
+ if (thread->thread_id != Qnil)
70
+ rb_gc_mark(thread->thread_id);
71
+
72
72
  st_foreach(thread->method_table, mark_methods, 0);
73
73
  }
74
74
 
@@ -179,6 +179,28 @@ switch_thread(void* prof, VALUE thread_id)
179
179
  return thread_data;
180
180
  }
181
181
 
182
+ int pause_thread(st_data_t key, st_data_t value, st_data_t data)
183
+ {
184
+ thread_data_t* thread_data = (thread_data_t *) value;
185
+ prof_profile_t* profile = (prof_profile_t*)data;
186
+
187
+ prof_frame_t* frame = prof_stack_peek(thread_data->stack);
188
+ prof_frame_pause(frame, profile->measurement_at_pause_resume);
189
+
190
+ return ST_CONTINUE;
191
+ }
192
+
193
+ int unpause_thread(st_data_t key, st_data_t value, st_data_t data)
194
+ {
195
+ thread_data_t* thread_data = (thread_data_t *) value;
196
+ prof_profile_t* profile = (prof_profile_t*)data;
197
+
198
+ prof_frame_t* frame = prof_stack_peek(thread_data->stack);
199
+ prof_frame_unpause(frame, profile->measurement_at_pause_resume);
200
+
201
+ return ST_CONTINUE;
202
+ }
203
+
182
204
  static int
183
205
  collect_methods(st_data_t key, st_data_t value, st_data_t result)
184
206
  {
@@ -220,18 +242,6 @@ prof_thread_methods(VALUE self)
220
242
  return thread->methods;
221
243
  }
222
244
 
223
- /* call-seq:
224
- method -> MethodInfo
225
-
226
- Returns the top level method for this thread (ie, the starting
227
- method). */
228
- static VALUE
229
- prof_thread_top_method(VALUE self)
230
- {
231
- thread_data_t* thread = prof_get_thread(self);
232
- return prof_method_wrap(thread->top);
233
- }
234
-
235
245
  void rp_init_thread()
236
246
  {
237
247
  cRpThread = rb_define_class_under(mProf, "Thread", rb_cObject);
@@ -239,5 +249,4 @@ void rp_init_thread()
239
249
 
240
250
  rb_define_method(cRpThread, "id", prof_thread_id, 0);
241
251
  rb_define_method(cRpThread, "methods", prof_thread_methods, 0);
242
- rb_define_method(cRpThread, "top_method", prof_thread_top_method, 0);
243
252
  }