stella 0.5.3 → 0.5.4
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/{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
|