sys-cpu 1.0.1 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +22 -0
- data/Gemfile +2 -7
- data/MANIFEST.md +1 -0
- data/README.md +21 -14
- data/Rakefile +4 -1
- data/doc/bsd.md +58 -0
- data/doc/linux.md +46 -0
- data/install.rb +2 -2
- data/lib/sys/cpu.rb +10 -1
- data/lib/sys/darwin/sys/cpu.rb +198 -0
- data/lib/sys/linux/sys/cpu.rb +43 -43
- data/lib/sys/unix/sys/cpu.rb +57 -97
- data/lib/sys/windows/sys/cpu.rb +430 -311
- data/lib/sys-cpu.rb +2 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/sys_cpu_bsd_spec.rb +53 -51
- data/spec/sys_cpu_hpux_spec.rb +33 -28
- data/spec/sys_cpu_linux_spec.rb +32 -26
- data/spec/{sys_cpu_spec.rb → sys_cpu_shared.rb} +10 -4
- data/spec/sys_cpu_sunos_spec.rb +44 -42
- data/spec/sys_cpu_windows_spec.rb +39 -34
- data/sys-cpu.gemspec +4 -4
- data.tar.gz.sig +0 -0
- metadata +40 -11
- metadata.gz.sig +0 -0
- data/doc/bsd.txt +0 -49
- data/doc/linux.txt +0 -41
data/lib/sys/linux/sys/cpu.rb
CHANGED
@@ -1,53 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
##########################################################
|
2
4
|
# linux.rb (sys-cpu) - pure Ruby version for Linux
|
3
5
|
##########################################################
|
4
|
-
module Sys
|
5
6
|
|
7
|
+
# The Sys module is a namespace only.
|
8
|
+
module Sys
|
6
9
|
# :stopdoc:
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
cpu_file = "/proc/cpuinfo"
|
11
|
-
cpu_hash = {}
|
11
|
+
cpu_file = '/proc/cpuinfo'
|
12
|
+
cpu_hash = {}
|
12
13
|
CPU_ARRAY = []
|
13
14
|
|
15
|
+
private_constant :CPU_ARRAY
|
16
|
+
|
14
17
|
# Parse the info out of the /proc/cpuinfo file
|
15
|
-
|
18
|
+
File.foreach(cpu_file) do |line|
|
16
19
|
line.strip!
|
17
20
|
next if line.empty?
|
18
21
|
|
19
|
-
key, val = line.split(
|
22
|
+
key, val = line.split(':')
|
20
23
|
key.strip!
|
21
|
-
key.gsub!(/\s+/,
|
24
|
+
key.gsub!(/\s+/, '_')
|
22
25
|
key.downcase!
|
23
26
|
val.strip! if val
|
24
27
|
|
25
|
-
if cpu_hash.
|
28
|
+
if cpu_hash.key?(key)
|
26
29
|
CPU_ARRAY.push(cpu_hash.dup)
|
27
30
|
cpu_hash.clear
|
28
31
|
end
|
29
32
|
|
30
33
|
# Turn yes/no attributes into booleans
|
31
|
-
if val == 'yes'
|
32
|
-
|
33
|
-
elsif val == 'no'
|
34
|
-
val = false
|
35
|
-
end
|
34
|
+
val = true if val == 'yes'
|
35
|
+
val = false if val == 'no'
|
36
36
|
|
37
37
|
cpu_hash[key] = val
|
38
|
-
|
38
|
+
end
|
39
39
|
|
40
40
|
CPU_ARRAY.push(cpu_hash)
|
41
41
|
|
42
|
-
public
|
43
|
-
|
44
42
|
# :startdoc:
|
45
43
|
|
44
|
+
# The CPU class encapsulates information about physical CPUs on your system.
|
46
45
|
class CPU
|
47
|
-
|
48
46
|
# :stopdoc:
|
49
47
|
|
50
|
-
CPUStruct = Struct.new(
|
48
|
+
CPUStruct = Struct.new('CPUStruct', *CPU_ARRAY.first.keys)
|
49
|
+
|
50
|
+
private_constant :CPUStruct
|
51
51
|
|
52
52
|
# :startdoc:
|
53
53
|
|
@@ -58,15 +58,15 @@ module Sys
|
|
58
58
|
#
|
59
59
|
def self.processors
|
60
60
|
array = []
|
61
|
-
CPU_ARRAY.each
|
61
|
+
CPU_ARRAY.each do |hash|
|
62
62
|
struct = CPUStruct.new
|
63
|
-
struct.members.each{ |m| struct.send("#{m}=", hash[
|
63
|
+
struct.members.each{ |m| struct.send("#{m}=", hash[m.to_s]) }
|
64
64
|
if block_given?
|
65
65
|
yield struct
|
66
66
|
else
|
67
67
|
array << struct
|
68
68
|
end
|
69
|
-
|
69
|
+
end
|
70
70
|
array unless block_given?
|
71
71
|
end
|
72
72
|
|
@@ -80,12 +80,10 @@ module Sys
|
|
80
80
|
#
|
81
81
|
def self.architecture
|
82
82
|
case CPU_ARRAY.first['cpu_family']
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
else
|
88
|
-
nil
|
83
|
+
when '3'
|
84
|
+
'x86'
|
85
|
+
when '6'
|
86
|
+
'x86_64'
|
89
87
|
end
|
90
88
|
end
|
91
89
|
|
@@ -101,28 +99,30 @@ module Sys
|
|
101
99
|
CPU_ARRAY.first['cpu_mhz'].to_f.round
|
102
100
|
end
|
103
101
|
|
104
|
-
private
|
105
|
-
|
106
102
|
# Create singleton methods for each of the attributes.
|
107
103
|
#
|
108
|
-
def self.method_missing(id, arg=0)
|
109
|
-
raise NoMethodError, "'#{id}'" unless CPU_ARRAY[arg].
|
104
|
+
def self.method_missing(id, arg = 0)
|
105
|
+
raise NoMethodError, "'#{id}'" unless CPU_ARRAY[arg].key?(id.to_s)
|
110
106
|
rv = CPU_ARRAY[arg][id.to_s]
|
111
107
|
if rv.nil?
|
112
|
-
id = id
|
108
|
+
id = "#{id}?"
|
113
109
|
rv = CPU_ARRAY[arg][id]
|
114
110
|
end
|
115
111
|
rv
|
116
112
|
end
|
117
113
|
|
118
|
-
|
114
|
+
def self.respond_to_missing?(method, _private_methods = false)
|
115
|
+
CPU_ARRAY.first.keys.include?(method.to_s)
|
116
|
+
end
|
117
|
+
|
118
|
+
private_class_method :method_missing
|
119
119
|
|
120
120
|
# Returns a 3 element Array corresponding to the 1, 5 and 15 minute
|
121
121
|
# load average for the system.
|
122
122
|
#
|
123
123
|
def self.load_avg
|
124
|
-
load_avg_file =
|
125
|
-
|
124
|
+
load_avg_file = '/proc/loadavg'
|
125
|
+
File.readlines(load_avg_file).first.split[0..2].map(&:to_f)
|
126
126
|
end
|
127
127
|
|
128
128
|
# Returns a hash of arrays that contains an array of the following
|
@@ -142,24 +142,24 @@ module Sys
|
|
142
142
|
# Note that older kernels may not necessarily include some of these fields.
|
143
143
|
#
|
144
144
|
def self.cpu_stats
|
145
|
-
cpu_stat_file =
|
145
|
+
cpu_stat_file = '/proc/stat'
|
146
146
|
hash = {} # Hash needed for multi-cpu systems
|
147
147
|
|
148
|
-
lines =
|
148
|
+
lines = File.readlines(cpu_stat_file)
|
149
149
|
|
150
|
-
lines.each_with_index
|
150
|
+
lines.each_with_index do |line, i|
|
151
151
|
array = line.split
|
152
|
-
break unless array[0] =~ /cpu/
|
152
|
+
break unless array[0] =~ /cpu/ # 'cpu' entries always on top
|
153
153
|
|
154
154
|
# Some machines list a 'cpu' and a 'cpu0'. In this case only
|
155
155
|
# return values for the numbered cpu entry.
|
156
|
-
if lines[i].split[0] ==
|
156
|
+
if lines[i].split[0] == 'cpu' && lines[i + 1].split[0] =~ /cpu\d/
|
157
157
|
next
|
158
158
|
end
|
159
159
|
|
160
|
-
vals = array[1..-1].map{ |e| e
|
160
|
+
vals = array[1..-1].map{ |e| e.to_i / 100 } # 100 jiffies/sec.
|
161
161
|
hash[array[0]] = vals
|
162
|
-
|
162
|
+
end
|
163
163
|
|
164
164
|
hash
|
165
165
|
end
|
data/lib/sys/unix/sys/cpu.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ffi'
|
2
4
|
require 'rbconfig'
|
3
5
|
|
6
|
+
# The Sys module is a name space only.
|
4
7
|
module Sys
|
8
|
+
# The CPU class encapsulates information about the physical CPU's on your system.
|
5
9
|
class CPU
|
6
10
|
extend FFI::Library
|
7
11
|
ffi_lib FFI::Library::LIBC
|
@@ -43,7 +47,7 @@ module Sys
|
|
43
47
|
begin
|
44
48
|
attach_function(
|
45
49
|
:sysctl,
|
46
|
-
[
|
50
|
+
%i[pointer uint pointer pointer pointer size_t],
|
47
51
|
:int
|
48
52
|
)
|
49
53
|
private_class_method :sysctl
|
@@ -54,7 +58,7 @@ module Sys
|
|
54
58
|
begin
|
55
59
|
attach_function(
|
56
60
|
:sysctlbyname,
|
57
|
-
[
|
61
|
+
%i[string pointer pointer pointer size_t],
|
58
62
|
:int
|
59
63
|
)
|
60
64
|
private_class_method :sysctlbyname
|
@@ -64,10 +68,10 @@ module Sys
|
|
64
68
|
|
65
69
|
# Solaris
|
66
70
|
begin
|
67
|
-
attach_function :getloadavg, [
|
68
|
-
attach_function :processor_info, [
|
71
|
+
attach_function :getloadavg, %i[pointer int], :int
|
72
|
+
attach_function :processor_info, %i[int pointer], :int
|
69
73
|
attach_function :sysconf, [:int], :long
|
70
|
-
attach_function :sysinfo, [
|
74
|
+
attach_function :sysinfo, %i[int pointer long], :int
|
71
75
|
|
72
76
|
private_class_method :getloadavg
|
73
77
|
private_class_method :processor_info
|
@@ -95,7 +99,7 @@ module Sys
|
|
95
99
|
buf = 0.chr * 257
|
96
100
|
|
97
101
|
if sysinfo(SI_ARCHITECTURE, buf, buf.size) < 0
|
98
|
-
raise Error,
|
102
|
+
raise Error, 'sysinfo function failed'
|
99
103
|
end
|
100
104
|
|
101
105
|
buf.strip
|
@@ -105,14 +109,8 @@ module Sys
|
|
105
109
|
|
106
110
|
size.write_int(optr.size)
|
107
111
|
|
108
|
-
if
|
109
|
-
|
110
|
-
else
|
111
|
-
name = 'hw.machine_arch'
|
112
|
-
end
|
113
|
-
|
114
|
-
if sysctlbyname(name, optr, size, nil, 0) < 0
|
115
|
-
raise Error, "sysctlbyname function failed"
|
112
|
+
if sysctlbyname('hw.machine_arch', optr, size, nil, 0) < 0
|
113
|
+
raise Error, 'sysctlbyname function failed'
|
116
114
|
end
|
117
115
|
|
118
116
|
optr.read_string
|
@@ -125,7 +123,7 @@ module Sys
|
|
125
123
|
size.write_int(buf.size)
|
126
124
|
|
127
125
|
if sysctl(mib, 2, buf, size, nil, 0) < 0
|
128
|
-
raise Error,
|
126
|
+
raise Error, 'sysctl function failed'
|
129
127
|
end
|
130
128
|
|
131
129
|
buf.strip
|
@@ -144,7 +142,7 @@ module Sys
|
|
144
142
|
size.write_long(optr.size)
|
145
143
|
|
146
144
|
if sysctlbyname('hw.ncpu', optr, size, nil, 0) < 0
|
147
|
-
raise Error,
|
145
|
+
raise Error, 'sysctlbyname failed'
|
148
146
|
end
|
149
147
|
|
150
148
|
optr.read_long
|
@@ -152,7 +150,7 @@ module Sys
|
|
152
150
|
num = sysconf(SC_NPROCESSORS_ONLN)
|
153
151
|
|
154
152
|
if num < 0
|
155
|
-
raise Error,
|
153
|
+
raise Error, 'sysconf function failed'
|
156
154
|
end
|
157
155
|
|
158
156
|
num
|
@@ -165,10 +163,10 @@ module Sys
|
|
165
163
|
size.write_int(buf.size)
|
166
164
|
|
167
165
|
if sysctl(mib, 2, buf, size, nil, 0) < 0
|
168
|
-
raise Error,
|
166
|
+
raise Error, 'sysctl function failed'
|
169
167
|
end
|
170
168
|
|
171
|
-
buf.strip.
|
169
|
+
buf.strip.unpack1('C')
|
172
170
|
end
|
173
171
|
end
|
174
172
|
|
@@ -186,70 +184,44 @@ module Sys
|
|
186
184
|
size.write_int(buf.size)
|
187
185
|
|
188
186
|
if sysctl(mib, 2, buf, size, nil, 0) < 0
|
189
|
-
raise Error,
|
187
|
+
raise Error, 'sysctl function failed'
|
190
188
|
end
|
191
|
-
|
192
|
-
buf.strip
|
193
189
|
else
|
194
190
|
buf = 0.chr * 257
|
195
191
|
|
196
192
|
if sysinfo(SI_MACHINE, buf, buf.size) < 0
|
197
|
-
raise Error,
|
193
|
+
raise Error, 'sysinfo function failed'
|
198
194
|
end
|
199
|
-
|
200
|
-
buf.strip
|
201
195
|
end
|
196
|
+
|
197
|
+
buf.strip
|
202
198
|
end
|
203
199
|
|
204
200
|
# Returns a string indicating the cpu model.
|
205
201
|
#
|
206
202
|
def self.model
|
207
|
-
if
|
208
|
-
|
209
|
-
|
203
|
+
if respond_to?(:sysctl, true)
|
204
|
+
buf = 0.chr * 64
|
205
|
+
mib = FFI::MemoryPointer.new(:int, 2)
|
206
|
+
size = FFI::MemoryPointer.new(:long, 1)
|
210
207
|
|
211
|
-
|
208
|
+
mib.write_array_of_int([CTL_HW, HW_MODEL])
|
209
|
+
size.write_int(buf.size)
|
212
210
|
|
213
|
-
if
|
214
|
-
raise
|
211
|
+
if sysctl(mib, 2, buf, size, nil, 0) < 0
|
212
|
+
raise Error, 'sysctl function failed'
|
215
213
|
end
|
216
214
|
|
217
|
-
|
218
|
-
when CPU_TYPE_X86, CPU_TYPE_X86_64
|
219
|
-
"Intel"
|
220
|
-
when CPU_TYPE_SPARC
|
221
|
-
"Sparc"
|
222
|
-
when CPU_TYPE_POWERPC, CPU_TYPE_POWERPC64
|
223
|
-
"PowerPC"
|
224
|
-
else
|
225
|
-
"Unknown"
|
226
|
-
end
|
215
|
+
buf.strip
|
227
216
|
else
|
228
|
-
|
229
|
-
buf = 0.chr * 64
|
230
|
-
mib = FFI::MemoryPointer.new(:int, 2)
|
231
|
-
size = FFI::MemoryPointer.new(:long, 1)
|
232
|
-
|
233
|
-
mib.write_array_of_int([CTL_HW, HW_MODEL])
|
234
|
-
size.write_int(buf.size)
|
235
|
-
|
236
|
-
if sysctl(mib, 2, buf, size, nil, 0) < 0
|
237
|
-
raise Error, "sysctl function failed"
|
238
|
-
end
|
239
|
-
|
240
|
-
buf.strip
|
241
|
-
else
|
242
|
-
pinfo = ProcInfo.new
|
243
|
-
|
244
|
-
# Some systems start at 0, some at 1
|
245
|
-
if processor_info(0, pinfo) < 0
|
246
|
-
if processor_info(1, pinfo) < 0
|
247
|
-
raise Error, "process_info function failed"
|
248
|
-
end
|
249
|
-
end
|
217
|
+
pinfo = ProcInfo.new
|
250
218
|
|
251
|
-
|
219
|
+
# Some systems start at 0, some at 1
|
220
|
+
if processor_info(0, pinfo) < 0 && processor_info(1, pinfo) < 0
|
221
|
+
raise Error, 'processor_info function failed'
|
252
222
|
end
|
223
|
+
|
224
|
+
pinfo[:pi_processor_type].to_s
|
253
225
|
end
|
254
226
|
end
|
255
227
|
|
@@ -269,14 +241,10 @@ module Sys
|
|
269
241
|
end
|
270
242
|
|
271
243
|
if sysctlbyname(name, optr, size, nil, 0) < 0
|
272
|
-
raise Error,
|
244
|
+
raise Error, 'sysctlbyname failed'
|
273
245
|
end
|
274
246
|
|
275
|
-
|
276
|
-
optr.read_long / 1000000
|
277
|
-
else
|
278
|
-
optr.read_long
|
279
|
-
end
|
247
|
+
optr.read_long
|
280
248
|
elsif respond_to?(:sysctl, true)
|
281
249
|
buf = 0.chr * 16
|
282
250
|
mib = FFI::MemoryPointer.new(:int, 2)
|
@@ -286,18 +254,16 @@ module Sys
|
|
286
254
|
size.write_int(buf.size)
|
287
255
|
|
288
256
|
if sysctl(mib, 2, buf, size, nil, 0) < 0
|
289
|
-
raise Error,
|
257
|
+
raise Error, 'sysctl function failed'
|
290
258
|
end
|
291
259
|
|
292
|
-
buf.
|
260
|
+
buf.unpack1('I*') / 1_000_000
|
293
261
|
else
|
294
262
|
pinfo = ProcInfo.new
|
295
263
|
|
296
264
|
# Some systems start at 0, some at 1
|
297
|
-
if processor_info(0, pinfo) < 0
|
298
|
-
|
299
|
-
raise Error, "process_info function failed"
|
300
|
-
end
|
265
|
+
if processor_info(0, pinfo) < 0 && processor_info(1, pinfo) < 0
|
266
|
+
raise Error, 'processor_info function failed'
|
301
267
|
end
|
302
268
|
|
303
269
|
pinfo[:pi_clock].to_i
|
@@ -308,15 +274,10 @@ module Sys
|
|
308
274
|
# average.
|
309
275
|
#
|
310
276
|
def self.load_avg
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
raise Error, "getloadavg function failed"
|
316
|
-
end
|
317
|
-
|
318
|
-
loadavg.get_array_of_double(0, 3)
|
319
|
-
end
|
277
|
+
return unless respond_to?(:getloadavg, true)
|
278
|
+
loadavg = FFI::MemoryPointer.new(:double, 3)
|
279
|
+
raise Error, 'getloadavg function failed' if getloadavg(loadavg, loadavg.size) < 0
|
280
|
+
loadavg.get_array_of_double(0, 3)
|
320
281
|
end
|
321
282
|
|
322
283
|
# Returns the floating point processor type.
|
@@ -328,10 +289,9 @@ module Sys
|
|
328
289
|
|
329
290
|
pinfo = ProcInfo.new
|
330
291
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
end
|
292
|
+
# Some start at 0, some start at 1
|
293
|
+
if processor_info(0, pinfo) < 0 && processor_info(1, pinfo) < 0
|
294
|
+
raise Error, 'processor_info function failed'
|
335
295
|
end
|
336
296
|
|
337
297
|
pinfo[:pi_fputypes].to_s
|
@@ -348,24 +308,24 @@ module Sys
|
|
348
308
|
pinfo = ProcInfo.new
|
349
309
|
|
350
310
|
if processor_info(num, pinfo) < 0
|
351
|
-
raise Error,
|
311
|
+
raise Error, 'processor_info function failed'
|
352
312
|
end
|
353
313
|
|
354
314
|
case pinfo[:pi_state].to_i
|
355
315
|
when P_ONLINE
|
356
|
-
|
316
|
+
'online'
|
357
317
|
when P_OFFLINE
|
358
|
-
|
318
|
+
'offline'
|
359
319
|
when P_POWEROFF
|
360
|
-
|
320
|
+
'poweroff'
|
361
321
|
when P_FAULTED
|
362
|
-
|
322
|
+
'faulted'
|
363
323
|
when P_NOINTR
|
364
|
-
|
324
|
+
'nointr'
|
365
325
|
when P_SPARE
|
366
|
-
|
326
|
+
'spare'
|
367
327
|
else
|
368
|
-
|
328
|
+
'unknown'
|
369
329
|
end
|
370
330
|
end
|
371
331
|
end
|