ruby-prof 0.7.10 → 0.8.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.
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ 0.7.10 (2009-01-22)
2
+ =======================
3
+ * fix SEGFAULT in 1.9
4
+ * add new printer flat_printer_with_line_numbers
5
+
1
6
  0.7.7 (2009-01-13)
2
7
  ======================
3
8
  * "fix" multi threading support for 1.9 http://redmine.ruby-lang.org/issues/show/2012
data/Rakefile CHANGED
@@ -123,7 +123,7 @@ end
123
123
 
124
124
  require 'fileutils'
125
125
 
126
- desc 'Build ext/ruby_prof.so'
126
+ desc 'Build ruby_prof.so'
127
127
  task :build do
128
128
  build(false)
129
129
  end
@@ -144,7 +144,7 @@ def build(with_debug)
144
144
  end
145
145
 
146
146
  desc 'build ruby_prof.so with verbose symbols enabled'
147
- task :build_with_debug do
147
+ task :build_debug do
148
148
  build(true)
149
149
  end
150
150
 
data/bin/go.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'rubygems'
2
+ Gem::Specification
data/ext/ruby_prof.c CHANGED
@@ -884,9 +884,6 @@ get_event_name(rb_event_flag_t event)
884
884
  }
885
885
  #endif
886
886
 
887
-
888
- // these differ 1.9/1.8
889
-
890
887
  static prof_method_t*
891
888
  #ifdef RUBY_VM
892
889
  get_method(rb_event_flag_t event, VALUE klass, ID mid, int depth, st_table* method_table)
@@ -924,7 +921,6 @@ update_result(prof_measure_t total_time,
924
921
  prof_frame_t *frame)
