sampling_prof 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e74f789ae7dba019462c771325081151d194206
4
- data.tar.gz: 00ee209871452f5fa34f62e973db2d801e6e27b2
3
+ metadata.gz: 3d1357aece706366d12fac2c1670ded8f2bdd24f
4
+ data.tar.gz: 12077ea8a42b5ca17c38df2875aab9c6234e9955
5
5
  SHA512:
6
- metadata.gz: eda0c06539ea65d5a9159cbee26b047f123fd73142cbff761f7b665d90cd97e81ae12fb4718698a86b584a9787f5d02186d3f4eae323468faf4405eb8eb8bb05
7
- data.tar.gz: b3a9f7a9900abd607deb03b669b5721b01a81f3ad2f81cb71ee241e3630ea46c622782786f76af53c34eea34a1ec6fc2b80d641e838a99c4cfd2d99d359e9e46
6
+ metadata.gz: 4fd426493b203256f040399daf7e3c69e3ce44b5428d420b6d70900036cc3cd5d8910d5f2e6d16c7db5ee40894ed4f8f156a5749fd23676cb6b9055bed166586
7
+ data.tar.gz: 65c57574670f4385e0b9f68a994bc33c01766e18b4025ee768292a22a8954662e7cc58f2267dcfc9b276f8f7856f3860c9b4f77be10ef0c51ad1813a7bad01bd
Binary file
data/lib/sampling_prof.rb CHANGED
@@ -9,6 +9,17 @@ class SamplingProf
9
9
 
10
10
  attr_writer :output_file
11
11
 
12
+ def initialize(sampling_interval=0.1,
13
+ multithreading=false,
14
+ output_interval=nil, #sec
15
+ &output_handler)
16
+ self.sampling_interval = sampling_interval
17
+ self.multithreading = multithreading
18
+ self.output_interval = output_interval || (multithreading ? 60 : nil)
19
+ self.output_handler = block_given? ? output_handler : default_output_handler
20
+ internal_initialize if respond_to?(:internal_initialize)
21
+ end
22
+
12
23
  def output_file
13
24
  @output_file ||= DEFAULT_OUTPUT_FILE
14
25
  end
@@ -20,28 +31,10 @@ class SamplingProf
20
31
  stop if block_given?
21
32
  end
22
33
 
23
- def start(handler=default_output_handler)
24
- __start__(&handler)
25
- end
26
-
27
34
  def default_output_handler
28
35
  lambda do |data|
29
- nodes, counts, call_graph = data
30
36
  File.open(output_file, 'w') do |f|
31
- nodes.each do |node|
32
- # node name, node id
33
- f.puts node.join(',')
34
- end
35
- f.puts ""
36
- counts.each do |count|
37
- # node id, count
38
- f.puts count.flatten.join(",")
39
- end
40
- f.puts ""
41
- call_graph.each do |v|
42
- # from node id, to node id, count
43
- f.puts v.flatten.join(",")
44
- end
37
+ f.write(data)
45
38
  end
46
39
  end
47
40
  end
@@ -1,40 +1,47 @@
1
+ require 'set'
2
+ require 'thread'
1
3
 
2
4
  class SamplingProf
3
- class Sample < Struct.new(:self, :total)
4
- end
5
-
6
5
  class Sampling
7
- def initialize
6
+ def initialize(threads)
8
7
  @samples = Hash.new{|h,k| h[k] = [0, 0] }
9
8
  @call_graph = Hash.new{|h,k| h[k] = 0}
10
9
  @nodes = {}
10
+ @threads = threads
11
11
  end
12
12
 
13
13
  def result
14
- [@nodes.to_a, @samples.to_a, @call_graph.to_a]
14
+ ret = []
15
+ ret << @nodes.map {|node| node.join(',')}.join("\n")
16
+ ret << @samples.map {|count| count.flatten.join(',')}.join("\n")
17
+ ret << @call_graph.map {|v| v.flatten.join(',')}.join("\n")
18
+ "#{ret.join("\n\n")}\n"
15
19
  end
16
20
 
