tunemygc 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4401c1469c2636840a42026092dcd8d682d8825f
4
+ data.tar.gz: 5e44ddbc6336a4683b155393087bc8d39bc95cba
5
+ SHA512:
6
+ metadata.gz: 294670fabab8fa5203a580b6a4182ebb888d83d52710dfe8f82fb5545b6daefdeb3dad21d72c16b7bc2c6f0f0b3cc5ccd73d65bac3512468dd1c383f21a58568
7
+ data.tar.gz: 6bac1f88cad71533a4731332526dabc49e3b60b2d77c68a133dc7b6dea55ade00b8522cf372b2884777f572744028e70f59435303e27ac1ebfb1c3c8ad88f760
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .DS_Store
2
+ .ruby-version
3
+ tmp/*
4
+ lib/tunemygc/tunemygc_ext.*
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ bundler_args: --quiet
3
+ rvm:
4
+ - 2.1.0
5
+ - 2.1.1
6
+ - 2.1.2
7
+ - 2.1.5
8
+ - 2.2.0
9
+ - ruby-head
10
+ script: "bundle exec rake"
11
+ env: RUBY_GC_TUNE=1 RUBY_GC_TUNE_DEBUG=1
12
+ gemfile:
13
+ - Gemfile
14
+ notifications:
15
+ recipients:
16
+ - lourens@methodmissing.com
17
+ branches:
18
+ only:
19
+ - master
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rails'
data/Gemfile.lock ADDED
@@ -0,0 +1,125 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tunemygc (1.0)
5
+ activesupport
6
+ certified
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionmailer (4.2.0)
12
+ actionpack (= 4.2.0)
13
+ actionview (= 4.2.0)
14
+ activejob (= 4.2.0)
15
+ mail (~> 2.5, >= 2.5.4)
16
+ rails-dom-testing (~> 1.0, >= 1.0.5)
17
+ actionpack (4.2.0)
18
+ actionview (= 4.2.0)
19
+ activesupport (= 4.2.0)
20
+ rack (~> 1.6.0)
21
+ rack-test (~> 0.6.2)
22
+ rails-dom-testing (~> 1.0, >= 1.0.5)
23
+ rails-html-sanitizer (~> 1.0, >= 1.0.1)
24
+ actionview (4.2.0)
25
+ activesupport (= 4.2.0)
26
+ builder (~> 3.1)
27
+ erubis (~> 2.7.0)
28
+ rails-dom-testing (~> 1.0, >= 1.0.5)
29
+ rails-html-sanitizer (~> 1.0, >= 1.0.1)
30
+ activejob (4.2.0)
31
+ activesupport (= 4.2.0)
32
+ globalid (>= 0.3.0)
33
+ activemodel (4.2.0)
34
+ activesupport (= 4.2.0)
35
+ builder (~> 3.1)
36
+ activerecord (4.2.0)
37
+ activemodel (= 4.2.0)
38
+ activesupport (= 4.2.0)
39
+ arel (~> 6.0)
40
+ activesupport (4.2.0)
41
+ i18n (~> 0.7)
42
+ json (~> 1.7, >= 1.7.7)
43
+ minitest (~> 5.1)
44
+ thread_safe (~> 0.3, >= 0.3.4)
45
+ tzinfo (~> 1.1)
46
+ addressable (2.3.6)
47
+ arel (6.0.0)
48
+ builder (3.2.2)
49
+ certified (1.0.0)
50
+ crack (0.4.2)
51
+ safe_yaml (~> 1.0.0)
52
+ erubis (2.7.0)
53
+ globalid (0.3.0)
54
+ activesupport (>= 4.1.0)
55
+ hike (1.2.3)
56
+ i18n (0.7.0)
57
+ json (1.8.2)
58
+ loofah (2.0.1)
59
+ nokogiri (>= 1.5.9)
60
+ mail (2.6.3)
61
+ mime-types (>= 1.16, < 3)
62
+ mime-types (2.4.3)
63
+ mini_portile (0.6.2)
64
+ minitest (5.5.0)
65
+ multi_json (1.10.1)
66
+ nokogiri (1.6.5)
67
+ mini_portile (~> 0.6.0)
68
+ rack (1.6.0)
69
+ rack-test (0.6.2)
70
+ rack (>= 1.0)
71
+ rails (4.2.0)
72
+ actionmailer (= 4.2.0)
73
+ actionpack (= 4.2.0)
74
+ actionview (= 4.2.0)
75
+ activejob (= 4.2.0)
76
+ activemodel (= 4.2.0)
77
+ activerecord (= 4.2.0)
78
+ activesupport (= 4.2.0)
79
+ bundler (>= 1.3.0, < 2.0)
80
+ railties (= 4.2.0)
81
+ sprockets-rails
82
+ rails-deprecated_sanitizer (1.0.3)
83
+ activesupport (>= 4.2.0.alpha)
84
+ rails-dom-testing (1.0.5)
85
+ activesupport (>= 4.2.0.beta, < 5.0)
86
+ nokogiri (~> 1.6.0)
87
+ rails-deprecated_sanitizer (>= 1.0.1)
88
+ rails-html-sanitizer (1.0.1)
89
+ loofah (~> 2.0)
90
+ railties (4.2.0)
91
+ actionpack (= 4.2.0)
92
+ activesupport (= 4.2.0)
93
+ rake (>= 0.8.7)
94
+ thor (>= 0.18.1, < 2.0)
95
+ rake (10.4.2)
96
+ rake-compiler (0.9.5)
97
+ rake
98
+ safe_yaml (1.0.4)
99
+ sprockets (2.12.3)
100
+ hike (~> 1.2)
101
+ multi_json (~> 1.0)
102
+ rack (~> 1.0)
103
+ tilt (~> 1.1, != 1.3.0)
104
+ sprockets-rails (2.2.2)
105
+ actionpack (>= 3.0)
106
+ activesupport (>= 3.0)
107
+ sprockets (>= 2.8, < 4.0)
108
+ thor (0.19.1)
109
+ thread_safe (0.3.4)
110
+ tilt (1.4.1)
111
+ tzinfo (1.2.2)
112
+ thread_safe (~> 0.1)
113
+ webmock (1.20.4)
114
+ addressable (>= 2.3.6)
115
+ crack (>= 0.3.2)
116
+
117
+ PLATFORMS
118
+ ruby
119
+
120
+ DEPENDENCIES
121
+ rails
122
+ rake
123
+ rake-compiler (~> 0.9.3)
124
+ tunemygc!
125
+ webmock
data/README.md ADDED
@@ -0,0 +1,193 @@
1
+ ## [TuneMyGC](https://www.tunemygc.com) - optimal MRI Ruby 2.1+ Garbage Collection
2
+
3
+ [![Build Status](https://travis-ci.org/bear-metal/tunemygc.svg)](https://travis-ci.org/bear-metal/tunemygc)
4
+
5
+ The Ruby garbage collector has been flagged as the crux of Ruby performance and memory use for a long time. It has improved a lot over the last years, but there's still a lot to tune and control. *The default configuration is not suitable and optimal for Rails applications, and neither is there a one-size-fits-all set of tuned parameters that would suit every app.* However, hand-tuning the GC parameters is a slippery slope to navigate for most developers.
6
+
7
+ ## We're fixing this
8
+
9
+ ![tunemygc workflow diagram](https://raw.githubusercontent.com/bear-metal/tunemygc/master/assets/tunemygc-graphic2x-80dac1571cacc70d9b272bb62ae9f6df.png?token=AAABe8sM_ofiQkrCpNw7OYRbtHMLO9l5ks5UuQlYwA%3D%3D)
10
+
11
+ ## Benefits
12
+
13
+ * Faster boot times
14
+ * Less major GC cycles during requests
15
+ * Less worst case memory usage - it's bound by sensible upper limits and growth factors
16
+ * No need to keep up to date with the C Ruby GC as an evolving moving target
17
+ * [in progress] A repeatable process to infer an optimal GC config for that app's current state within the context of a longer development cycle.
18
+
19
+ ## Benchmarks
20
+
21
+ We used [Discourse](http://www.discourse.org) as our primary test harness as it's representative of most Rails applications and has been instrumental in asserting RGenC developments on Rails as well.
22
+
23
+ ![tunemygc workflow diagram](https://raw.githubusercontent.com/bear-metal/tunemygc/master/assets/discourse_bench.png?token=AAABe8sM_ofiQkrCpNw7OYRbtHMLO9l5ks5UuQlYwA%3D%3D)
24
+
25
+ ## Installing
26
+
27
+ #### OS X / Linux
28
+
29
+ Add to your Gemfile and run `bundle install`
30
+
31
+ ``` sh
32
+ gem 'tunemygc', :require => 'tunemygc'
33
+ ```
34
+ This gem linterposes itself into the Rails request/response lifecycles and piggy backs off the new GC events in Ruby 2.x for introspection. Tuning recommendations are handled through a web service at `https://tunemygc.com`. You will need a `rails > 4.1`, installation and MRI Ruby `2.1`, or later.
35
+
36
+ #### Windows
37
+
38
+ Has not been tested at all.
39
+
40
+ ## Getting started
41
+
42
+ There isn't much setup other than adding the gem to your Gemfile and running a single command from your application root to register your application with the `https://tunemygc.com` service:
43
+
44
+ ``` sh
45
+ Lourenss-MacBook-Air-2:discourse lourens$ bundle exec tunemygc -r lourens@bearmetal.eu
46
+ Application registered. Use RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 in your environment.
47
+ ```
48
+
49
+ We require a valid email address as a canonical reference for tuner tokens for your applications.
50
+
51
+ For the above command sequences, to sample your Rails app for tuning, run:
52
+
53
+ ``` sh
54
+ RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 RUBY_GC_TUNE=1 bundle exec rails s
55
+ ```
56
+
57
+ The CLI interface supports retrieving configuration options for your application as well.
58
+
59
+ ``` sh
60
+ Lourenss-MacBook-Air-2:discourse lourens$ bundle exec tunemygc
61
+ Usage: tunemygc [options]
62
+ -r, --register EMAIL Register this Rails app with the https://tunemygc.com service
63
+ -c, --config TOKEN Fetch the last known config for a given Rails app
64
+ -h, --help How to use the TuneMyGC agent CLI
65
+ ```
66
+
67
+ ## Configuration options
68
+
69
+ We fully embrace and encourage [12 factor](http://12factor.net) conventions and as such configuration is limited to a few environment variables. No config files and YAML or initializer cruft.
70
+
71
+ #### Basic
72
+
73
+ * `RUBY_GC_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
74
+
75
+ This application specific token is required for GC instrumentation. You can generate one from the CLI interface by registering for the service with a valid email address:
76
+
77
+ ``` sh
78
+ Lourenss-MacBook-Air-2:discourse lourens$ bundle exec tunemygc -r lourens@bearmetal.eu
79
+ Application registered. Use RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 in your environment.
80
+ ```
81
+
82
+ * `RUBY_GC_TUNE=1`
83
+
84
+ Enables the interposer for taking a few lightweight snapshots and submitting them to `tunemygc.com`. Without this environment variable set, it won't interpose itself.
85
+
86
+ For the above command sequences, to sample my Rails app for tuning, I'd run:
87
+
88
+ ``` sh
89
+ RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 RUBY_GC_TUNE=1 bundle exec rails s
90
+ ```
91
+
92
+ #### Advanced
93
+
94
+ * `RUBY_GC_TUNE_REQUESTS=x`
95
+
96
+ Controls the interposer lifetime for sampling requests. It will enable itself, then remove request instrumentation after `x` requests. A good minimum ballpark sample set would be 200
97
+
98
+ * `RUBY_GC_TUNE_DEBUG=1`
99
+
100
+ As above, but dumps snapshots to Rails logger or STDOUT prior to submission. Mostly for developer use/support.
101
+
102
+ ## How do I use this?
103
+
104
+ This gem is only a lightweight agent and designed to not get in your way. There's not much workflow at the moment other than applying the suggested GC configuration to your application's environment.
105
+
106
+ #### Interpreting configurations
107
+
108
+ An instrumented process dumps a reccommended config to the Rails logger.
109
+
110
+ ``` sh
111
+ [TuneMyGC] Syncing 688 snapshots
112
+ [TuneMyGC] ==== Recommended GC configs from https://tunemygc.com/configs/d739119e4abc38d42e183d1361991818.json
113
+ [TuneMyGC] export RUBY_GC_HEAP_INIT_SLOTS=382429
114
+ [TuneMyGC] export RUBY_GC_HEAP_FREE_SLOTS=603850
115
+ [TuneMyGC] export RUBY_GC_HEAP_GROWTH_FACTOR=1.2
116
+ [TuneMyGC] export RUBY_GC_HEAP_GROWTH_MAX_SLOTS=301925
117
+ [TuneMyGC] export RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=2.0
118
+ [TuneMyGC] export RUBY_GC_MALLOC_LIMIT=35818030
119
+ [TuneMyGC] export RUBY_GC_MALLOC_LIMIT_MAX=42981636
120
+ [TuneMyGC] export RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR=1.32
121
+ [TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT=32782669
122
+ [TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT_MAX=49174003.5
123
+ [TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2
124
+ ```
125
+
126
+ We're still in the process of building tools and a launcher shim around this. You can also retrieve the last known configuration for you app via the CLI interface:
127
+
128
+ ``` sh
129
+ Lourenss-MacBook-Air-2:discourse lourens$ bundle exec tunemygc -c 3b8796e5627f97ec760f000d55d9b3f5
130
+ === Suggested GC configuration:
131
+
132
+ export RUBY_GC_HEAP_INIT_SLOTS=382429
133
+ export RUBY_GC_HEAP_FREE_SLOTS=603850
134
+ export RUBY_GC_HEAP_GROWTH_FACTOR=1.2
135
+ export RUBY_GC_HEAP_GROWTH_MAX_SLOTS=301925
136
+ export RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=2.0
137
+ export RUBY_GC_MALLOC_LIMIT=35818030
138
+ export RUBY_GC_MALLOC_LIMIT_MAX=42981636
139
+ export RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR=1.32
140
+ export RUBY_GC_OLDMALLOC_LIMIT=32782669
141
+ export RUBY_GC_OLDMALLOC_LIMIT_MAX=49174003.5
142
+ export RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2
143
+ ```
144
+
145
+ #### Heroku and 12 factor
146
+
147
+ We have a [Heroku](http://www.heroku.com) addon in Alpha testing and the Ruby GC lends itself well to tuning through 12 factor principles as it's designed around environment variables.
148
+
149
+ ## Security and privacy concerns
150
+
151
+ We don't track any data specific to your application other than a simple environment header which allows us to pick the best tuner for your setup:
152
+
153
+ * Ruby version eg. "2.2.0"
154
+ * Rails version eg. "4.1.8"
155
+ * Compile time GC options eg. "["USE_RGENGC", "RGENGC_ESTIMATE_OLDMALLOC", "GC_ENABLE_LAZY_SWEEP"]"
156
+ * Compile time GC constants eg. "{"RVALUE_SIZE"=>40, "HEAP_OBJ_LIMIT"=>408, "HEAP_BITMAP_SIZE"=>56, "HEAP_BITMAP_PLANES"=>3}"
157
+
158
+ Samples hitting our tuner endpoint doesn't include any proprietary details from your application either - just data points about GC activity.
159
+
160
+ We do however ask for a valid email address as a canonical reference for tuner tokens for your applications.
161
+
162
+ ## Feedback and issues
163
+
164
+ When trouble strikes, please file an [issue](https://www.github.com/bear-metal/tunemygc/issues) or email Lourens directly <lourens@bearmetal.eu>
165
+
166
+ [Bear Metal OÜ](http://www.bearmetal.eu) is also available for consulting around general Rails performance, heap dump analysis (more tools coming soon) and custom Ruby extension development.
167
+
168
+ ## License
169
+
170
+ (The MIT License)
171
+
172
+ Copyright (c) 2015:
173
+
174
+ * [Bear Metal OÜ](http://bearmetal.eu)
175
+
176
+ Permission is hereby granted, free of charge, to any person obtaining
177
+ a copy of this software and associated documentation files (the
178
+ 'Software'), to deal in the Software without restriction, including
179
+ without limitation the rights to use, copy, modify, merge, publish,
180
+ distribute, sublicense, and/or sell copies of the Software, and to
181
+ permit persons to whom the Software is furnished to do so, subject to
182
+ the following conditions:
183
+
184
+ The above copyright notice and this permission notice shall be
185
+ included in all copies or substantial portions of the Software.
186
+
187
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
188
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
189
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
190
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
191
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
192
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
193
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems' unless defined?(Gem)
4
+ require 'rake' unless defined?(Rake)
5
+
6
+ require 'rake/extensiontask'
7
+ require 'rake/testtask'
8
+
9
+ Rake::ExtensionTask.new('tunemygc') do |ext|
10
+ ext.name = 'tunemygc_ext'
11
+ ext.ext_dir = 'ext/tunemygc'
12
+ ext.lib_dir = "lib/tunemygc"
13
+ CLEAN.include 'lib/**/tunemygc_ext.*'
14
+ end
15
+
16
+ desc 'Run tunemygc tests'
17
+ Rake::TestTask.new(:test) do |t|
18
+ t.libs << 'test'
19
+ t.pattern = "test/**/test_*.rb"
20
+ t.verbose = true
21
+ t.warning = true
22
+ end
23
+
24
+ namespace :debug do
25
+ desc "Run the test suite under gdb"
26
+ task :gdb do
27
+ system "gdb --args ruby rake"
28
+ end
29
+ end
30
+
31
+ task :test => :compile
32
+ task :default => :test
Binary file
data/bin/tunemygc ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tunemygc'
4
+ require 'tunemygc/cli'
5
+
6
+ TuneMyGc::CLI.start(ARGV)
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+
3
+ require 'mkmf'
4
+
5
+ dir_config('tunemygc')
6
+
7
+ # Only defined for Ruby 2.1.x and 2.2.x
8
+ gc_events = have_const('RUBY_INTERNAL_EVENT_GC_END_SWEEP')
9
+
10
+ if gc_events
11
+ # From ko1/gc_tracer
12
+ # Piggy backs off the new methods to retrieve GC stats and latest cycle info without doing
13
+ # allocations - thus safe to call within a GC cycle and properly snapshot what we need without
14
+ # the results being skewed by postponed jobs, which isn't deterministic.
15
+ open("tunemygc_env.h", 'w'){|f|
16
+ gc_stat = GC.stat
17
+ gc_latest_info = GC.latest_gc_info
18
+ f.puts '#include "ruby/ruby.h"'
19
+ f.puts "static VALUE sym_gc_stat[#{gc_stat.keys.size}];"
20
+ f.puts "static VALUE sym_latest_gc_info[#{gc_latest_info.keys.size}];"
21
+
22
+ f.puts 'typedef struct {'
23
+ f.puts ' double ts;'
24
+ f.puts ' size_t peak_rss;'
25
+ f.puts ' size_t current_rss;'
26
+ f.puts ' VALUE stage;'
27
+ gc_stat.keys.each do |key|
28
+ f.puts " size_t #{key};"
29
+ end
30
+ gc_latest_info.each do |key, val|
31
+ f.puts " VALUE #{key};"
32
+ end
33
+ f.puts '} tunemygc_stat_record;'
34
+
35
+ f.puts "static void"
36
+ f.puts "tunemygc_set_stat_record(tunemygc_stat_record *record)"
37
+ f.puts "{"
38
+ #
39
+ gc_stat.keys.each.with_index{|k, i|
40
+ f.puts " record->#{k} = rb_gc_stat(sym_gc_stat[#{i}]);"
41
+ }
42
+ gc_latest_info.keys.each.with_index{|k, i|
43
+ f.puts " record->#{k} = rb_gc_latest_gc_info(sym_latest_gc_info[#{i}]);"
44
+ }
45
+ #
46
+ f.puts "}"
47
+
48
+ f.puts "static VALUE"
49
+ f.puts "tunemygc_get_stat_record(tunemygc_stat_record *record)"
50
+ f.puts "{"
51
+ #
52
+ f.puts " VALUE stat = rb_hash_new();"
53
+ f.puts " VALUE latest_info = rb_hash_new();"
54
+ f.puts " VALUE snapshot = rb_ary_new2(7);"
55
+ gc_stat.keys.each.with_index{|k, i|
56
+ f.puts " rb_hash_aset(stat, sym_gc_stat[#{i}], SIZET2NUM(record->#{k}));"
57
+ }
58
+ gc_latest_info.keys.each.with_index{|k, i|
59
+ f.puts " rb_hash_aset(latest_info, sym_latest_gc_info[#{i}], record->#{k});"
60
+ }
61
+ f.puts " rb_ary_store(snapshot, 0, DBL2NUM(record->ts));"
62
+ f.puts " rb_ary_store(snapshot, 1, SIZET2NUM(record->peak_rss));"
63
+ f.puts " rb_ary_store(snapshot, 2, SIZET2NUM(record->current_rss));"
64
+ f.puts " rb_ary_store(snapshot, 3, record->stage);"
65
+ f.puts " rb_ary_store(snapshot, 4, stat);"
66
+ f.puts " rb_ary_store(snapshot, 5, latest_info);"
67
+ f.puts " rb_ary_store(snapshot, 6, Qnil);"
68
+ f.puts " return snapshot;"
69
+ #
70
+ f.puts "}"
71
+
72
+ f.puts "static void"
73
+ f.puts "tunemygc_setup_trace_symbols(void)"
74
+ f.puts "{"
75
+ #
76
+ gc_stat.keys.each.with_index{|k, i|
77
+ f.puts " sym_gc_stat[#{i}] = ID2SYM(rb_intern(\"#{k}\"));"
78
+ }
79
+ gc_latest_info.keys.each.with_index{|k, i|
80
+ f.puts " sym_latest_gc_info[#{i}] = ID2SYM(rb_intern(\"#{k}\"));"
81
+ }
82
+ #
83
+ f.puts "}"
84
+ }
85
+
86
+ create_makefile('tunemygc/tunemygc_ext')
87
+ else
88
+ # do nothing if we're not running within Ruby 2.1.x or 2.2.x
89
+ File.open('Makefile', 'w') do |f|
90
+ f.puts "install:\n\t\n"
91
+ end
92
+ end
@@ -0,0 +1,122 @@
1
+ /*
2
+ * Author: David Robert Nadeau
3
+ * Site: http://NadeauSoftware.com/
4
+ * License: Creative Commons Attribution 3.0 Unported License
5
+ * http://creativecommons.org/licenses/by/3.0/deed.en_US
6
+ */
7
+
8
+ #if defined(_WIN32)
9
+ #include <windows.h>
10
+ #include <psapi.h>
11
+
12
+ #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
13
+ #include <unistd.h>
14
+ #include <sys/resource.h>
15
+
16
+ #if defined(__APPLE__) && defined(__MACH__)
17
+ #include <mach/mach.h>
18
+
19
+ #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
20
+ #include <fcntl.h>
21
+ #include <procfs.h>
22
+
23
+ #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
24
+ #include <stdio.h>
25
+
26
+ #endif
27
+
28
+ #else
29
+ #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
30
+ #endif
31
+
32
+
33
+
34
+
35
+
36
+ /**
37
+ * Returns the peak (maximum so far) resident set size (physical
38
+ * memory use) measured in bytes, or zero if the value cannot be
39
+ * determined on this OS.
40
+ */
41
+ size_t getPeakRSS( )
42
+ {
43
+ #if defined(_WIN32)
44
+ /* Windows -------------------------------------------------- */
45
+ PROCESS_MEMORY_COUNTERS info;
46
+ GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
47
+ return (size_t)info.PeakWorkingSetSize;
48
+
49
+ #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
50
+ /* AIX and Solaris ------------------------------------------ */
51
+ struct psinfo psinfo;
52
+ int fd = -1;
53
+ if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
54
+ return (size_t)0L; /* Can't open? */
55
+ if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
56
+ {
57
+ close( fd );
58
+ return (size_t)0L; /* Can't read? */
59
+ }
60
+ close( fd );
61
+ return (size_t)(psinfo.pr_rssize * 1024L);
62
+
63
+ #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
64
+ /* BSD, Linux, and OSX -------------------------------------- */
65
+ struct rusage rusage;
66
+ getrusage( RUSAGE_SELF, &rusage );
67
+ #if defined(__APPLE__) && defined(__MACH__)
68
+ return (size_t)rusage.ru_maxrss;
69
+ #else
70
+ return (size_t)(rusage.ru_maxrss * 1024L);
71
+ #endif
72
+
73
+ #else
74
+ /* Unknown OS ----------------------------------------------- */
75
+ return (size_t)0L; /* Unsupported. */
76
+ #endif
77
+ }
78
+
79
+
80
+
81
+
82
+
83
+ /**
84
+ * Returns the current resident set size (physical memory use) measured
85
+ * in bytes, or zero if the value cannot be determined on this OS.
86
+ */
87
+ size_t getCurrentRSS( )
88
+ {
89
+ #if defined(_WIN32)
90
+ /* Windows -------------------------------------------------- */
91
+ PROCESS_MEMORY_COUNTERS info;
92
+ GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
93
+ return (size_t)info.WorkingSetSize;
94
+
95
+ #elif defined(__APPLE__) && defined(__MACH__)
96
+ /* OSX ------------------------------------------------------ */
97
+ struct mach_task_basic_info info;
98
+ mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
99
+ if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
100
+ (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
101
+ return (size_t)0L; /* Can't access? */
102
+ return (size_t)info.resident_size;
103
+
104
+ #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
105
+ /* Linux ---------------------------------------------------- */
106
+ long rss = 0L;
107
+ FILE* fp = NULL;
108
+ if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
109
+ return (size_t)0L; /* Can't open? */
110
+ if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
111
+ {
112
+ fclose( fp );
113
+ return (size_t)0L; /* Can't read? */
114
+ }
115
+ fclose( fp );
116
+ return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE);
117
+
118
+ #else
119
+ /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
120
+ return (size_t)0L; /* Unsupported. */
121
+ #endif
122
+ }