925
922
  {
926
923
  prof_measure_t self_time = total_time - frame->child_time - frame->wait_time;
927
-
928
924
  prof_call_info_t *call_info = frame->call_info;
929
925
 
930
926
  /* Update information about the current method */
@@ -941,15 +937,15 @@ update_result(prof_measure_t total_time,
941
937
  static thread_data_t *
942
938
  switch_thread(VALUE thread_id, prof_measure_t now)
943
939
  {
944
- prof_frame_t *frame = NULL;
945
- prof_measure_t wait_time = 0;
940
+ prof_frame_t *frame = NULL;
941
+ prof_measure_t wait_time = 0;
946
942
  /* Get new thread information. */
947
943
  thread_data_t *thread_data = threads_table_lookup(threads_tbl, thread_id);
948
944
 
949
945
  /* How long has this thread been waiting? */
950
946
  wait_time = now - thread_data->last_switch;
951
947
 
952
- thread_data->last_switch = 0;
948
+ thread_data->last_switch = now; // XXXX a test that fails if this is 0
953
949
 
954
950
  /* Get the frame at the top of the stack. This may represent
955
951
  the current method (EVENT_LINE, EVENT_RETURN) or the
@@ -959,8 +955,6 @@ switch_thread(VALUE thread_id, prof_measure_t now)
959
955
  if (frame) {
960
956
  frame->wait_time += wait_time;
961
957
  }
962
-
963
-
964
958
 
965
959
  /* Save on the last thread the time of the context switch
966
960
  and reset this thread's last context switch to 0.*/
@@ -995,7 +989,7 @@ pop_frame(thread_data_t *thread_data, prof_measure_t now)
995
989
  parent_frame = stack_peek(thread_data->stack);
996
990
  if (parent_frame)
997
991
  {
998
- parent_frame->child_time += total_time;
992
+ parent_frame->child_time += total_time;
999
993
  }
1000
994
 
1001
995
  update_result(total_time, parent_frame, frame); // only time it's called
@@ -1024,18 +1018,19 @@ pop_frames(st_data_t key, st_data_t value, st_data_t now_arg)
1024
1018
  static void
1025
1019
  prof_pop_threads()
1026
1020
  {
1027
- /* Get current measurement*/
1021
+ /* Get current measurement */
1028
1022
  prof_measure_t now = get_measurement();
1029
1023
  st_foreach(threads_tbl, pop_frames, (st_data_t) &now);
1030
1024
  }
1031
1025
 
1032
1026
 
1033
1027
  #ifdef RUBY_VM
1028
+
1029
+ /* These are mostly to avoid bugs in core */
1030
+ static inline void walk_up_until_right_frame(prof_frame_t *frame, thread_data_t* thread_data, ID mid, VALUE klass, prof_measure_t now);
1034
1031
  void prof_install_hook();
1035
1032
  void prof_remove_hook();
1036
- #endif
1037
1033
 
1038
- #ifdef RUBY_VM
1039
1034
  static void
1040
1035
  prof_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE klass)
1041
1036
  #else
@@ -1049,15 +1044,15 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1049
1044
  thread_data_t* thread_data = NULL;
1050
1045
  prof_frame_t *frame = NULL;
1051
1046
 
1052
-
1053
- #ifdef RUBY_VM
1054
-
1055
- if (event != RUBY_EVENT_C_CALL && event != RUBY_EVENT_C_RETURN) {
1056
- // guess these are already set for C call in 1.9?
1047
+ #ifdef RUBY_VM
1048
+ if (event != RUBY_EVENT_C_CALL && event != RUBY_EVENT_C_RETURN) {
1049
+ // guess these are already set for C calls in 1.9, then?
1057
1050
  rb_frame_method_id_and_class(&mid, &klass);
1058
- }
1059
-
1060
- #endif
1051
+ }
1052
+ #endif
1053
+
1054
+ /* Get current timestamp */
1055
+ now = get_measurement();
1061
1056
 
1062
1057
  #ifdef DEBUG
1063
1058
  /* This code is here for debug purposes - uncomment it out
@@ -1068,9 +1063,9 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1068
1063
 
1069
1064
  VALUE thread = rb_thread_current();
1070
1065
  VALUE thread_id = rb_obj_id(thread);
1071
- char* class_name = NULL;
1072
- char* method_name = rb_id2name(mid);
1073
- char* source_file = rb_sourcefile();
1066
+ const char* class_name = NULL;
1067
+ const char* method_name = rb_id2name(mid);
1068
+ const char* source_file = rb_sourcefile();
1074
1069
  unsigned int source_line = rb_sourceline();
1075
1070
 
1076
1071
  char* event_name = get_event_name(event);
@@ -1083,9 +1078,9 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1083
1078
  if (last_thread_id != thread_id) {
1084
1079
  printf("\n");
1085
1080
  }
1086
-
1087
- printf("%2u: %-8s %s:%2d %s#%s\n",
1088
- thread_id, event_name, source_file, source_line, class_name, method_name);
1081
+
1082
+ printf("%2u:%2ums %-8s %s:%2d %s#%s\n",
1083
+ (unsigned int) thread_id, (unsigned int) now, event_name, source_file, source_line, class_name, method_name);
1089
1084
  fflush(stdout);
1090
1085
  last_thread_id = thread_id;
1091
1086
  }
@@ -1096,18 +1091,15 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1096
1091
  the results but aren't important to them results. */
1097
1092
  if (self == mProf) return;
1098
1093
 
1099
- /* Get current measurement*/
1100
- now = get_measurement();
1101
-
1102
1094
  /* Get the current thread information. */
1103
1095
  thread = rb_thread_current();
1104
1096
  thread_id = rb_obj_id(thread);
1105
1097
 
1106
- #ifdef RUBY_VM
1107
- /* ensure that new threads are hooked [sigh] */
1108
- prof_remove_hook();
1109
- prof_install_hook();
1110
- #endif
1098
+ # ifdef RUBY_VM
1099
+ /* ensure that new threads are hooked [sigh] (bug in core) */
1100
+ prof_remove_hook();
1101
+ prof_install_hook();
1102
+ # endif
1111
1103
 
1112
1104
  if (exclude_threads_tbl &&
1113
1105
  st_lookup(exclude_threads_tbl, (st_data_t) thread_id, 0))
@@ -1115,24 +1107,34 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1115
1107
  return;
1116
1108
  }
1117
1109
 
1110
+
1118
1111
  /* Was there a context switch? */
1119
1112
  if (!last_thread_data || last_thread_data->thread_id != thread_id)
1120
1113
  thread_data = switch_thread(thread_id, now);
1121
1114
  else
1122
1115
  thread_data = last_thread_data;
1123
1116
 
1124
- /* Get the current frame for the current thread. */
1125
- frame = stack_peek(thread_data->stack);
1126
-
1117
+
1127
1118
  switch (event) {
1128
1119
  case RUBY_EVENT_LINE:
1129
1120
  {
1130
1121
  /* Keep track of the current line number in this method. When
1131
1122
  a new method is called, we know what line number it was
1132
1123
  called from. */
1124
+
1125
+ /* Get the current frame for the current thread. */
1126
+ frame = stack_peek(thread_data->stack);
1127
+
1133
1128
  if (frame)
1134
1129
  {
1135
- frame->line = rb_sourceline();
1130
+ frame->line = rb_sourceline();
1131
+
1132
+ # ifdef RUBY_VM
1133
+ // disabled till I figure out why it causes
1134
+ // us to lose valuable frame information...maybe mid comes in wrong sometimes?
1135
+ // walk_up_until_right_frame(frame, thread_data, mid, klass, now);
1136
+ # endif
1137
+
1136
1138
  break;
1137
1139
  }
1138
1140
 
@@ -1143,6 +1145,8 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1143
1145
  case RUBY_EVENT_CALL:
1144
1146
  case RUBY_EVENT_C_CALL:
1145
1147
  {
1148
+ /* Get the current frame for the current thread. */
1149
+ frame = stack_peek(thread_data->stack);
1146
1150
  prof_call_info_t *call_info = NULL;
1147
1151
  prof_method_t *method = NULL;
1148
1152
 
@@ -1154,20 +1158,20 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1154
1158
  klass = (BUILTIN_TYPE(klass) == T_ICLASS ? RBASIC(klass)->klass : klass);
1155
1159
 
1156
1160
  /* Assume this is the first time we have called this method. */
1157
- #ifdef RUBY_VM
1158
- method = get_method(event, klass, mid, 0, thread_data->method_table);
1159
- #else
1160
- method = get_method(event, node, klass, mid, 0, thread_data->method_table);
1161
- #endif
1161
+ #ifdef RUBY_VM
1162
+ method = get_method(event, klass, mid, 0, thread_data->method_table);
1163
+ #else
1164
+ method = get_method(event, node, klass, mid, 0, thread_data->method_table);
1165
+ #endif
1162
1166
  /* Check for a recursive call */
1163
- while (method->active) // it's while because we start at 0 and then go down to the right depth
1167
+ while (method->active) // it's while because we start at 0 and then inc. to the right recursive depth
1164
1168
  {
1165
1169
  /* Yes, this method is already active somewhere up the stack */
1166
- #ifdef RUBY_VM
1167
- method = get_method(event, klass, mid, method->key->depth + 1, thread_data->method_table);
1168
- #else
1169
- method = get_method(event, node, klass, mid, method->key->depth + 1, thread_data->method_table);
1170
- #endif
1170
+ #ifdef RUBY_VM
1171
+ method = get_method(event, klass, mid, method->key->depth + 1, thread_data->method_table);
1172
+ #else
1173
+ method = get_method(event, node, klass, mid, method->key->depth + 1, thread_data->method_table);
1174
+ #endif
1171
1175
  }
1172
1176
  method->active = 1;
1173
1177
 
@@ -1195,27 +1199,35 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1195
1199
  frame->wait_time = 0;
1196
1200
  frame->child_time = 0;
1197
1201
  frame->line = rb_sourceline();
1198
-
1199
1202
  break;
1200
1203
  }
1201
1204
  case RUBY_EVENT_RETURN:
1202
1205
  case RUBY_EVENT_C_RETURN:
1203
- {
1204
- frame = pop_frame(thread_data, now);
1205
- #ifdef RUBY_VM
1206
- // we need to walk up the stack to find the right one [http://redmine.ruby-lang.org/issues/show/2610] (for now)
1207
- // sometimes frames don't have line and source somehow [like blank]
1208
- // if we hit one there's not much we can do...I guess...
1209
- // or maybe we don't have one because we're at the top or something.
1210
- while( frame && frame->call_info->target->key->mid && frame->call_info->target->key->klass && ((frame->call_info->target->key->mid != mid) || (frame->call_info->target->key->klass != klass))){
1211
- frame = pop_frame(thread_data, now);
1212
- }
1213
- #endif
1214
- break;
1215
- }
1206
+ {
1207
+ frame = pop_frame(thread_data, now);
1208
+
1209
+ # ifdef RUBY_VM
1210
+ // we need to walk up the stack to find the right one [http://redmine.ruby-lang.org/issues/show/2610] (for now)
1211
+ // sometimes frames don't have line and source somehow [like blank]
1212
+ // if we hit one there's not much we can do...I guess...
1213
+ // or maybe we don't have one because we're at the top or something.
1214
+ walk_up_until_right_frame(frame, thread_data, mid, klass, now);
1215
+ # endif
1216
+
1217
+ break;
1218
+ }
1216
1219
  }
1217
1220
  }
1218
1221
 
1222
+ #ifdef RUBY_VM
1223
+
1224
+ static inline void walk_up_until_right_frame(prof_frame_t *frame, thread_data_t* thread_data, ID mid, VALUE klass, prof_measure_t now) {
1225
+ // while it doesn't match, pop on up until we have found where we belong...
1226
+ while( frame && frame->call_info->target->key->mid && frame->call_info->target->key->klass && ((frame->call_info->target->key->mid != mid) || (frame->call_info->target->key->klass != klass))){
1227
+ frame = pop_frame(thread_data, now);
1228
+ }
1229
+ }
1230
+ #endif
1219
1231
 
1220
1232
  /* ======== ProfResult ============== */
1221
1233
 
@@ -1429,7 +1441,7 @@ prof_install_hook()
1429
1441
  rb_add_event_hook(prof_event_hook,
1430
1442
  RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
1431
1443
  RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN
1432
- | RUBY_EVENT_LINE, Qnil); // | RUBY_EVENT_SWITCH
1444
+ | RUBY_EVENT_LINE, Qnil); // RUBY_EVENT_SWITCH
1433
1445
  #else