17
- def process(locations)
18
- from = -1
19
- paths = []
20
- calls = []
21
- top_index = locations.size - 1
22
- locations.reverse.each_with_index do |loc, i|
23
- node_id = node_id(loc)
24
- if i == top_index
25
- @samples[node_id][0] += 1
26
- end
21
+ def process
22
+ @threads.each do |thread|
23
+ locations = thread.backtrace_locations
24
+ from = -1
25
+ paths = []
26
+ calls = []
27
+ top_index = locations.size - 1
28
+ locations.reverse.each_with_index do |loc, i|
29
+ node_id = node_id(loc)
30
+ if i == top_index
31
+ @samples[node_id][0] += 1
32
+ end
27
33
 
28
- path = [from, node_id]
29
- if !paths.include?(path)
30
- paths << path
31
- @call_graph[path] += 1
32
- end
33
- if !calls.include?(node_id)
34
- calls << node_id
35
- @samples[node_id][1] += 1
34
+ path = [from, node_id]
35
+ if !paths.include?(path)
36
+ paths << path
37
+ @call_graph[path] += 1
38
+ end
39
+ if !calls.include?(node_id)
40
+ calls << node_id
41
+ @samples[node_id][1] += 1
42
+ end
43
+ from = node_id
36
44
  end
37
- from = node_id
38
45
  end
39
46
  end
40
47
 
@@ -47,24 +54,56 @@ class SamplingProf
47
54
  end
48
55
  end
49
56
 
50
- def initialize(period)
51
- @period = period
57
+ class Threads
58
+ def initialize
59
+ @set = Set.new
60
+ @mutex = Mutex.new
61
+ end
62
+
63
+ def each(&block)
64
+ dup.each(&block)
65
+ end
66
+
67
+ def dup
68
+ @mutex.synchronize { @set.dup }
69
+ end
70
+
71
+ def add(obj)
72
+ @mutex.synchronize { @set.add(obj) }
73
+ end
74
+
75
+ def delete(obj)
76
+ @mutex.synchronize { @set.delete(obj) }
77
+ end
78
+ end
79
+
80
+ attr_accessor :sampling_interval, :multithreading, :output_interval, :output_handler
81
+
82
+ def internal_initialize
52
83
  @running = false
53
84
  @sampling_thread = nil
85
+ @threads = Threads.new
54
86
  end
55
87
 
56
- def __start__(&block)
57
- unless @running
88
+ def start
89
+ if @multithreading || !@running
58
90
  @running = true
59
- target = Thread.current
60
- @sampling_thread = Thread.start do
61
- sampling = Sampling.new
91
+ @threads.add(Thread.current)
92
+ @sampling_thread ||= Thread.start do
62
93
  loop do
94
+ sampling = Sampling.new(@threads)
95
+ start_time = Time.now
96
+ loop do
97
+ break unless @running
98
+ if @multithreading
99
+ break if output_interval < (Time.now - start_time)
100
+ end
101
+ sampling.process
102
+ sleep @sampling_interval
103
+ end
104
+ @output_handler.call(sampling.result)
63
105
  break unless @running
64
- sampling.process(target.backtrace_locations)
65
- sleep @period
66
106
  end
67
- block.call(sampling.result)
68
107
  end
69
108
  true
70
109
  end
@@ -72,13 +111,22 @@ class SamplingProf
72
111
 
73
112
  def stop
74
113
  if @running
75
- @running = false
76
- @sampling_thread.join
77
- @sampling_thread = nil
114
+ if @multithreading
115
+ @threads.delete(Thread.current)
116
+ else
117
+ terminate
118
+ end
78
119
  true
79
120
  end
80
121
  end
81
122
 
123
+ def terminate
124
+ @running = false
125
+ @sampling_thread.join
126
+ @sampling_thread = nil
127
+ true
128
+ end
129
+
82
130
  def profiling?
83
131
  !!@sampling_thread
84
132
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sampling_prof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xiao Li
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2014-03-22 00:00:00 Z
12
+ date: 2014-03-23 00:00:00 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler