linux_stat 2.1.2 → 2.3.0

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/exe/linuxstat.rb CHANGED
@@ -7,6 +7,12 @@ rescue LoadError
7
7
  abort "The Gem needs to be installed before this test can be run!"
8
8
  end
9
9
 
10
+ # Time reporting format
11
+ T_FMT = '%d'.freeze
12
+
13
+ # Check the number of iterations
14
+ iterations = (ARGV.find { |x| x.to_i.to_s == x } || 1).to_i
15
+
10
16
  Integer.class_exec do
11
17
  define_method(:clamp) { |min, max|
12
18
  self < min ? min : self > max ? max : self
@@ -100,122 +106,166 @@ execute = constants.map(&:downcase).map.with_index { |x, i|
100
106
  execute.replace(constants) if execute.empty?
101
107
  HEXAGONS = %W(\u2b22 \u2b23 \u2B53 \u2B1F)
102
108
 
103
- execute.sort.each do |c|
104
- e = eval("LinuxStat::#{c}")
109
+ puts " #{HEXAGONS.rotate![0]} LinuxStat: #{LinuxStat::VERSION}"
110
+ puts " #{HEXAGONS.rotate![0]} Test Modules: #{execute.size}"
111
+ puts " #{HEXAGONS.rotate![0]} Iterations: #{iterations}"
105
112
 
106
- next if e.class != Module && e.class != Class
113
+ puts " #{HEXAGONS.rotate![0]} Format: Markdown" if MARKDOWN
114
+ puts " #{HEXAGONS.rotate![0]} Format: HTML" if HTML
107
115
 
108
- meths = e.methods(false).sort
116
+ sleep 2
117
+ puts
109
118
 
110
- if meths.length > 0
111
- if MARKDOWN
112
- puts "### LinuxStat::#{c}\n```"
113
- elsif HTML
114
- puts "<h3>LinuxStat::#{c}</h3>\n<pre>"
115
- else
116
- puts "\e[1;4;38;2;255;240;0mLinuxStat::#{c}\e[0m"
117
- end
119
+ def get_colour(n)
120
+ if n > 10_000
121
+ "\e[1;38;2;255;50;50m"
122
+ elsif n > 5_000
123
+ "\e[1;38;2;255;170;0m"
124
+ else
125
+ "\e[1;38;2;0;170;0m"
118
126
  end
127
+ end
128
+
129
+ total_real_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
130
+ total_cpu_time = Process.times
131
+
132
+ iterations.times do
133
+ execute.sort.each do |c|
134
+ e = eval("LinuxStat::#{c}")
135
+
136
+ next if e.class != Module && e.class != Class
119
137
 
120
- meths.each do |meth|
121
- arg = nil
138
+ meths = e.methods(false).sort
122
139
 
123
- arity = e.method(meth).arity
124
- if arity > 0 || arity == -2
125
- if c == :PrettifyBytes
126
- arg = rand(10 ** 15)
127
- elsif c == :FS
128
- arg = '/'
140
+ if meths.length > 0
141
+ if MARKDOWN
142
+ puts "### LinuxStat::#{c}\n```"
143
+ elsif HTML
144
+ puts "<h3>LinuxStat::#{c}</h3>\n<pre>"
129
145
  else
130
- next
146
+ puts "\e[1;4;38;2;255;240;0mLinuxStat::#{c}\e[0m"
131
147
  end
132
148
  end
133
149
 
134
- params = e.method(meth).parameters
135
- param = ''
136
- params.each do |p|
137
- case p[0]
138
- when :opt
139
- param << "#{p[1]}, "
140
- when :key
141
- param << "#{p[1]}:, "
142
- when :req
143
- _arg = arg ? " = #{arg.inspect}" : ''.freeze
144
- param << "#{p[1] || 'arg'}#{_arg}, "
150
+ meths.each do |meth|
151
+ arg = nil
152
+
153
+ arity = e.method(meth).arity
154
+ if arity > 0 || arity == -2
155
+ if c == :PrettifyBytes
156
+ arg = rand(10 ** 15)
157
+ elsif c == :FS
158
+ arg = '/'
159
+ else
160
+ next
161
+ end
145
162
  end
146
- end
147
163
 
148
- param.chomp!(", ")
149
-
150
- disp_meth = "#{meth}"
151
- disp_meth.concat(arg ? "(#{param})" : "(#{param})")
152
-
153
- time = Time.now
154
- ret = arg ? e.send(meth, arg) : e.send(meth)
155
- time2 = Time.now
156
- time = time2.-(time).*(1_000_000).round(3)
157
-
158
- v = ret.inspect
159
- dis = v.length > 253 ? v[0..250].strip + '...'.freeze : v
160
-
161
- source = e.singleton_method(meth).source_location.to_a
162
- src, src_meth, src_ret = '', '', ''
163
-
164
- unless source.empty?
165
- src << " File:\t\t#{File.split(source[0])[-1]} | Line: #{source[1]}\n"
166
- src_meth << " Definition:\t#{IO.foreach(source[0]).first(source[1])[-1].strip}\n"
167
-
168
- src_ret << " Returns:\t" << case ret
169
- when Array then 'Array | Empty Array'
170
- when Complex then 'Complex | nil'
171
- when Float then 'Float | nil'
172
- when Hash then 'Hash | Empty Hash'
173
- when Integer then 'Integer | nil'
174
- when Rational then 'Rational | nil'
175
- when String then "String | (Frozen) Empty String"
176
- when Time then 'Time | nil'
177
- when true, false then 'True or False | nil'
178
- when nil then 'nil'
179
- else ''
180
- end << ?\n.freeze if PRINT_TYPE
181
-
182
- if MARKDOWN || HTML
183
- src.prepend('#'.freeze)
184
- src_meth.prepend('#'.freeze)
185
- src_ret.prepend(?#.freeze) if PRINT_TYPE
186
- else
187
- src.prepend(HEXAGONS.rotate![0].freeze)
188
- src_meth.prepend(HEXAGONS.rotate![0].freeze)
189
- src_ret.prepend(HEXAGONS.rotate![0].freeze) if PRINT_TYPE
164
+ params = e.method(meth).parameters
165
+ param = ''
166
+ params.each do |p|
167
+ case p[0]
168
+ when :opt
169
+ param << "#{p[1]}, "
170
+ when :key
171
+ param << "#{p[1]}:, "
172
+ when :req
173
+ _arg = arg ? " = #{arg.inspect}" : ''.freeze
174
+ param << "#{p[1] || 'arg'}#{_arg}, "
175
+ end
190
176
  end
191
- end
192
177
 
193
- if MARKDOWN
194
- puts "#{src}#{src_meth}#{src_ret}#{e}.#{disp_meth}\n=> #{dis}"
195
- elsif HTML
196
- puts "#{src}#{src_meth}#{src_ret}#{e}.#{disp_meth}\n=> #{dis}"
197
- else
198
- puts "\e[1m#{src.colourize}\e[1m#{src_meth.colourize(6)}\e[1m#{src_ret.colourize(1)}\e[0m\e[1;38;2;80;80;255m#{e}.#{disp_meth}\e[0m\n=> #{dis}"
199
- end
178
+ param.chomp!(", ")
179
+
180
+ disp_meth = "#{meth}"
181
+ disp_meth.concat(arg ? "(#{param})" : "(#{param})")
182
+
183
+ time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
184
+ cputime = Process.times
185
+
186
+ ret = arg ? e.send(meth, arg) : e.send(meth)
187
+
188
+ time2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
189
+ cputime2 = Process.times
190
+
191
+ time = time2.-(time).*(1_000_000)
192
+ cputime = cputime2.stime.+(cputime2.utime).-(cputime.stime + cputime.utime).*(1_000_000)
193
+
194
+ v = ret.inspect
195
+ dis = v.length > 253 ? v[0..250].strip + '...'.freeze : v
196
+
197
+ source = e.singleton_method(meth).source_location.to_a
198
+ src, src_meth, src_ret = '', '', ''
199
+
200
+ unless source.empty?
201
+ src << " File:\t\t#{File.split(source[0])[-1]} | Line: #{source[1]}\n"
202
+ src_meth << " Definition:\t#{IO.foreach(source[0]).first(source[1])[-1].strip}\n"
203
+
204
+ src_ret << " Returns:\t" << case ret
205
+ when Array then 'Array | Empty Array'
206
+ when Complex then 'Complex | nil'
207
+ when Float then 'Float | nil'
208
+ when Hash then 'Hash | Empty Hash'
209
+ when Integer then 'Integer | nil'
210
+ when Rational then 'Rational | nil'
211
+ when String then "String | (Frozen) Empty String"
212
+ when Time then 'Time | nil'
213
+ when true, false then 'True or False | nil'
214
+ when nil then 'nil'
215
+ else ''
216
+ end << ?\n.freeze if PRINT_TYPE
217
+
218
+ if MARKDOWN || HTML
219
+ src.prepend('#'.freeze)
220
+ src_meth.prepend('#'.freeze)
221
+ src_ret.prepend(?#.freeze) if PRINT_TYPE
222
+ else
223
+ src.prepend(HEXAGONS.rotate![0].freeze)
224
+ src_meth.prepend(HEXAGONS.rotate![0].freeze)
225
+ src_ret.prepend(HEXAGONS.rotate![0].freeze) if PRINT_TYPE
226
+ end
227
+ end
200
228
 
201
- puts( "(" +
202
- if time > 10_000
203
- "\e[1;38;2;255;50;50m"
204
- elsif time > 5_000
205
- "\e[1;38;2;255;170;0m"
229
+ if MARKDOWN
230
+ puts "#{src}#{src_meth}#{src_ret}#{e}.#{disp_meth}\n=> #{dis}"
231
+ elsif HTML
232
+ puts "#{src}#{src_meth}#{src_ret}#{e}.#{disp_meth}\n=> #{dis}"
206
233
  else
207
- "\e[1;38;2;0;170;0m"
208
- end + "Time taken: #{time}\u03BCs\e[0m)"
209
- ) if PRINT_TIME
234
+ puts "\e[1m#{src.colourize}\e[1m#{src_meth.colourize(6)}\e[1m#{src_ret.colourize(1)}\e[0m\e[1;38;2;80;80;255m#{e}.#{disp_meth}\e[0m\n=> #{dis}"
235
+ end
210
236
 
211
- puts
212
- end
237
+ if PRINT_TIME
238
+ time_colour = get_colour(time)
239
+ cputime_colour = get_colour(cputime)
240
+
241
+ puts "[Real Time: #{time_colour}#{T_FMT % time}\u03BCs\e[0m, "\
242
+ "CPU Time: #{cputime_colour}#{T_FMT % cputime}\u03BCs\e[0m]"
243
+ end
244
+
245
+ puts
246
+ end
213
247
 
214
- if meths.length > 0
215
- if MARKDOWN
216
- puts "```\n\n"
217
- elsif HTML
218
- puts "</pre>"
248
+ if meths.length > 0
249
+ if MARKDOWN
250
+ puts "```\n\n"
251
+ elsif HTML
252
+ puts "</pre>"
253
+ end
219
254
  end
220
255
  end
221
256
  end
257
+
258
+ if PRINT_TIME
259
+ total_real_time2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
260
+ total_cpu_time2 = Process.times
261
+
262
+ total_real_t = total_real_time2.-(total_real_time).*(1_000_000)
263
+
264
+ total_cpu_t = total_cpu_time2.stime.+(total_cpu_time2.utime).-(
265
+ total_cpu_time.stime + total_cpu_time.utime
266
+ ).*(1_000_000)
267
+
268
+ puts "\e[38;2;255;255;0m:: Warning total time also depends on your terminal speed!\e[0m"
269
+ puts "Total Real Time: #{T_FMT % total_real_t}ms"
270
+ puts "Total CPU Time: #{T_FMT % total_cpu_t}ms"
271
+ end
@@ -0,0 +1,25 @@
1
+ static VALUE getDiskStats (volatile VALUE obj, volatile VALUE path) {
2
+ FILE *file = fopen("/proc/diskstats", "r") ;
3
+ if(!file) return rb_ary_new() ;
4
+
5
+ char lines[120] ;
6
+ unsigned long long read, write ;
7
+ char *p = StringValuePtr(path) ;
8
+
9
+ while(fgets(lines, 119, file)) {
10
+ sscanf(lines, "%*s %*s %s %*s %*s %llu %*s %*s %*s %llu", lines, &read, &write) ;
11
+
12
+ if(strcmp(lines, p) == 0) {
13
+ fclose(file) ;
14
+
15
+ return rb_ary_new_from_args(
16
+ 2,
17
+ ULL2NUM(read),
18
+ ULL2NUM(write)
19
+ ) ;
20
+ }
21
+ }
22
+
23
+ fclose(file) ;
24
+ return rb_ary_new() ;
25
+ }
@@ -4,7 +4,8 @@ unless have_const('linux') || RbConfig::CONFIG['arch'].to_s[/linux/]
4
4
  abort('Platform is not linux')
5
5
  end
6
6
 
7
- unless have_header('sys/statvfs.h') && have_header('ruby.h')
7
+ unless have_header('sys/statvfs.h') && have_header('sys/ioctl.h') &&
8
+ have_header('fcntl.h') && have_header('linux/fs.h') && have_header('unistd.h')
8
9
  abort('Missing header')
9
10
  end
10
11
 
@@ -1,5 +1,12 @@
1
1
  #include <sys/statvfs.h>
2
+ #include <sys/ioctl.h>
3
+ #include <fcntl.h>
4
+ #include <linux/fs.h>
5
+ #include <unistd.h>
6
+
2
7
  #include "ruby.h"
8
+ #include "sector_size.h"
9
+ #include "disk_stat.h"
3
10
 
4
11
  #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
5
12
  #pragma GCC optimize ("O3")
@@ -11,7 +18,7 @@
11
18
  #pragma intel optimization_level 3
12
19
  #endif
13
20
 
14
- static VALUE statfs(VALUE obj, VALUE dir) {
21
+ static VALUE statfs(volatile VALUE obj, volatile VALUE dir) {
15
22
  struct statvfs buf ;
16
23
  char *d = StringValuePtr(dir) ;
17
24
  VALUE hash = rb_hash_new() ;
@@ -36,4 +43,6 @@ void Init_fs_stat() {
36
43
  VALUE _linux_stat = rb_define_module("LinuxStat") ;
37
44
  VALUE fs = rb_define_module_under(_linux_stat, "FS") ;
38
45
  rb_define_module_function(fs, "stat", statfs, 1) ;
46
+ rb_define_module_function(fs, "sectors", getSectorSize, 1) ;
47
+ rb_define_module_function(fs, "total_io", getDiskStats, 1) ;
39
48
  }
@@ -0,0 +1,13 @@
1
+ static VALUE getSectorSize(volatile VALUE obj, volatile VALUE path) {
2
+ char *dev = StringValuePtr(path) ;
3
+
4
+ unsigned int fd = open(dev, O_RDONLY | O_NONBLOCK) ;
5
+ if(fd < 0) return Qnil ;
6
+
7
+ unsigned int sSize = 0 ;
8
+ short status = ioctl(fd, BLKSSZGET, &sSize) ;
9
+ close(fd) ;
10
+ if(status < 0) return Qnil ;
11
+
12
+ return UINT2NUM(sSize) ;
13
+ }
data/ext/nproc/nproc.c CHANGED
@@ -15,7 +15,7 @@
15
15
  #pragma intel optimization_level 3
16
16
  #endif
17
17
 
18
- static VALUE count_cpu_for_pid(VALUE obj, VALUE pid) {
18
+ static VALUE count_cpu_for_pid(volatile VALUE obj, volatile VALUE pid) {
19
19
  cpu_set_t set ;
20
20
  CPU_ZERO(&set) ;
21
21
  char status = sched_getaffinity(FIX2INT(pid), sizeof(set), &set) ;
@@ -1,4 +1,4 @@
1
- VALUE last_pid(VALUE obj) {
1
+ static VALUE last_pid(volatile VALUE obj) {
2
2
  FILE *f = fopen("/proc/loadavg", "r") ;
3
3
  if (!f) return Qnil ;
4
4
 
data/ext/procfs/procfs.c CHANGED
@@ -38,5 +38,6 @@ int Init_procfs() {
38
38
 
39
39
  // stat
40
40
  rb_define_module_function(_procfs, "ps_state", ps_state, 1) ;
41
+ rb_define_module_function(_procfs, "ps_times", ps_times, 1) ;
41
42
  rb_define_module_function(_procfs, "ps_stat", ps_stat, 1) ;
42
43
  }
data/ext/procfs/stat.h CHANGED
@@ -1,4 +1,4 @@
1
- VALUE ps_state(VALUE obj, VALUE pid) {
1
+ static VALUE ps_state(volatile VALUE obj, volatile VALUE pid) {
2
2
  int _pid = FIX2INT(pid) ;
3
3
  if (_pid < 0) return rb_str_new_cstr("") ;
4
4
 
@@ -17,7 +17,28 @@ VALUE ps_state(VALUE obj, VALUE pid) {
17
17
  return rb_str_new_cstr(_s) ;
18
18
  }
19
19
 
20
- VALUE ps_stat(VALUE obj, VALUE pid) {
20
+ static VALUE ps_times(volatile VALUE obj, volatile VALUE pid) {
21
+ int _pid = FIX2INT(pid) ;
22
+ if (_pid < 0) return Qnil ;
23
+
24
+ char _path[22] ;
25
+ sprintf(_path, "/proc/%d/stat", _pid) ;
26
+
27
+ FILE *f = fopen(_path, "r") ;
28
+ if (!f) return Qnil ;
29
+
30
+ unsigned long utime, stime ;
31
+
32
+ char status = fscanf(f, "%*llu (%*[^)]%*[)] %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %lu %lu", &utime, &stime) ;
33
+ fclose(f) ;
34
+
35
+ if (status != 2) return Qnil ;
36
+ double total_time = (utime + stime) / (float)sysconf(_SC_CLK_TCK);
37
+
38
+ return DBL2NUM(total_time) ;
39
+ }
40
+
41
+ static VALUE ps_stat(volatile VALUE obj, volatile VALUE pid) {
21
42
  int _pid = FIX2INT(pid) ;
22
43
  if (_pid < 0) return rb_str_new_cstr("") ;
23
44
 
data/ext/procfs/statm.h CHANGED
@@ -1,6 +1,6 @@
1
1
  #define PAGESIZE sysconf(_SC_PAGESIZE)
2
2
 
3
- VALUE statm(VALUE obj, VALUE pid) {
3
+ static VALUE statm(volatile VALUE obj, volatile VALUE pid) {
4
4
  VALUE hash = rb_hash_new() ;
5
5
 
6
6
  int _pid = FIX2INT(pid) ;
@@ -34,7 +34,7 @@ VALUE statm(VALUE obj, VALUE pid) {
34
34
  return hash ;
35
35
  }
36
36
 
37
- VALUE statm_virtual(VALUE obj, VALUE pid) {
37
+ static VALUE statm_virtual(volatile VALUE obj, volatile VALUE pid) {
38
38
  int _pid = FIX2INT(pid) ;
39
39
  if (_pid < 0) return Qnil ;
40
40
 
@@ -52,7 +52,7 @@ VALUE statm_virtual(VALUE obj, VALUE pid) {
52
52
  return UINT2NUM(_virtual * PAGESIZE) ;
53
53
  }
54
54
 
55
- VALUE statm_resident(VALUE obj, VALUE pid) {
55
+ static VALUE statm_resident(volatile VALUE obj, volatile VALUE pid) {
56
56
  int _pid = FIX2INT(pid) ;
57
57
  if (_pid < 0) return Qnil ;
58
58
 
@@ -70,7 +70,7 @@ VALUE statm_resident(VALUE obj, VALUE pid) {
70
70
  return UINT2NUM(resident * PAGESIZE) ;
71
71
  }
72
72
 
73
- VALUE statm_shared(VALUE obj, VALUE pid) {
73
+ static VALUE statm_shared(volatile VALUE obj, volatile VALUE pid) {
74
74
  int _pid = FIX2INT(pid) ;
75
75
  if (_pid < 0) return Qnil ;
76
76
 
@@ -88,7 +88,7 @@ VALUE statm_shared(VALUE obj, VALUE pid) {
88
88
  return UINT2NUM(shared * PAGESIZE) ;
89
89
  }
90
90
 
91
- VALUE statm_memory(VALUE obj, VALUE pid) {
91
+ static VALUE statm_memory(volatile VALUE obj, volatile VALUE pid) {
92
92
  int _pid = FIX2INT(pid) ;
93
93
  if (_pid < 0) return Qnil ;
94
94