1434
1446
  rb_add_event_hook(prof_event_hook,
1435
1447
  RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
data/ext/version.h CHANGED
@@ -1,4 +1,4 @@
1
- #define RUBY_PROF_VERSION "0.7.10"
1
+ #define RUBY_PROF_VERSION "0.8.1"
2
2
  #define RUBY_PROF_VERSION_MAJ 0
3
- #define RUBY_PROF_VERSION_MIN 7
4
- #define RUBY_PROF_VERSION_MIC 10
3
+ #define RUBY_PROF_VERSION_MIN 8
4
+ #define RUBY_PROF_VERSION_MIC 1
data/lib/ruby-prof.rb CHANGED
@@ -9,6 +9,7 @@ require "ruby-prof/graph_printer"
9
9
  require "ruby-prof/graph_html_printer"
10
10
  require "ruby-prof/call_tree_printer"
11
11
  require "ruby-prof/symbol_to_proc" # for 1.8's benefit
12
+ #require "ruby-prof/result"
12
13
 
13
14
  module RubyProf
14
15
  # See if the user specified the clock mode via
@@ -75,5 +75,4 @@ module RubyProf
75
75
  end
76
76
  end
77
77
  end
78
- end
79
-
78
+ end
@@ -1,5 +1,5 @@
1
1
  require 'ruby-prof/abstract_printer'
2
-
2
+ require 'pathname'
3
3
  module RubyProf
4
4
  # Generates flat[link:files/examples/flat_txt.html] profile reports as text.
5
5
  # To use the flat printer with line numbers:
@@ -31,7 +31,6 @@ module RubyProf
31
31
  @output << "Total: %0.6f\n" % total_time
32
32
  @output << "\n"
33
33
  @output << " %self total self wait child calls name\n"
34
-
35
34
  sum = 0
36
35
  methods.each do |method|
37
36
  self_percent = (method.self_time / total_time) * 100
@@ -48,14 +47,24 @@ module RubyProf
48
47
  method.wait_time, # wait
49
48
  method.children_time, # children
50
49
  method.called, # calls
51
- method_name(method), # name
52
- method.source_file, # filename
53
- method.line # line in said file
50
+ method_name(method), # name
54
51
  ]
