ruby-prof 0.11.3 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
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
  }