sys-cpu 1.0.1 → 1.0.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.
- 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
|