55
52
  if method.source_file != 'ruby_runtime'
56
- @output << " %s:%s" % [method.source_file, method.line]
53
+ @output << " %s:%s" % [File.expand_path(method.source_file), method.line]
57
54
  end
58
- @output << "\n"
55
+ @output << "\n\tcalled from: "
56
+
57
+ # make sure they're unique
58
+ method.call_infos.map{|ci|
59
+ if ci.parent && ci.parent.target.source_file != 'ruby_runtime'
60
+ [method_name(ci.parent.target), File.expand_path(ci.parent.target.source_file), ci.parent.target.line]
61
+ else
62
+ nil
63
+ end
64
+ }.compact.uniq.each{|args|
65
+ @output << " %s (%s:%s) " % args
66
+ }
67
+ @output << "\n\n"
59
68
  end
60
69
  end
61
70
  end
data/test/basic_test.rb CHANGED
@@ -148,15 +148,15 @@ class BasicTest < Test::Unit::TestCase
148
148
 
149
149
  # Check times
150
150
  assert_in_delta(0.2, methods[0].total_time, 0.02)
151
- assert_in_delta(0, methods[0].wait_time, 0.01)
152
- assert_in_delta(0, methods[0].self_time, 0.01)
151
+ assert_in_delta(0, methods[0].wait_time, 0.02)
152
+ assert_in_delta(0, methods[0].self_time, 0.02)
153
153
 
