stella 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/{README.txt → README.textile} +63 -40
- data/Rakefile +7 -5
- data/bin/stella +1 -1
- data/bin/stella.bat +12 -0
- data/lib/pcaplet.rb +180 -0
- data/lib/stella/adapter/ab.rb +57 -33
- data/lib/stella/adapter/base.rb +11 -1
- data/lib/stella/adapter/httperf.rb +13 -10
- data/lib/stella/adapter/pcap_watcher.rb +221 -0
- data/lib/stella/adapter/proxy_watcher.rb +76 -0
- data/lib/stella/adapter/siege.rb +28 -11
- data/lib/stella/cli/agents.rb +2 -2
- data/lib/stella/cli/base.rb +37 -1
- data/lib/stella/cli/localtest.rb +1 -2
- data/lib/stella/cli/sysinfo.rb +17 -0
- data/lib/stella/cli/watch.rb +278 -0
- data/lib/stella/cli.rb +23 -11
- data/lib/stella/command/base.rb +1 -10
- data/lib/stella/command/localtest.rb +43 -23
- data/lib/stella/data/domain.rb +75 -0
- data/lib/stella/data/http.rb +124 -0
- data/lib/stella/logger.rb +16 -5
- data/lib/stella/storable.rb +4 -2
- data/lib/stella/support.rb +71 -0
- data/lib/stella/sysinfo.rb +247 -0
- data/lib/stella/test/base.rb +5 -1
- data/lib/stella/test/definition.rb +1 -1
- data/lib/stella/test/run/summary.rb +14 -4
- data/lib/stella/text/resource.rb +0 -1
- data/lib/stella.rb +28 -10
- data/lib/utils/domainutil.rb +47 -0
- data/lib/utils/fileutil.rb +22 -3
- data/lib/utils/httputil.rb +184 -128
- data/lib/utils/mathutil.rb +20 -7
- data/lib/win32/Console/ANSI.rb +305 -0
- data/lib/win32/Console.rb +970 -0
- data/spec/show-agents_spec.rb +0 -0
- data/support/kvm.h +91 -0
- data/support/ruby-pcap-takuma-notes.txt +19 -0
- data/support/ruby-pcap-takuma-patch.txt +30 -0
- data/support/text/en.yaml +26 -3
- data/vendor/frylock/README.textile +72 -0
- data/vendor/frylock/bin/example +170 -0
- data/vendor/frylock/frylock.gemspec +18 -0
- data/vendor/frylock/lib/frylock/exceptions.rb +24 -0
- data/vendor/frylock/lib/frylock.rb +232 -0
- data/vendor/frylock/test/command_test.rb +33 -0
- data/vendor/hitimes-0.4.0/HISTORY +28 -0
- data/vendor/hitimes-0.4.0/LICENSE.txt +19 -0
- data/vendor/hitimes-0.4.0/README +80 -0
- data/vendor/hitimes-0.4.0/Rakefile +63 -0
- data/vendor/hitimes-0.4.0/examples/benchmarks.rb +86 -0
- data/vendor/hitimes-0.4.0/examples/stats.rb +29 -0
- data/vendor/hitimes-0.4.0/ext/extconf.rb +15 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_ext.c +21 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_clock_gettime.c +20 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_osx.c +16 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_windows.c +27 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_interval.c +340 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_interval.h +73 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_stats.c +242 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_stats.h +30 -0
- data/vendor/hitimes-0.4.0/ext/rbconfig-mingw.rb +178 -0
- data/vendor/hitimes-0.4.0/ext/rbconfig.rb +178 -0
- data/vendor/hitimes-0.4.0/gemspec.rb +54 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/mutexed_stats.rb +23 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/paths.rb +54 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/stats.rb +29 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/timer.rb +223 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/version.rb +42 -0
- data/vendor/hitimes-0.4.0/lib/hitimes.rb +24 -0
- data/vendor/hitimes-0.4.0/spec/interval_spec.rb +115 -0
- data/vendor/hitimes-0.4.0/spec/mutex_stats_spec.rb +34 -0
- data/vendor/hitimes-0.4.0/spec/paths_spec.rb +14 -0
- data/vendor/hitimes-0.4.0/spec/spec_helper.rb +6 -0
- data/vendor/hitimes-0.4.0/spec/stats_spec.rb +72 -0
- data/vendor/hitimes-0.4.0/spec/timer_spec.rb +105 -0
- data/vendor/hitimes-0.4.0/spec/version_spec.rb +27 -0
- data/vendor/hitimes-0.4.0/tasks/announce.rake +39 -0
- data/vendor/hitimes-0.4.0/tasks/config.rb +107 -0
- data/vendor/hitimes-0.4.0/tasks/distribution.rake +53 -0
- data/vendor/hitimes-0.4.0/tasks/documentation.rake +33 -0
- data/vendor/hitimes-0.4.0/tasks/extension.rake +64 -0
- data/vendor/hitimes-0.4.0/tasks/rspec.rake +31 -0
- data/vendor/hitimes-0.4.0/tasks/rubyforge.rake +52 -0
- data/vendor/hitimes-0.4.0/tasks/utils.rb +80 -0
- data/vendor/useragent/lib/user_agent.rb +1 -1
- metadata +87 -8
@@ -0,0 +1,232 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
require 'frylock/exceptions'
|
6
|
+
|
7
|
+
module Frylock
|
8
|
+
class Command
|
9
|
+
attr_reader :cmd, :index
|
10
|
+
def initialize(cmd, index, &b)
|
11
|
+
@cmd = (cmd.kind_of?(Symbol)) ? cmd.to_s : cmd
|
12
|
+
@index = index
|
13
|
+
@b = b
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(cmd_str, argv, stdin, global_options, options)
|
17
|
+
block_args = [options, argv, global_options, stdin, cmd_str, self]
|
18
|
+
@b.call(*block_args[0..(@b.arity-1)])
|
19
|
+
end
|
20
|
+
def to_s
|
21
|
+
@cmd.to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Frylock
|
27
|
+
extend self
|
28
|
+
|
29
|
+
FORWARDED_METHODS = %w(command before alias_command global_option global_usage usage option stdin default commands).freeze
|
30
|
+
|
31
|
+
def default(cmd)
|
32
|
+
@default_command = canonize(cmd)
|
33
|
+
end
|
34
|
+
|
35
|
+
def stdin(&b)
|
36
|
+
@stdin_block = b
|
37
|
+
end
|
38
|
+
def before(&b)
|
39
|
+
@before_block = b
|
40
|
+
end
|
41
|
+
|
42
|
+
# global_usage
|
43
|
+
# ex: usage "Usage: frylla [global options] command [command options]"
|
44
|
+
def global_usage(msg)
|
45
|
+
@global_opts_parser ||= OptionParser.new
|
46
|
+
@global_options ||= OpenStruct.new
|
47
|
+
|
48
|
+
@global_opts_parser.banner = msg
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
# process_arguments
|
54
|
+
#
|
55
|
+
# Split the +argv+ array into global args and command args and
|
56
|
+
# find the command name.
|
57
|
+
# i.e. ./script -H push -f (-H is a global arg, push is the command, -f is a command arg)
|
58
|
+
# returns [global_options, cmd, command_options, argv]
|
59
|
+
def process_arguments(argv)
|
60
|
+
global_options = command_options = {}
|
61
|
+
cmd = nil
|
62
|
+
|
63
|
+
global_parser = @global_opts_parser
|
64
|
+
|
65
|
+
global_options = global_parser.getopts(argv)
|
66
|
+
global_options = global_options.keys.inject({}) do |hash, key|
|
67
|
+
hash[key.to_sym] = global_options[key]
|
68
|
+
hash
|
69
|
+
end
|
70
|
+
|
71
|
+
cmd_name = (argv.empty?) ? @default_command : argv.shift
|
72
|
+
raise UnknownCommand.new(cmd_name) unless command?(cmd_name)
|
73
|
+
|
74
|
+
cmd = get_command(cmd_name)
|
75
|
+
command_parser = @command_opts_parser[cmd.index]
|
76
|
+
|
77
|
+
command_options = command_parser.getopts(argv) if (!argv.empty? && command_parser)
|
78
|
+
command_options = command_options.keys.inject({}) do |hash, key|
|
79
|
+
hash[key.to_sym] = command_options[key]
|
80
|
+
hash
|
81
|
+
end
|
82
|
+
|
83
|
+
[global_options, cmd_name, command_options, argv]
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
def usage(msg)
|
89
|
+
get_current_option_parser.banner = msg
|
90
|
+
end
|
91
|
+
|
92
|
+
# get_current_option_parser
|
93
|
+
#
|
94
|
+
# Grab the options parser for the current command or create it if it doesn't exist.
|
95
|
+
def get_current_option_parser
|
96
|
+
@command_opts_parser ||= []
|
97
|
+
@command_index ||= 0
|
98
|
+
(@command_opts_parser[@command_index] ||= OptionParser.new)
|
99
|
+
end
|
100
|
+
|
101
|
+
def global_option(*args, &b)
|
102
|
+
@global_opts_parser ||= OptionParser.new
|
103
|
+
args.unshift(@global_opts_parser)
|
104
|
+
option_parser(args, &b)
|
105
|
+
end
|
106
|
+
|
107
|
+
def option(*args, &b)
|
108
|
+
args.unshift(get_current_option_parser)
|
109
|
+
option_parser(args, &b)
|
110
|
+
end
|
111
|
+
|
112
|
+
# option_parser
|
113
|
+
#
|
114
|
+
# Processes calls to option and global_option. Symbols are converted into
|
115
|
+
# OptionParser style strings (:h and :help become '-h' and '--help'). If a
|
116
|
+
# class is included, it will tell OptionParser to expect a value otherwise
|
117
|
+
# it assumes a boolean value.
|
118
|
+
#
|
119
|
+
# +args+ is passed directly to OptionParser.on so it can contain anything
|
120
|
+
# that's valid to that method. Some examples:
|
121
|
+
# [:h, :help, "Displays this message"]
|
122
|
+
# [:m, :max, Integer, "Maximum threshold"]
|
123
|
+
# ['-l x,y,z', '--lang=x,y,z', Array, "Requested languages"]
|
124
|
+
def option_parser(args=[], &b)
|
125
|
+
return if args.empty?
|
126
|
+
opts_parser = args.shift
|
127
|
+
|
128
|
+
symbol_switches = []
|
129
|
+
args.each_with_index do |arg, index|
|
130
|
+
if arg.is_a? Symbol
|
131
|
+
args[index] = (arg.to_s.length == 1) ? "-#{arg.to_s}" : "--#{arg.to_s}"
|
132
|
+
symbol_switches << args[index]
|
133
|
+
elsif arg.kind_of?(Class)
|
134
|
+
symbol_switches.each do |arg|
|
135
|
+
arg << "=S"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if args.size == 1
|
141
|
+
opts_parser.on(args.shift)
|
142
|
+
else
|
143
|
+
opts_parser.on(*args) do |v|
|
144
|
+
block_args = [v, opts_parser]
|
145
|
+
result = (b.nil?) ? v : b.call(*block_args[0..(b.arity-1)])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def command(*cmds, &b)
|
151
|
+
@command_index ||= 0
|
152
|
+
@command_opts_parser ||= []
|
153
|
+
cmds.each do |cmd|
|
154
|
+
c = Command.new(cmd, @command_index, &b)
|
155
|
+
(@commands ||= {})[cmd] = c
|
156
|
+
end
|
157
|
+
|
158
|
+
@command_index += 1
|
159
|
+
end
|
160
|
+
|
161
|
+
def alias_command(aliaz, cmd)
|
162
|
+
return unless @commands.has_key? cmd
|
163
|
+
@commands[aliaz] = @commands[cmd]
|
164
|
+
end
|
165
|
+
|
166
|
+
def run!(argv, stdin=nil)
|
167
|
+
raise NoCommandsDefined.new unless @commands
|
168
|
+
@global_options, cmd_name, @command_options, argv = process_arguments(argv)
|
169
|
+
|
170
|
+
cmd_name ||= @default_command
|
171
|
+
|
172
|
+
raise UnknownCommand.new(cmd_name) unless command?(cmd_name)
|
173
|
+
|
174
|
+
stdin = (defined? @stdin_block) ? @stdin_block.call(stdin, []) : stdin
|
175
|
+
@before_block.call if defined? @before_block
|
176
|
+
|
177
|
+
|
178
|
+
call_command(cmd_name, argv, stdin)
|
179
|
+
|
180
|
+
|
181
|
+
rescue OptionParser::InvalidOption => ex
|
182
|
+
raise Frylock::InvalidArgument.new(ex.args)
|
183
|
+
rescue OptionParser::MissingArgument => ex
|
184
|
+
raise Frylock::MissingArgument.new(ex.args)
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
def call_command(cmd_str, argv=[], stdin=nil)
|
189
|
+
return unless command?(cmd_str)
|
190
|
+
get_command(cmd_str).call(cmd_str, argv, stdin, @global_options, @command_options)
|
191
|
+
end
|
192
|
+
|
193
|
+
def get_command(cmd)
|
194
|
+
return unless command?(cmd)
|
195
|
+
@commands[canonize(cmd)]
|
196
|
+
end
|
197
|
+
|
198
|
+
def commands
|
199
|
+
@commands
|
200
|
+
end
|
201
|
+
|
202
|
+
def run
|
203
|
+
@run || true
|
204
|
+
end
|
205
|
+
|
206
|
+
def run=(v)
|
207
|
+
@run = v
|
208
|
+
end
|
209
|
+
|
210
|
+
def command?(cmd)
|
211
|
+
name = canonize(cmd)
|
212
|
+
(@commands || {}).has_key? name
|
213
|
+
end
|
214
|
+
def canonize(cmd)
|
215
|
+
return unless cmd
|
216
|
+
return cmd if cmd.kind_of?(Symbol)
|
217
|
+
cmd.tr('-', '_').to_sym
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
Frylock::FORWARDED_METHODS.each do |m|
|
223
|
+
eval(<<-end_eval, binding, "(Frylock)", __LINE__)
|
224
|
+
def #{m}(*args, &b)
|
225
|
+
Frylock.#{m}(*args, &b)
|
226
|
+
end
|
227
|
+
end_eval
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../lib/frylock"
|
2
|
+
require "rubygems"
|
3
|
+
require "test/spec"
|
4
|
+
require "mocha"
|
5
|
+
|
6
|
+
class Test::Unit::TestCase
|
7
|
+
def test_command(cmd, argv, &b)
|
8
|
+
Frylock::Command.new(cmd, &b).call(argv)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
Frylock.run = false
|
13
|
+
|
14
|
+
context "command" do
|
15
|
+
|
16
|
+
setup { @mock = mock() }
|
17
|
+
|
18
|
+
specify "should know a symbol is the full command name" do
|
19
|
+
@mock.expects(:called).with()
|
20
|
+
test_command(:foo, ['foo']) { @mock.called }
|
21
|
+
end
|
22
|
+
|
23
|
+
specify "should know only send params needed by block" do
|
24
|
+
@mock.expects(:called).with('bar')
|
25
|
+
test_command(:foo, ['foo', 'bar']) { |a| @mock.called(a) }
|
26
|
+
end
|
27
|
+
|
28
|
+
specify "should know only send params needed by block 2" do
|
29
|
+
@mock.expects(:called).with('bar', 'baz')
|
30
|
+
test_command(:foo, ['foo', 'bar', 'baz']) { |a,b| @mock.called(a,b) }
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
= Changelog
|
2
|
+
== Version 0.4.0 2008-12-20
|
3
|
+
|
4
|
+
* Added new stat 'rate'
|
5
|
+
* Added new stat method to_hash
|
6
|
+
* Added MutexedStats class for threadsafe stats collection
|
7
|
+
- not needed when used in MRI 1.8.x
|
8
|
+
* remove stale dependency on mkrf
|
9
|
+
|
10
|
+
== Version 0.3.0
|
11
|
+
|
12
|
+
* switched to extconf for building extensions
|
13
|
+
* first release of windows binary gem
|
14
|
+
* reverted back to normal rdoc
|
15
|
+
|
16
|
+
== Version 0.2.1
|
17
|
+
|
18
|
+
* added Timer#rate method
|
19
|
+
* switched to darkfish rdoc
|
20
|
+
|
21
|
+
== Version 0.2.0
|
22
|
+
|
23
|
+
* Performance improvements
|
24
|
+
* Added Stats class
|
25
|
+
|
26
|
+
== Version 0.1.0
|
27
|
+
|
28
|
+
* Initial completion
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008 Jeremy Hinegardner
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
@@ -0,0 +1,80 @@
|
|
1
|
+
== hitimes
|
2
|
+
|
3
|
+
* Homepage[http://copiousfreetime.rubyforge.org/hitimes]
|
4
|
+
* {Rubyforge project}[http://rubyforge.org/projects/copiousfreetime/]
|
5
|
+
* email jeremy at copiousfreetime dot org
|
6
|
+
* git clone url git://github.com/copiousfreetime/hitimes.git
|
7
|
+
|
8
|
+
== INSTALL
|
9
|
+
|
10
|
+
* gem install hitimes
|
11
|
+
|
12
|
+
== DESCRIPTION
|
13
|
+
|
14
|
+
Hitimes is a fast, high resolution timer library for recording
|
15
|
+
performance metrics. It uses the appropriate C method calls for each
|
16
|
+
system to get the highest granularity time increments possible.
|
17
|
+
|
18
|
+
It currently supports any system with the POSIX call clock_gettime(),
|
19
|
+
Mac OS X and Windows.
|
20
|
+
|
21
|
+
Using Hitimes can be faster than using a series of Time.new calls, and
|
22
|
+
it will have a much higher granularity. It is definitely faster than
|
23
|
+
using Process.times.
|
24
|
+
|
25
|
+
== SYNOPSIS
|
26
|
+
|
27
|
+
Use Hitimes::Interval to calculate only the duration of a block of code
|
28
|
+
|
29
|
+
duration = Hitimes::Interval.measure do
|
30
|
+
# some operation ...
|
31
|
+
end
|
32
|
+
|
33
|
+
puts duration
|
34
|
+
|
35
|
+
Use a Hitimes::Timer to calculate statistics about an iterative operation
|
36
|
+
|
37
|
+
timer = Hitimes::Timer.new
|
38
|
+
collection.each do |item|
|
39
|
+
timer.start
|
40
|
+
# .. do something with item
|
41
|
+
timer.stop
|
42
|
+
end
|
43
|
+
|
44
|
+
puts timer.mean
|
45
|
+
puts timer.median
|
46
|
+
puts timer.max
|
47
|
+
puts timer.min
|
48
|
+
puts timer.stddev
|
49
|
+
puts timer.rate
|
50
|
+
|
51
|
+
|
52
|
+
== CHANGES
|
53
|
+
|
54
|
+
Read the HISTORY file.
|
55
|
+
|
56
|
+
== CREDITS
|
57
|
+
|
58
|
+
* Bruce Williams for suggesting the idea
|
59
|
+
|
60
|
+
== MIT LICENSE
|
61
|
+
|
62
|
+
Copyright (c) 2008 Jeremy Hinegardner
|
63
|
+
|
64
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
65
|
+
this software and associated documentation files (the "Software"), to deal in
|
66
|
+
the Software without restriction, including without limitation the rights to
|
67
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
68
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
69
|
+
so, subject to the following conditions:
|
70
|
+
|
71
|
+
The above copyright notice and this permission notice shall be included in all
|
72
|
+
copies or substantial portions of the Software.
|
73
|
+
|
74
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
75
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
76
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
77
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
78
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
79
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
80
|
+
SOFTWARE.
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2008 Jeremy Hinegardner
|
3
|
+
# All rights reserved. See LICENSE and/or COPYING for details.
|
4
|
+
#++
|
5
|
+
|
6
|
+
#-------------------------------------------------------------------------------
|
7
|
+
# make sure our project's top level directory and the lib directory are added to
|
8
|
+
# the ruby search path.
|
9
|
+
#-------------------------------------------------------------------------------
|
10
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"ext"))
|
11
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__),"lib"))
|
12
|
+
$: << File.expand_path(File.dirname(__FILE__))
|
13
|
+
|
14
|
+
|
15
|
+
#-------------------------------------------------------------------------------
|
16
|
+
# load the global project configuration and add in the top level clean and
|
17
|
+
# clobber tasks so that other tasks can utilize those constants if necessary
|
18
|
+
# This loads up the defaults for the whole project configuration
|
19
|
+
#-------------------------------------------------------------------------------
|
20
|
+
require 'rubygems'
|
21
|
+
require 'tasks/config.rb'
|
22
|
+
require 'rake/clean'
|
23
|
+
|
24
|
+
#-------------------------------------------------------------------------------
|
25
|
+
# Main configuration for the project, these overwrite the items that are in
|
26
|
+
# tasks/config.rb
|
27
|
+
#-------------------------------------------------------------------------------
|
28
|
+
require 'hitimes/version'
|
29
|
+
require 'hitimes/paths'
|
30
|
+
|
31
|
+
Configuration.for("project") {
|
32
|
+
name "hitimes"
|
33
|
+
version Hitimes::VERSION
|
34
|
+
author "Jeremy Hinegardner"
|
35
|
+
email "jeremy@copiousfreetime.org"
|
36
|
+
homepage "http://copiousfreetime.rubyforge.org/hitimes/"
|
37
|
+
}
|
38
|
+
|
39
|
+
#-------------------------------------------------------------------------------
|
40
|
+
# load up all the project tasks and setup the default task to be the
|
41
|
+
# test:default task.
|
42
|
+
#-------------------------------------------------------------------------------
|
43
|
+
Configuration.for("packaging").files.tasks.each do |tasklib|
|
44
|
+
import tasklib
|
45
|
+
end
|
46
|
+
task :default => 'test:default'
|
47
|
+
|
48
|
+
#-------------------------------------------------------------------------------
|
49
|
+
# Finalize the loading of all pending imports and update the top level clobber
|
50
|
+
# task to depend on all possible sub-level tasks that have a name like
|
51
|
+
# ':clobber' in other namespaces. This allows us to say:
|
52
|
+
#
|
53
|
+
# rake clobber
|
54
|
+
#
|
55
|
+
# and it will get everything.
|
56
|
+
#-------------------------------------------------------------------------------
|
57
|
+
Rake.application.load_imports
|
58
|
+
Rake.application.tasks.each do |t|
|
59
|
+
if t.name =~ /:clobber/ then
|
60
|
+
task :clobber => [t.name]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
#
|
5
|
+
# this is all here in case this example is run from the examples directory
|
6
|
+
#
|
7
|
+
begin
|
8
|
+
require 'hitimes'
|
9
|
+
rescue LoadError => le
|
10
|
+
ext_path = File.expand_path( File.join( File.dirname( __FILE__ ), "..", "ext" ) )
|
11
|
+
lib_path = File.expand_path( File.join( File.dirname( __FILE__ ), "..", "lib" ) )
|
12
|
+
if $:.include?( ext_path ) then
|
13
|
+
raise le
|
14
|
+
end
|
15
|
+
$: << ext_path
|
16
|
+
$: << lib_path
|
17
|
+
retry
|
18
|
+
end
|
19
|
+
|
20
|
+
#----------------------------------------------------------------------
|
21
|
+
# test program to look at the performance sampling time durations using
|
22
|
+
# different methods
|
23
|
+
#----------------------------------------------------------------------
|
24
|
+
|
25
|
+
include Benchmark
|
26
|
+
|
27
|
+
#
|
28
|
+
# Normal apprach to Interval usage
|
29
|
+
#
|
30
|
+
def hitimes_duration_i1
|
31
|
+
i = Hitimes::Interval.new
|
32
|
+
i.start
|
33
|
+
i.stop
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Use the easy access method to start stop an interval
|
38
|
+
#
|
39
|
+
def hitimes_duration_i2
|
40
|
+
Hitimes::Interval.now.stop
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Use a new timer each time
|
45
|
+
#
|
46
|
+
def hitimes_duration_t1
|
47
|
+
Hitimes::Timer.now.stop
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# reuse the same timer over and over
|
52
|
+
#
|
53
|
+
HT = Hitimes::Timer.new
|
54
|
+
def hitimes_duration_t2
|
55
|
+
HT.start
|
56
|
+
HT.stop
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# use the Struct::Tms values and return the difference in User time between 2
|
61
|
+
# successive calls
|
62
|
+
#
|
63
|
+
def process_duration
|
64
|
+
t1 = Process.times.utime
|
65
|
+
Process.times.utime - t1
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Take 2 times and subtract one from the other
|
70
|
+
#
|
71
|
+
def time_duration
|
72
|
+
t1 = Time.now.to_f
|
73
|
+
Time.now.to_f - t1
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
puts "Testing time sampling 100,000 times"
|
78
|
+
|
79
|
+
bm(20) do |x|
|
80
|
+
x.report("Process") { 100_000.times { process_duration } }
|
81
|
+
x.report("Time") { 100_000.times { time_duration } }
|
82
|
+
x.report("Hitimes::Timer 1") { 100_000.times { hitimes_duration_t1 } }
|
83
|
+
x.report("Hitimes::Timer 2") { 100_000.times { hitimes_duration_t2 } }
|
84
|
+
x.report("Hitimes::Interval 1") { 100_000.times { hitimes_duration_i1 } }
|
85
|
+
x.report("Hitimes::Interval 2") { 100_000.times { hitimes_duration_i2 } }
|
86
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# this is all here in case this example is run from the examples directory
|
3
|
+
#
|
4
|
+
begin
|
5
|
+
require 'hitimes'
|
6
|
+
rescue LoadError => le
|
7
|
+
%w[ ext lib ].each do |p|
|
8
|
+
path = File.expand_path( File.join( File.dirname( __FILE__ ), "..", p ) )
|
9
|
+
if $:.include?( path ) then
|
10
|
+
raise le
|
11
|
+
end
|
12
|
+
$: << path
|
13
|
+
end
|
14
|
+
retry
|
15
|
+
end
|
16
|
+
|
17
|
+
s = Hitimes::Stats.new
|
18
|
+
dir = ARGV.shift || Dir.pwd
|
19
|
+
Dir.entries( dir ).each do |entry|
|
20
|
+
fs = File.stat( entry )
|
21
|
+
if fs.file? then
|
22
|
+
s.update( fs.size )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
%w[ count min max mean sum stddev ].each do |m|
|
27
|
+
puts "#{m.rjust(6)} : #{s.send( m ) }"
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
if Config::CONFIG['host_os'] =~ /darwin/ then
|
5
|
+
$CFLAGS += " -DUSE_INSTANT_OSX=1 -Wall"
|
6
|
+
$LDFLAGS += " -framework CoreServices"
|
7
|
+
elsif Config::CONFIG['host_os'] =~ /win32/ or Config::CONFIG['host_os'] =~ /mingw/ then
|
8
|
+
$CFLAGS += " -DUSE_INSTANT_WINDOWS=1"
|
9
|
+
else
|
10
|
+
if have_library("rt", "clock_gettime") then
|
11
|
+
$CFLAGS += " -DUSE_INSTANT_CLOCK_GETTIME=1"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
create_makefile('hitimes_ext')
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "hitimes_interval.h"
|
3
|
+
|
4
|
+
/* Module and Classes */
|
5
|
+
VALUE mH; /* module Hitimes */
|
6
|
+
VALUE eH_Error; /* class Hitimes::Error */
|
7
|
+
|
8
|
+
/*
|
9
|
+
* Document-class: Hitimes::Error
|
10
|
+
*
|
11
|
+
* General error class for the Hitimes module
|
12
|
+
*/
|
13
|
+
void Init_hitimes_ext( )
|
14
|
+
{
|
15
|
+
mH = rb_define_module("Hitimes");
|
16
|
+
|
17
|
+
eH_Error = rb_define_class_under(mH, "Error", rb_eStandardError);
|
18
|
+
|
19
|
+
Init_hitimes_interval();
|
20
|
+
Init_hitimes_stats( );
|
21
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#ifdef USE_INSTANT_CLOCK_GETTIME
|
2
|
+
|
3
|
+
#include "hitimes_interval.h"
|
4
|
+
|
5
|
+
#include <sys/time.h>
|
6
|
+
|
7
|
+
hitimes_instant_t hitimes_get_current_instant( )
|
8
|
+
{
|
9
|
+
struct timespec time;
|
10
|
+
int rc;
|
11
|
+
|
12
|
+
rc = clock_gettime( CLOCK_MONOTONIC, &time);
|
13
|
+
if ( 0 != rc ) {
|
14
|
+
char* e = strerror( rc );
|
15
|
+
rb_raise(eH_Error, "Unable to retrieve time for CLOCK_MONOTONIC : %s", e );
|
16
|
+
}
|
17
|
+
|
18
|
+
return ( ( NANOSECONDS_PER_SECOND * (long)time.tv_sec ) + time.tv_nsec );
|
19
|
+
}
|
20
|
+
#endif
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#ifdef USE_INSTANT_OSX
|
2
|
+
|
3
|
+
#include "hitimes_interval.h"
|
4
|
+
#include <CoreServices/CoreServices.h>
|
5
|
+
|
6
|
+
/*
|
7
|
+
* returns the number of nanoseconds since the machine was booted
|
8
|
+
*/
|
9
|
+
hitimes_instant_t hitimes_get_current_instant( )
|
10
|
+
{
|
11
|
+
Nanoseconds nano = AbsoluteToNanoseconds( UpTime() );
|
12
|
+
|
13
|
+
return *( hitimes_instant_t *)&nano;
|
14
|
+
}
|
15
|
+
|
16
|
+
#endif
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#ifdef USE_INSTANT_WINDOWS
|
2
|
+
|
3
|
+
#include "hitimes_interval.h"
|
4
|
+
|
5
|
+
|
6
|
+
/*
|
7
|
+
* returns the conversion factor, this value is used to convert
|
8
|
+
* the value from hitimes_get_current_instant() into seconds
|
9
|
+
*/
|
10
|
+
double hitimes_instant_conversion_factor()
|
11
|
+
{
|
12
|
+
LARGE_INTEGER ticks_per_second;
|
13
|
+
QueryPerformanceFrequency( &ticks_per_second );
|
14
|
+
return (double)ticks_per_second.QuadPart;
|
15
|
+
}
|
16
|
+
|
17
|
+
/*
|
18
|
+
* returns the number of ticks
|
19
|
+
*/
|
20
|
+
hitimes_instant_t hitimes_get_current_instant()
|
21
|
+
{
|
22
|
+
LARGE_INTEGER tick;
|
23
|
+
QueryPerformanceCounter(&tick);
|
24
|
+
return (hitimes_instant_t)tick.QuadPart;
|
25
|
+
}
|
26
|
+
|
27
|
+
#endif
|