linux_stat 1.5.1 → 2.1.2

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.
@@ -1,5 +1,4 @@
1
1
  #include <sys/sysinfo.h>
2
- #include <inttypes.h>
3
2
  #include "ruby.h"
4
3
 
5
4
  #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
@@ -15,8 +14,7 @@
15
14
  static struct sysinfo info ;
16
15
 
17
16
  VALUE totalram(VALUE obj) {
18
- static struct sysinfo info ;
19
- short status = sysinfo(&info) ;
17
+ char status = sysinfo(&info) ;
20
18
  if (status < 0) return Qnil ;
21
19
 
22
20
  VALUE _rb_v = ULL2NUM((unsigned long long) info.totalram) ;
@@ -25,7 +23,7 @@ VALUE totalram(VALUE obj) {
25
23
  }
26
24
 
27
25
  VALUE freeram(VALUE obj) {
28
- short status = sysinfo(&info) ;
26
+ char status = sysinfo(&info) ;
29
27
  if (status < 0) return Qnil ;
30
28
 
31
29
  VALUE _rb_v = ULL2NUM((unsigned long long) info.freeram) ;
@@ -34,7 +32,7 @@ VALUE freeram(VALUE obj) {
34
32
  }
35
33
 
36
34
  VALUE sharedram(VALUE obj) {
37
- short status = sysinfo(&info) ;
35
+ char status = sysinfo(&info) ;
38
36
  if (status < 0) return Qnil ;
39
37
 
40
38
  VALUE _rb_v = ULL2NUM((unsigned long long) info.sharedram) ;
@@ -43,7 +41,7 @@ VALUE sharedram(VALUE obj) {
43
41
  }
44
42
 
45
43
  VALUE bufferram(VALUE obj) {
46
- short status = sysinfo(&info) ;
44
+ char status = sysinfo(&info) ;
47
45
  if (status < 0) return Qnil ;
48
46
 
49
47
  VALUE _rb_v = ULL2NUM((unsigned long long) info.bufferram) ;
@@ -53,7 +51,7 @@ VALUE bufferram(VALUE obj) {
53
51
 
54
52
  VALUE totalswap(VALUE obj) {
55
53
  static struct sysinfo info ;
56
- short status = sysinfo(&info) ;
54
+ char status = sysinfo(&info) ;
57
55
  if (status < 0) return Qnil ;
58
56
 
59
57
  VALUE _rb_v = ULL2NUM((unsigned long long) info.totalswap) ;
@@ -62,7 +60,7 @@ VALUE totalswap(VALUE obj) {
62
60
  }
63
61
 
64
62
  VALUE freeswap(VALUE obj) {
65
- short status = sysinfo(&info) ;
63
+ char status = sysinfo(&info) ;
66
64
  if (status < 0) return Qnil ;
67
65
 
68
66
  VALUE _rb_v = ULL2NUM((unsigned long long) info.freeswap) ;
@@ -71,7 +69,7 @@ VALUE freeswap(VALUE obj) {
71
69
  }
72
70
 
73
71
  VALUE totalhigh(VALUE obj) {
74
- short status = sysinfo(&info) ;
72
+ char status = sysinfo(&info) ;
75
73
  if (status < 0) return Qnil ;
76
74
 
77
75
  VALUE _rb_v = ULL2NUM((unsigned long long) info.totalhigh) ;
@@ -80,7 +78,7 @@ VALUE totalhigh(VALUE obj) {
80
78
  }
81
79
 
82
80
  VALUE freehigh(VALUE obj) {
83
- short status = sysinfo(&info) ;
81
+ char status = sysinfo(&info) ;
84
82
  if (status < 0) return Qnil ;
85
83
 
86
84
  VALUE _rb_v = ULL2NUM((unsigned long long) info.freehigh) ;
@@ -89,15 +87,15 @@ VALUE freehigh(VALUE obj) {
89
87
  }
90
88
 
91
89
  VALUE uptime(VALUE obj) {
92
- short status = sysinfo(&info) ;
90
+ char status = sysinfo(&info) ;
93
91
  if (status < 0) return Qnil ;
94
92
 
95
- uint64_t v = info.uptime ;
93
+ unsigned long long v = info.uptime ;
96
94
  return ULL2NUM((unsigned long long) v) ;
97
95
  }
98
96
 
99
97
  VALUE loads(VALUE obj) {
100
- short status = sysinfo(&info) ;
98
+ char status = sysinfo(&info) ;
101
99
  if(status < 0) return rb_ary_new() ;
102
100
 
103
101
  long double load = 1.f / (1 << SI_LOAD_SHIFT) ;
@@ -113,6 +111,54 @@ VALUE loads(VALUE obj) {
113
111
  ) ;
114
112
  }
115
113
 
114
+ // Some people may need this function, just keep it to not make unnecessary calls
115
+ VALUE sysinfoStat(VALUE obj) {
116
+ char status = sysinfo(&info) ;
117
+ VALUE hash = rb_hash_new() ;
118
+ if (status < 0) return hash ;
119
+
120
+ unsigned long long mem_unit = info.mem_unit ;
121
+ VALUE _rb_mem_unit = ULL2NUM(mem_unit) ;
122
+
123
+ unsigned long long _totalram = info.totalram ;
124
+ unsigned long long _freeram = info.freeram ;
125
+ unsigned long long _sharedram = info.sharedram ;
126
+ unsigned long long _bufferram = info.bufferram ;
127
+ unsigned long long _totalswap = info.totalswap ;
128
+ unsigned long long _freeswap = info.freeswap ;
129
+ unsigned long long _totalhigh = info.totalhigh ;
130
+ unsigned long long _freehigh = info.freehigh ;
131
+ unsigned long long _uptime = info.uptime ;
132
+
133
+ long double load = 1.f / (1 << SI_LOAD_SHIFT) ;
134
+
135
+ float l_1 = info.loads[0] * load ;
136
+ float l_5 = info.loads[1] * load ;
137
+ float l_15 = info.loads[2] * load ;
138
+
139
+ VALUE loads = rb_ary_new_from_args(3,
140
+ rb_float_new(l_1),
141
+ rb_float_new(l_5),
142
+ rb_float_new(l_15)
143
+ ) ;
144
+
145
+ VALUE mul = rb_intern("*") ;
146
+
147
+ rb_hash_aset(hash, ID2SYM(rb_intern("totalram")), rb_funcallv_public(ULL2NUM(_totalram), mul, 1, &_rb_mem_unit)) ;
148
+ rb_hash_aset(hash, ID2SYM(rb_intern("freeram")), rb_funcallv_public(ULL2NUM(_freeram), mul, 1, &_rb_mem_unit)) ;
149
+ rb_hash_aset(hash, ID2SYM(rb_intern("sharedram")), rb_funcallv_public(ULL2NUM(_sharedram), mul, 1, &_rb_mem_unit)) ;
150
+ rb_hash_aset(hash, ID2SYM(rb_intern("bufferram")), rb_funcallv_public(ULL2NUM(_bufferram), mul, 1, &_rb_mem_unit)) ;
151
+ rb_hash_aset(hash, ID2SYM(rb_intern("totalswap")), rb_funcallv_public(ULL2NUM(_totalswap), mul, 1, &_rb_mem_unit)) ;
152
+ rb_hash_aset(hash, ID2SYM(rb_intern("freeswap")), rb_funcallv_public(ULL2NUM(_freeswap), mul, 1, &_rb_mem_unit)) ;
153
+ rb_hash_aset(hash, ID2SYM(rb_intern("totalhigh")), rb_funcallv_public(ULL2NUM(_totalhigh), mul, 1, &_rb_mem_unit)) ;
154
+ rb_hash_aset(hash, ID2SYM(rb_intern("freehigh")), rb_funcallv_public(ULL2NUM(_freehigh), mul, 1, &_rb_mem_unit)) ;
155
+ rb_hash_aset(hash, ID2SYM(rb_intern("uptime")), rb_funcallv_public(ULL2NUM(_uptime), mul, 1, &_rb_mem_unit)) ;
156
+
157
+ rb_hash_aset(hash, ID2SYM(rb_intern("loads")), loads) ;
158
+
159
+ return hash ;
160
+ }
161
+
116
162
  void Init_sysinfo() {
117
163
  VALUE _linux_stat = rb_define_module("LinuxStat") ;
118
164
  VALUE _sysinfo = rb_define_module_under(_linux_stat, "Sysinfo") ;
@@ -127,4 +173,5 @@ void Init_sysinfo() {
127
173
  rb_define_module_function(_sysinfo, "freehigh", freehigh, 0) ;
128
174
  rb_define_module_function(_sysinfo, "uptime", uptime, 0) ;
129
175
  rb_define_module_function(_sysinfo, "loads", loads, 0) ;
176
+ rb_define_module_function(_sysinfo, "stat", sysinfoStat, 0) ;
130
177
  }
@@ -17,7 +17,7 @@ static char *sysname = "", *nodename = "" ;
17
17
  static char *release = "", *version = "", *machine = "" ;
18
18
 
19
19
  void init_buf() {
20
- short status = uname(&buf) ;
20
+ char status = uname(&buf) ;
21
21
 
22
22
  if (status > -1) {
23
23
  sysname = buf.sysname ;
data/lib/linux_stat.rb CHANGED
@@ -25,13 +25,16 @@ require "linux_stat/battery"
25
25
  require "linux_stat/bios"
26
26
  require "linux_stat/net"
27
27
  require "linux_stat/pci"
28
- require "linux_stat/process"
29
28
  require "linux_stat/thermal"
30
29
  require "linux_stat/usb"
31
30
 
32
31
  # Dependent Modules
33
32
  # Modules that can have reverse dependency
34
33
 
34
+ # LinuxStat::ProcFS dependent modules
35
+ require "linux_stat/procfs"
36
+ require "linux_stat/process"
37
+
35
38
  # LinuxStat::CPU.sysinfo dependent modules
36
39
  require "linux_stat/sysinfo"
37
40
  require "linux_stat/swap"
@@ -178,7 +178,14 @@ module LinuxStat
178
178
  # For example, a sample output can be like this (taken on a test system):
179
179
  #
180
180
  # LinuxStat::Battery.devices_stat
181
- # => {:AC=>{:type=>"Mains", :online=>1}, :BAT0=>{:model=>"DELL CYMGM77", :manufacturer=>"Samsung SDI", :type=>"Battery", :status=>"Full", :capacity=>100, :voltage_min_design=>11.4, :charge_full_design=>3.684, :charge_full_design_wh=>42.0, :voltage_now=>12.558, :charge_now=>2.087, :charge_now_wh=>26.21, :charge_full_wh=>23.79, :charge_percentage=>100.0}, :hidpp_battery_0=>{:model=>"Wireless Keyboard", :manufacturer=>"Logitech", :type=>"Battery", :status=>"Discharging", :online=>1}}
181
+ # => {:AC=>{:type=>"Mains", :online=>1},
182
+ # :BAT0=>{:model=>"DELL CYMGM77", :manufacturer=>"Samsung SDI",
183
+ # :type=>"Battery", :status=>"Full", :capacity=>100, :voltage_min_design=>11.4,
184
+ # :charge_full_design=>3.684, :charge_full_design_wh=>42.0,
185
+ # :voltage_now=>12.558, :charge_now=>2.087, :charge_now_wh=>26.21,
186
+ # :charge_full_wh=>23.79, :charge_percentage=>100.0},
187
+ # :hidpp_battery_0=>{:model=>"Wireless Keyboard", :manufacturer=>"Logitech",
188
+ # :type=>"Battery", :status=>"Discharging", :online=>1}}
182
189
  #
183
190
  # If you need info about lots of batteries, use this method.
184
191
  # If the informations are not available, it will return empty Hash for each devices.
@@ -30,7 +30,7 @@ module LinuxStat
30
30
  data = IO.readlines(DEV).drop(2)
31
31
  indices = find_index_of_bytes
32
32
  data.reject! { |x| x.strip.start_with?('lo:') }
33
- r, t = data.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map(&:sum)
33
+ r, t = data.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map { |x| x.reduce(:+) }
34
34
 
35
35
  {
36
36
  received: r,
@@ -48,7 +48,7 @@ module LinuxStat
48
48
  data = IO.readlines(DEV).drop(2)
49
49
  index = find_index_of_bytes[0]
50
50
  data.reject! { |x| x.strip.start_with?('lo:') }
51
- data.map { |x| x.split[index].to_i }.sum
51
+ data.map { |x| x.split[index].to_i }.reduce(:+)
52
52
  end
53
53
 
54
54
  ##
@@ -61,7 +61,7 @@ module LinuxStat
61
61
  data = IO.readlines(DEV).drop(2)
62
62
  index = find_index_of_bytes[-1]
63
63
  data.reject! { |x| x.strip.start_with?('lo:') }
64
- data.map { |x| x.split[index].to_i }.sum
64
+ data.map { |x| x.split[index].to_i }.reduce(:+)
65
65
  end
66
66
 
67
67
  ##
@@ -89,13 +89,13 @@ module LinuxStat
89
89
  data = IO.readlines(DEV).drop(2)
90
90
  indices = find_index_of_bytes
91
91
  data.reject! { |x| x.strip.start_with?('lo:'.freeze) }
92
- r, t = data.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map(&:sum)
92
+ r, t = data.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map { |x| x.reduce(:+) }
93
93
 
94
94
  sleep(interval)
95
95
 
96
96
  data2 = IO.readlines(DEV).drop(2)
97
97
  data2.reject! { |x| x.strip.start_with?('lo:'.freeze) }
98
- r2, t2 = data2.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map(&:sum)
98
+ r2, t2 = data2.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map { |x| x.reduce(:+) }
99
99
 
100
100
  # Measure the difference
101
101
  dr, dt = r2.-(r).fdiv(interval), t2.-(t).fdiv(interval)
data/lib/linux_stat/os.rb CHANGED
@@ -140,29 +140,46 @@ module LinuxStat
140
140
  #
141
141
  # => {:hour=>10, :minute=>34, :second=>12.59}
142
142
  #
143
+ # Using uptime is 10x slower than using uptime_i
144
+ #
143
145
  # If the stat isn't available, an empty hash is returned.
144
146
  def uptime
145
- return {} unless uptime_readable?
147
+ _uptime = LinuxStat::ProcFS.uptime_f
148
+ return {} unless _uptime
146
149
 
147
- uptime = IO.read('/proc/uptime'.freeze).to_f
148
- uptime_i = uptime.to_i
150
+ uptime_i = _uptime.to_i
149
151
 
150
152
  h = uptime_i / 3600
151
153
  m = uptime_i % 3600 / 60
152
- s = uptime.%(3600).%(60).round(2)
154
+ s = _uptime.%(60).round(2)
153
155
 
154
156
  {
155
157
  hour: h,
156
158
  minute: m,
157
159
  second: s
158
- }.freeze
160
+ }
161
+ end
162
+
163
+ ##
164
+ # Returns Float uptime of the system reported by /proc/uptime
165
+ # LinuxStat::OS.uptime_f
166
+ #
167
+ # => 28956.34
168
+ #
169
+ # The value is generally rounded to 2 decimal places.
170
+ #
171
+ # Using uptime_f is 10x slower than using uptime_i
172
+ #
173
+ # If the stat isn't available, nil is returned.
174
+ def uptime_f
175
+ LinuxStat::ProcFS.uptime_f
159
176
  end
160
177
 
161
178
  ##
162
179
  # Returns uptime of the system reported by LinuxStat::Sysinfo.uptime()
163
180
  # LinuxStat::OS.uptime_i
164
181
  #
165
- # 28956
182
+ # => 28956
166
183
  #
167
184
  # If the stat isn't available, nil is returned.
168
185
  def uptime_i
@@ -214,10 +231,6 @@ module LinuxStat
214
231
  h.merge!( key.to_sym => value )
215
232
  }
216
233
  end
217
-
218
- def uptime_readable?
219
- @@uptime_readable ||= File.readable?('/proc/uptime')
220
- end
221
234
  end
222
235
  end
223
236
  end
@@ -86,7 +86,7 @@ module LinuxStat
86
86
 
87
87
  begin
88
88
  h.merge!(x =>
89
- case IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip
89
+ case LinuxStat::ProcFS.ps_state(x)
90
90
  when ?S.freeze then :sleeping
91
91
  when ?I.freeze then :idle
92
92
  when ?Z.freeze then :zombie
@@ -110,11 +110,7 @@ module LinuxStat
110
110
  # The return type is an Array of Integers.
111
111
  def sleeping
112
112
  list.select { |x|
113
- begin
114
- IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?S.freeze
115
- rescue StandardError
116
- false
117
- end
113
+ LinuxStat::ProcFS.ps_state(x) == ?S.freeze
118
114
  }
119
115
  end
120
116
 
@@ -123,11 +119,7 @@ module LinuxStat
123
119
  # The return type is an Array of Integers.
124
120
  def idle
125
121
  list.select { |x|
126
- begin
127
- IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?I.freeze
128
- rescue StandardError
129
- false
130
- end
122
+ LinuxStat::ProcFS.ps_state(x) == ?I.freeze
131
123
  }
132
124
  end
133
125
 
@@ -136,11 +128,7 @@ module LinuxStat
136
128
  # The return type is an Array of Integers.
137
129
  def zombie
138
130
  list.select { |x|
139
- begin
140
- IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?Z.freeze
141
- rescue StandardError
142
- false
143
- end
131
+ LinuxStat::ProcFS.ps_state(x) == ?Z.freeze
144
132
  }
145
133
  end
146
134
 
@@ -149,11 +137,7 @@ module LinuxStat
149
137
  # The return type is an Array of Integers.
150
138
  def running
151
139
  list.select { |x|
152
- begin
153
- IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?R.freeze
154
- rescue StandardError
155
- false
156
- end
140
+ LinuxStat::ProcFS.ps_state(x) == ?R.freeze
157
141
  }
158
142
  end
159
143
 
@@ -162,14 +146,20 @@ module LinuxStat
162
146
  # The return type is an Array of Integers.
163
147
  def stopped
164
148
  list.select { |x|
165
- begin
166
- v = IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip
167
- v == ?T.freeze || v == ?t.freeze
168
- rescue StandardError
169
- false
170
- end
149
+ v = LinuxStat::ProcFS.ps_state(x)
150
+ v == ?T.freeze || v == ?t.freeze
171
151
  }
172
152
  end
153
+
154
+ ##
155
+ # Returns the last_pid of the system.
156
+ # It directly calls LS::ProcFS.last_pid
157
+ #
158
+ # The return value is Integer, but if the status
159
+ # isn't available, it will return nil
160
+ def last_pid
161
+ LinuxStat::ProcFS.last_pid
162
+ end
173
163
  end
174
164
  end
175
165
  end
@@ -149,20 +149,7 @@ module LinuxStat
149
149
  #
150
150
  # If the info isn't available it will return an empty Hash.
151
151
  def mem_stat(pid = $$)
152
- statm = "/proc/#{pid}/statm".freeze
153
- return {} unless File.readable?(statm)
154
-
155
- data = IO.read(statm).split
156
-
157
- _rss_anon = (data[1] && data[2]) ? data[1].to_i.-(data[2].to_i).*(pagesize).fdiv(1000) : nil
158
- _virtual_memory = data[0] ? data[0].to_i*(pagesize).fdiv(1000) : nil
159
- _resident_memory = data[1] ? data[1].to_i.*(pagesize).fdiv(1000) : nil
160
-
161
- {
162
- memory: _rss_anon,
163
- virtual_memory: _virtual_memory,
164
- resident_memory: _resident_memory
165
- }
152
+ LinuxStat::ProcFS.statm(pid)
166
153
  end
167
154
 
168
155
  ##
@@ -182,11 +169,7 @@ module LinuxStat
182
169
  #
183
170
  # If the info isn't available it will return nil.
184
171
  def memory(pid = $$)
185
- file = "/proc/#{pid}/statm".freeze
186
- return nil unless File.readable?(file)
187
-
188
- data = IO.read(file).split
189
- (data[1] && data[2]) ? data[1].to_i.-(data[2].to_i).*(pagesize).fdiv(1000) : nil
172
+ LinuxStat::ProcFS.statm_memory(pid) &.fdiv(1000)
190
173
  end
191
174
 
192
175
  ##
@@ -207,11 +190,7 @@ module LinuxStat
207
190
  #
208
191
  # If the info isn't available it will return nil.
209
192
  def virtual_memory(pid = $$)
210
- file = "/proc/#{pid}/statm".freeze
211
- return nil unless File.readable?(file)
212
-
213
- _virtual_memory = IO.read(file).split[0]
214
- _virtual_memory ? _virtual_memory.to_i.*(pagesize).fdiv(1000) : nil
193
+ LinuxStat::ProcFS.statm_virtual(pid) &.fdiv(1000)
215
194
  end
216
195
 
217
196
  ##
@@ -226,17 +205,34 @@ module LinuxStat
226
205
  # The value is in kilobytes.
227
206
  #
228
207
  # The output is an Integer. For example:
229
- # LinuxStat::ProcessInfo.cpu_stat
208
+ # LinuxStat::ProcessInfo.resident_memory
230
209
  #
231
210
  # => 13996.032
232
211
  #
233
212
  # If the info isn't available it will return nil.
234
213
  def resident_memory(pid = $$)
235
- file = "/proc/#{pid}/statm".freeze
236
- return nil unless File.readable?(file)
214
+ LinuxStat::ProcFS.statm_resident(pid) &.fdiv(1000)
215
+ end
237
216
 
238
- _vm_rss = IO.read(file).split[1]
239
- _vm_rss ? _vm_rss.to_i.*(pagesize).fdiv(1000) : nil
217
+ ##
218
+ # = shared_memory(pid = $$)
219
+ #
220
+ # Where pid is the process ID.
221
+ #
222
+ # By default it is the id of the current process ($$)
223
+ #
224
+ # It retuns the shared memory for the process.
225
+ #
226
+ # The value is in kilobytes.
227
+ #
228
+ # The output is an Integer. For example:
229
+ # LinuxStat::ProcessInfo.shared_memory
230
+ #
231
+ # => 13996.032
232
+ #
233
+ # If the info isn't available it will return nil.
234
+ def shared_memory(pid = $$)
235
+ LinuxStat::ProcFS.statm_shared(pid) &.fdiv(1000)
240
236
  end
241
237
 
242
238
  ##
@@ -282,37 +278,31 @@ module LinuxStat
282
278
  #
283
279
  # The :last_executed_cpu also returns an Integer indicating the last executed cpu of the process.
284
280
  def cpu_stat(pid: $$, sleep: ticks_to_ms_t5)
285
- file = "/proc/#{pid}/stat"
286
281
  ticks = get_ticks
282
+ stat = LinuxStat::ProcFS.ps_stat(pid)
283
+ uptime = LS::ProcFS.uptime_f
284
+ return {} unless uptime && !stat.empty?
287
285
 
288
- return {} unless File.readable?(file)
289
-
290
- stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
291
- return {} unless stat
292
-
293
- utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
294
-
295
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
286
+ utime, stime, starttime = *stat.values_at(10, 11, 18).map(&:to_f)
287
+ uptime *= ticks
296
288
 
297
289
  total_time = utime + stime
298
290
  idle1 = uptime - starttime - total_time
299
291
 
300
292
  sleep(sleep)
301
293
 
302
- return {} unless File.readable?(file)
303
-
304
- stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
305
- return {} unless stat
306
-
307
- utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
294
+ stat = LinuxStat::ProcFS.ps_stat(pid)
295
+ uptime = LS::ProcFS.uptime_f
296
+ return {} unless uptime && !stat.empty?
308
297
 
309
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
298
+ utime2, stime2, starttime2 = *stat.values_at(10, 11, 18).map(&:to_f)
299
+ uptime *= ticks
310
300
 
311
301
  total_time2 = utime2 + stime2
312
302
  idle2 = uptime - starttime2 - total_time2
313
303
 
314
304
  totald = idle2.+(total_time2).-(idle1 + total_time)
315
- cpu_u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)./(cpu_count)
305
+ cpu_u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)./(LinuxStat::CPU.count)
316
306
 
317
307
  {
318
308
  cpu_usage: cpu_u > 100 ? 100.0 : cpu_u.round(2),
@@ -348,37 +338,10 @@ module LinuxStat
348
338
  #
349
339
  # This method is more efficient than running LinuxStat::ProcessInfo.cpu_stat()
350
340
  def cpu_usage(pid: $$, sleep: ticks_to_ms_t5)
351
- file = "/proc/#{pid}/stat"
352
- ticks = get_ticks
353
-
354
- return nil unless File.readable?(file)
355
-
356
- stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
357
- return nil unless stat
358
-
359
- utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
360
-
361
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
362
-
363
- total_time = utime + stime
364
- idle1 = uptime - starttime - total_time
365
-
366
- sleep(sleep)
367
-
368
- return nil unless File.readable?(file)
369
-
370
- stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
371
- return nil unless stat
372
-
373
- utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
374
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
341
+ u = cpu_usage_thread(pid, sleep)
342
+ return nil unless u
375
343
 
376
- total_time2 = utime2 + stime2
377
- idle2 = uptime - starttime2 - total_time2
378
-
379
- totald = idle2.+(total_time2).-(idle1 + total_time)
380
-
381
- u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)./(cpu_count)
344
+ u /= LinuxStat::CPU.count
382
345
  u > 100 ? 100.0 : u.round(2)
383
346
  end
384
347
 
@@ -405,40 +368,10 @@ module LinuxStat
405
368
  #
406
369
  # But if the info isn't available, it will return nil.
407
370
  def thread_usage(pid: $$, sleep: ticks_to_ms_t5)
408
- file = "/proc/#{pid}/stat"
409
- ticks = get_ticks
410
-
411
- return nil unless File.readable?(file)
371
+ u = cpu_usage_thread(pid, sleep)
372
+ return nil unless u
412
373
 
413
- stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
414
- return nil unless stat
415
-
416
- utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
417
-
418
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
419
-
420
- total_time = utime + stime
421
- idle1 = uptime - starttime - total_time
422
-
423
- sleep(sleep)
424
-
425
- return nil unless File.readable?(file)
426
-
427
- stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
428
- return nil unless stat
429
-
430
- utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
431
-
432
- uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
433
-
434
- total_time2 = utime2 + stime2
435
- idle2 = uptime - starttime2 - total_time2
436
-
437
- totald = idle2.+(total_time2).-(idle1 + total_time)
438
-
439
- u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)
440
-
441
- cpu_count_t100 = cpu_count * 100
374
+ cpu_count_t100 = LinuxStat::CPU.count * 100
442
375
  u > cpu_count_t100 ? cpu_count_t100 : u.round(2)
443
376
  end
444
377
 
@@ -460,11 +393,7 @@ module LinuxStat
460
393
  #
461
394
  # This method is way more efficient than running LinuxStat::ProcessInfo.cpu_stat()
462
395
  def threads(pid = $$)
463
- file = "/proc/#{pid}/stat".freeze
464
- return nil unless File.readable?(file)
465
-
466
- data = IO.read(file).split(/(\(.*\))/)[-1] &.split &.at(17)
467
- data ? data.to_i : nil
396
+ LinuxStat::ProcFS.ps_stat(pid)[16]
468
397
  end
469
398
 
470
399
  ##
@@ -485,11 +414,7 @@ module LinuxStat
485
414
  #
486
415
  # This method is way more efficient than running LinuxStat::ProcessInfo.cpu_stat()
487
416
  def last_executed_cpu(pid = $$)
488
- file = "/proc/#{pid}/stat".freeze
489
- return nil unless File.readable?(file)
490
-
491
- data = IO.read(file).split(/(\(.*\))/)[-1] &.split &.at(36)
492
- data ? data.to_i : nil
417
+ LinuxStat::ProcFS.ps_stat(pid)[35]
493
418
  end
494
419
 
495
420
  ##
@@ -566,21 +491,15 @@ module LinuxStat
566
491
  #
567
492
  # If the info isn't available or the argument passed doesn't exist as a process ID, it will return nil.
568
493
  def start_time_epoch(pid = $$)
569
- stat_file = "/proc/#{pid}/stat".freeze
570
- uptime = "/proc/uptime".freeze
571
-
572
- @@u_readable ||= File.readable?(uptime)
573
- return nil unless @@u_readable && File.readable?(stat_file)
494
+ uptime = LS::ProcFS.uptime_f
495
+ stat = LinuxStat::ProcFS.ps_stat(pid)[18]
574
496
 
575
- stat = IO.read(stat_file).split(/(\(.*\))/)[-1] &.split
576
- return nil unless stat
577
-
578
- u = IO.foreach(uptime, ' '.freeze).next.to_f
579
- st = stat[19].to_f / get_ticks
497
+ return nil unless uptime && stat
498
+ st = stat.to_f / get_ticks
580
499
 
581
500
  # Getting two Time objects and dealing with floating point numbers
582
- # Just to make sure the time goes monotonically
583
- Time.now.-(u - st).to_i
501
+ # Just to make sure the time goes monotonically unless the clock changes
502
+ Time.now.-(uptime - st).to_i
584
503
  end
585
504
 
586
505
  ##
@@ -619,17 +538,10 @@ module LinuxStat
619
538
  #
620
539
  # If the info isn't available or the argument passed doesn't exist as a process ID, it will return nil.
621
540
  def running_time(pid = $$)
622
- stat_file = "/proc/#{pid}/stat".freeze
623
- uptime = "/proc/uptime".freeze
624
-
625
- @@u_readable ||= File.readable?(uptime)
626
- return nil unless @@u_readable && File.readable?(stat_file)
627
-
628
- stat = IO.read(stat_file).split(/(\(.*\))/)[-1] &.split
629
- return nil unless stat
630
-
631
- IO.foreach(uptime, ' '.freeze).next.to_f
632
- .-(stat[19].to_f / get_ticks).round(2)
541
+ uptime = LS::ProcFS.uptime_f
542
+ stat = LinuxStat::ProcFS.ps_stat(pid)[18]
543
+ return nil unless uptime && stat
544
+ uptime.-(stat.to_f / get_ticks).round(2)
633
545
  end
634
546
 
635
547
  ##
@@ -651,13 +563,7 @@ module LinuxStat
651
563
  # If the info isn't available or the argument passed doesn't exist as a process ID,
652
564
  # it will return an empty String.
653
565
  def state(pid = $$)
654
- file = "/proc/#{pid}/stat".freeze
655
- return ''.freeze unless File.readable?(file)
656
-
657
- stat = IO.read(file).split(/(\(.*\))/)[-1]
658
- return '' unless stat
659
-
660
- stat[/\s.+?/].strip
566
+ LinuxStat::ProcFS.ps_state(pid)
661
567
  end
662
568
 
663
569
  ##
@@ -670,13 +576,7 @@ module LinuxStat
670
576
  #
671
577
  # If the info isn't available or the argument passed doesn't exist as a process ID, it will return nil.
672
578
  def nice(pid = $$)
673
- file = "/proc/#{pid}/stat"
674
- return nil unless File.readable?(file)
675
-
676
- stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
677
- return nil unless stat
678
-
679
- stat[16].to_i
579
+ LinuxStat::ProcFS.ps_stat(pid)[15]
680
580
  end
681
581
 
682
582
  ##
@@ -709,6 +609,41 @@ module LinuxStat
709
609
  LinuxStat::Nproc.count_cpu_for_pid(pid)
710
610
  end
711
611
 
612
+ ##
613
+ # = def cpu_times_i(pid = $$)
614
+ #
615
+ # Shows the CPU time used by the process.
616
+ #
617
+ # The return value is an Integer.
618
+ def cpu_time(pid = $$)
619
+ times = LinuxStat::ProcFS.ps_stat(pid)
620
+ utime, stime, cutime, cstime = times[10], times[11], times[12], times[13]
621
+ return nil unless utime && stime && cutime && cstime
622
+
623
+ utime.+(stime).+(cutime).+(cstime) / get_ticks
624
+ end
625
+
626
+ ##
627
+ # = def cpu_times(pid = $$)
628
+ #
629
+ # Shows the CPU time used by the process.
630
+ #
631
+ # The return value is a Hash.
632
+ def cpu_times(pid = $$)
633
+ v = cpu_time(pid)
634
+ return {} unless v
635
+
636
+ hour = v / 3600
637
+ min = v % 3600 / 60
638
+ sec = v % 60
639
+
640
+ {
641
+ hour: hour,
642
+ minute: min,
643
+ second: sec
644
+ }
645
+ end
646
+
712
647
  alias count_cpu nproc
713
648
 
714
649
  private
@@ -728,8 +663,33 @@ module LinuxStat
728
663
  @@pagesize ||= LinuxStat::Sysconf.pagesize.to_i
729
664
  end
730
665
 
731
- def cpu_count
732
- @@nprocessors_conf ||= LinuxStat::CPU.count
666
+ def cpu_usage_thread(pid, delay)
667
+ ticks = get_ticks
668
+ stat = LinuxStat::ProcFS.ps_stat(pid)
669
+ uptime = LS::ProcFS.uptime_f
670
+ return nil unless uptime && !stat.empty?
671
+
672
+ utime, stime, starttime = *stat.values_at(10, 11, 18).map(&:to_f)
673
+ uptime *= ticks
674
+
675
+ total_time = utime + stime
676
+ idle1 = uptime - starttime - total_time
677
+
678
+ sleep(delay)
679
+
680
+ stat = LinuxStat::ProcFS.ps_stat(pid)
681
+ uptime = LS::ProcFS.uptime_f
682
+ return nil unless uptime && !stat.empty?
683
+
684
+ utime2, stime2, starttime2 = *stat.values_at(10, 11, 18).map(&:to_f)
685
+ uptime *= ticks
686
+
687
+ total_time2 = utime2 + stime2
688
+ idle2 = uptime - starttime2 - total_time2
689
+
690
+ totald = idle2.+(total_time2).-(idle1 + total_time)
691
+
692
+ totald.-(idle2 - idle1).fdiv(totald).abs.*(100)
733
693
  end
734
694
  end
735
695
  end