154
154
  assert_in_delta(0.2, methods[1].total_time, 0.02)
155
- assert_in_delta(0, methods[1].wait_time, 0.01)
156
- assert_in_delta(0, methods[1].self_time, 0.01)
155
+ assert_in_delta(0, methods[1].wait_time, 0.02)
156
+ assert_in_delta(0, methods[1].self_time, 0.02)
157
157
 
158
158
  assert_in_delta(0.2, methods[2].total_time, 0.02)
159
- assert_in_delta(0, methods[2].wait_time, 0.01)
159
+ assert_in_delta(0, methods[2].wait_time, 0.02)
160
160
  assert_in_delta(0.2, methods[2].self_time, 0.02)
161
161
 
162
162
  assert_in_delta(0, methods[3].total_time, 0.01)
data/test/prime.rb CHANGED
@@ -54,5 +54,5 @@ def run_primes
54
54
  primes = find_primes(random_array)
55
55
 
56
56
  # Find the largest primes
57
- largest = find_largest(primes)
57
+ # largest = find_largest(primes)
58
58
  end
@@ -1,15 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'test/unit'
3
3
  require 'ruby-prof'
4
- require './prime'
4
+ require File.dirname(__FILE__) + '/prime'
5
5
 
6
6
  # -- Tests ----
7
7
  class PrintersTest < Test::Unit::TestCase
8
+
9
+ def go
10
+ run_primes
11
+ end
12
+
8
13
  def setup
9
- RubyProf::measure_mode = RubyProf::PROCESS_TIME
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME # WALL_TIME so we can use sleep in our test
10
15
  @result = RubyProf.profile do
11
16
  run_primes
17
+ go
12
18
  end
19
+
13
20
  end
14
21
 
15
22
  def test_printers
@@ -26,10 +33,8 @@ class PrintersTest < Test::Unit::TestCase
26
33
  printer.print
27
34
 
28
35
  printer = RubyProf::CallTreePrinter.new(@result)
29
- printer.print(STDOUT)
30
-
31
- # we should get here
32
- assert(true)
36
+ printer.print(STDOUT)
37
+ # we should get here
33
38
  end
34
39
 
35
40
  def test_flat_string
@@ -41,7 +46,7 @@ class PrintersTest < Test::Unit::TestCase
41
46
  output = ''
42
47
 
43
48
  printer = klass.new(@result)
44
- assert_nothing_raised { printer.print(output) }
49
+ printer.print(output)
45
50
 
46
51
  assert_match(/Thread ID: -?\d+/i, output)
47
52
  assert_match(/Total: \d+\.\d+/i, output)
@@ -53,12 +58,22 @@ class PrintersTest < Test::Unit::TestCase
53
58
  output = helper_test_flat_string RubyProf::FlatPrinterWithLineNumbers
54
59
  assert_match(/prime.rb/, output)
55
60
  assert_no_match(/ruby_runtime:0/, output)
61
+ assert_match(/called from/, output)
62
+
63
+ # should combine common parents
64
+ if RUBY_VERSION < '1.9'
65
+ assert_equal(3, output.scan(/Object#is_prime/).length)
66
+ else
67
+ # 1.9
68
+ assert_equal(2, output.scan(/Object#is_prime/).length)
69
+ end
70
+ assert_no_match(/\.\/test\/prime.rb/, output) # don't use relative paths
56
71
  end
57
72
 
58
73
  def test_graph_html_string
59
74
  output = ''
60
75
  printer = RubyProf::GraphHtmlPrinter.new(@result)
61
- assert_nothing_raised { printer.print(output) }
76
+ printer.print(output)
62
77
 
63
78
  assert_match( /DTD HTML 4\.01/i, output )
64
79
  assert_match( %r{<th>Total Time</th>}i, output )
@@ -68,7 +83,7 @@ class PrintersTest < Test::Unit::TestCase
68
83
  def test_graph_string
69
84
  output = ''
70
85
  printer = RubyProf::GraphPrinter.new(@result)
71
- assert_nothing_raised { printer.print(output) }
86
+ printer.print(output)
72
87
 
73
88
  assert_match( /Thread ID: -?\d+/i, output )
74
89
  assert_match( /Total Time: \d+\.\d+/i, output )
@@ -78,9 +93,38 @@ class PrintersTest < Test::Unit::TestCase
78
93
  def test_call_tree_string
79
94
  output = ''
80
95
  printer = RubyProf::CallTreePrinter.new(@result)
81
- assert_nothing_raised { printer.print(output) }
96
+ printer.print(output)
82
97
 
83
98
  assert_match(/fn=Object::find_primes/i, output)
84
- assert_match(/events: process_time/i, output)
99
+ assert_match(/events: wall_time/i, output)
100
+ end
101
+
102
+ def do_nothing
103
+ start = Time.now
104
+ while(Time.now == start)
105
+ end
85
106
  end
107
+
108
+ def test_all_with_small_percentiles
109
+
110
+ result = RubyProf.profile do
111
+ sleep 2
112
+ do_nothing
113
+ end
114
+
115
+ # RubyProf::CallTreePrinter doesn't "do" a min_percent
116
+ # RubyProf::FlatPrinter only outputs if self time > percent...
117
+ # RubyProf::FlatPrinterWithLineNumbers same
118
+ for klass in [ RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
119
+ puts klass
120
+ printer = klass.new(result)
121
+ out = ''
122
+ output = printer.print(out, :min_percent => 0.00000001 )
123
+ assert_match(/do_nothing/, out)
124
+ end
125
+
126
+ end
127
+
128
+
129
+
86
130
  end
@@ -57,10 +57,10 @@ class RecursiveTest < Test::Unit::TestCase
57
57
  method = methods[1]
58
58
  assert_equal('Object#simple', method.full_name)
59
59
  assert_equal(1, method.called)
60
- assert_in_delta(2, method.total_time, 0.01)
61
- assert_in_delta(0, method.self_time, 0.01)
62
- assert_in_delta(0, method.wait_time, 0.01)
63
- assert_in_delta(2, method.children_time, 0.01)
60
+ assert_in_delta(2, method.total_time, 0.02)
61
+ assert_in_delta(0, method.self_time, 0.02)
62
+ assert_in_delta(0, method.wait_time, 0.02)
63
+ assert_in_delta(2, method.children_time, 0.02)
64
64
 
65
65
  assert_equal(1, method.call_infos.length)
66
66
  call_info = method.call_infos[0]
data/test/stack_test.rb CHANGED
@@ -67,7 +67,7 @@ class StackTest < Test::Unit::TestCase
67
67
  method = methods[1]
68
68
  assert_equal('StackClass#a', method.full_name)
69
69
  assert_equal(1, method.called)
70
- assert_in_delta(8, method.total_time, 0.05)
70
+ assert_in_delta(8, method.total_time, 0.15)
71
71
  assert_in_delta(0, method.wait_time, 0.01)
72
72
  assert_in_delta(0, method.self_time, 0.01)
73
73
  assert_in_delta(8, method.children_time, 0.05)
data/test/thread_test.rb CHANGED
@@ -45,8 +45,12 @@ class ThreadTest < Test::Unit::TestCase
45
45
  end
46
46
 
47
47
  def test_thread_timings
48
- RubyProf.start
48
+ RubyProf.start
49
49
  thread = Thread.new do
50
+ sleep 0 # force it to hit thread.join, below, first
51
+ # thus forcing sleep(1), below, to be counted as (wall) self_time
52
+ # since we currently count time "in some other thread" as self.wait_time
53
+ # for whatever reason
50
54
  sleep(1)
51
55
  end
52
56
  thread.join
@@ -71,10 +75,10 @@ class ThreadTest < Test::Unit::TestCase
71
75
 
72
76
  method = methods[1]
73
77
  assert_equal('Kernel#sleep', method.full_name)
74
- assert_equal(1, method.called)
78
+ assert_equal(2, method.called)
75
79
  assert_in_delta(1, method.total_time, 0.01)
76
- assert_in_delta(0, method.self_time, 0.01)
77
- assert_in_delta(1.0, method.wait_time, 0.01)
80
+ assert_in_delta(1.0, method.self_time, 0.01)
81
+ assert_in_delta(0, method.wait_time, 0.01)
78
82
  assert_in_delta(0, method.children_time, 0.01)
79
83
 
80
84
  assert_equal(1, method.call_infos.length)
@@ -91,7 +95,7 @@ class ThreadTest < Test::Unit::TestCase
91
95
  assert_equal('ThreadTest#test_thread_timings', method.full_name)
92
96
  # the sub calls to Object#new, when popped,
93
97
  # cause the parent frame to be created for method #test_thread_timings, which means a +1 when it's popped in the end
94
- # xxxx a test that shows it the other way, too
98
+ # xxxx a test that shows it the other way, too (never creates parent frame--if that's even possible)
95
99
  assert_equal(1, method.called)
96
100
  assert_in_delta(1, method.total_time, 0.01)
97
101
  assert_in_delta(0, method.self_time, 0.05)
@@ -107,10 +111,8 @@ class ThreadTest < Test::Unit::TestCase
107
111
  assert_equal('Thread#join', method.full_name)
108
112
  assert_equal(1, method.called)
109
113
  assert_in_delta(1, method.total_time, 0.01)
110
- assert_in_delta(1.0, method.self_time, 0.01)
111
- # todo this is a bug since #sleep really isn't using self_time--it's sleep time!
112
- # but for our purposes...I guess that's ok for now...sure.
113
- assert_in_delta(0, method.wait_time, 0.01)
114
+ assert_in_delta(0, method.self_time, 0.01)
115
+ assert_in_delta(1.0, method.wait_time, 0.01)
114
116
  assert_in_delta(0, method.children_time, 0.01)
115
117
 
116
118
  assert_equal(1, method.call_infos.length)
@@ -145,6 +147,17 @@ class ThreadTest < Test::Unit::TestCase
145
147
  assert_equal(0, call_info.children.length)
146
148
  end
147
149
 
150
+ # useless test
151
+ def test_thread_back_and_forth
152
+ result = RubyProf.profile do
153
+ a = Thread.new { 100_000.times { sleep 0 }}
154
+ b = Thread.new { 100_000.times { sleep 0 }}
155
+ a.join
156
+ b.join
157
+ end
158
+ assert result.threads.values.flatten.sort[-1].total_time < 10 # 10s
159
+ end
160
+
148
161
  def test_thread
149
162
  result = RubyProf.profile do
150
163
  begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-prof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.10
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda, Charlie Savage, Roger Pack
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-22 00:00:00 -07:00
12
+ date: 2010-02-03 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,6 +42,7 @@ files:
42
42
  - README
43
43
  - LICENSE
44
44
  - CHANGES
45
+ - bin/go.rb
45
46
  - bin/ruby-prof
46
47
  - examples/flat.txt
47
48
  - examples/graph.html