sys-cpu 1.1.0 → 1.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +9 -0
- data/README.md +1 -1
- data/Rakefile +4 -1
- data/lib/sys/cpu.rb +1 -1
- data/lib/sys/darwin/sys/cpu.rb +117 -2
- data/lib/sys/linux/sys/cpu.rb +70 -2
- data/lib/sys/unix/sys/cpu.rb +67 -3
- data/lib/sys/windows/sys/cpu.rb +42 -0
- data/spec/sys_cpu_bsd_spec.rb +32 -12
- data/spec/sys_cpu_hpux_spec.rb +27 -7
- data/spec/sys_cpu_linux_spec.rb +25 -6
- data/spec/sys_cpu_shared.rb +1 -1
- data/spec/sys_cpu_windows_spec.rb +28 -7
- data/sys-cpu.gemspec +8 -2
- data.tar.gz.sig +0 -0
- metadata +4 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 56f093dfd8f11c6ed9da97cc8020e687a76001dabef4596299041e6b875a2d3c
|
|
4
|
+
data.tar.gz: ac4b1d0ef5430c4d5078d9f4cbf12320f2900beab58d815202b32191209631ed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 24a439eec1f866b22d52bd75665f284e8cd27351f474708b85f14900a3a77f4b5563b2961a3a5df7853fe10542048b7ff5c70eff1def7848da7eefa2964f28a2
|
|
7
|
+
data.tar.gz: e366fd2da77cf922abd384bb16e1c6bff84d4e3c11dc69d1732065971f80a2b5484db0cef28ae0d490492d4efb6173dea77a24b746302273eea7cf52d761716d
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## 1.3.0 - 24-Mar-2026
|
|
2
|
+
* Added the cpu_usage method.
|
|
3
|
+
|
|
4
|
+
## 1.2.0 - 17-Feb-2026
|
|
5
|
+
* The win32ole gem is now a dependency since Ruby 4.x no longer bundles it.
|
|
6
|
+
* The freq method was updated for BSD platforms on aarch64. It now defaults
|
|
7
|
+
to the hardclock timer value as a best guess.
|
|
8
|
+
* The architecture method now recognizes ARM64 on Windows.
|
|
9
|
+
|
|
1
10
|
## 1.1.0 - 9-Jun-2024
|
|
2
11
|
* Removed Solaris support.
|
|
3
12
|
* Added DragonflyBSD support.
|
data/README.md
CHANGED
data/Rakefile
CHANGED
data/lib/sys/cpu.rb
CHANGED
data/lib/sys/darwin/sys/cpu.rb
CHANGED
|
@@ -43,7 +43,7 @@ module Sys
|
|
|
43
43
|
CPU_ARCH_ABI64 = 0x01000000
|
|
44
44
|
CPU_TYPE_X86 = 7
|
|
45
45
|
CPU_TYPE_X86_64 = (CPU_TYPE_X86 | CPU_ARCH_ABI64)
|
|
46
|
-
CPU_TYPE_ARM
|
|
46
|
+
CPU_TYPE_ARM = 12
|
|
47
47
|
CPU_TYPE_SPARC = 14
|
|
48
48
|
CPU_TYPE_POWERPC = 18
|
|
49
49
|
CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
|
|
@@ -74,6 +74,7 @@ module Sys
|
|
|
74
74
|
private_class_method :getloadavg
|
|
75
75
|
private_class_method :sysconf
|
|
76
76
|
|
|
77
|
+
# Private wrapper class for struct clockinfo
|
|
77
78
|
class ClockInfo < FFI::Struct
|
|
78
79
|
layout(
|
|
79
80
|
:hz, :int,
|
|
@@ -189,7 +190,7 @@ module Sys
|
|
|
189
190
|
(optr.read_long * clock[:hz]) / 1_000_000
|
|
190
191
|
else
|
|
191
192
|
if sysctlbyname('hw.cpufrequency', optr, size, nil, 0) < 0
|
|
192
|
-
raise Error, 'sysctlbyname failed on hw.cpufrequency'
|
|
193
|
+
raise Error, 'sysctlbyname failed on hw.cpufrequency'
|
|
193
194
|
end
|
|
194
195
|
optr.read_long / 1_000_000
|
|
195
196
|
end
|
|
@@ -207,5 +208,119 @@ module Sys
|
|
|
207
208
|
|
|
208
209
|
loadavg.get_array_of_double(0, 3)
|
|
209
210
|
end
|
|
211
|
+
|
|
212
|
+
# Returns CPU usage as a percentage.
|
|
213
|
+
#
|
|
214
|
+
# If +sample_time+ is positive, samples CPU times and calculates an average
|
|
215
|
+
# over that interval. You can also specify +samples+ to average multiple
|
|
216
|
+
# consecutive measurements.
|
|
217
|
+
#
|
|
218
|
+
# If +sample_time+ is 0 (default), uses a 1-second sample window by default.
|
|
219
|
+
# Default value for +samples+ is 2 (averages two measurements).
|
|
220
|
+
#
|
|
221
|
+
HOST_CPU_LOAD_INFO = 3
|
|
222
|
+
HOST_CPU_LOAD_INFO_COUNT = 4
|
|
223
|
+
|
|
224
|
+
private_constant :HOST_CPU_LOAD_INFO, :HOST_CPU_LOAD_INFO_COUNT
|
|
225
|
+
|
|
226
|
+
attach_function :mach_host_self, [], :uint
|
|
227
|
+
attach_function :host_statistics, %i[uint int pointer pointer], :int
|
|
228
|
+
|
|
229
|
+
private_class_method :mach_host_self, :host_statistics
|
|
230
|
+
|
|
231
|
+
# Returns the current CPU usage as a percentage, averaged over a sampling interval.
|
|
232
|
+
#
|
|
233
|
+
# By default, this method samples CPU usage over a 1-second interval and averages two measurements.
|
|
234
|
+
# You can customize the interval and number of samples by passing the +sample_time+ (in seconds)
|
|
235
|
+
# and +samples+ keyword arguments. For example, +cpu_usage(sample_time: 0.5, samples: 4)+ will take four
|
|
236
|
+
# samples, each 0.5 seconds apart, and return the average CPU usage over that period.
|
|
237
|
+
#
|
|
238
|
+
# Passing nil, 0, or a negative value for either argument falls back to the defaults (1.0 seconds
|
|
239
|
+
# and 2 samples) to keep behavior consistent across platforms.
|
|
240
|
+
#
|
|
241
|
+
# Returns a Float (percentage), rounded to one decimal place, or nil if CPU usage cannot be determined.
|
|
242
|
+
#
|
|
243
|
+
# Example usage:
|
|
244
|
+
# Sys::CPU.cpu_usage #=> 12.3
|
|
245
|
+
# Sys::CPU.cpu_usage(sample_time: 2, samples: 3) #=> 10.7
|
|
246
|
+
# Sys::CPU.cpu_usage(sample_time: 0, samples: 0) #=> 12.3 # zeros fall back to defaults
|
|
247
|
+
#
|
|
248
|
+
def self.cpu_usage(sample_time: 1.0, samples: 2)
|
|
249
|
+
sample_time = 1.0 if sample_time.nil? || sample_time <= 0
|
|
250
|
+
samples = 2 if samples.nil? || samples <= 0
|
|
251
|
+
|
|
252
|
+
usages = []
|
|
253
|
+
|
|
254
|
+
samples.times do
|
|
255
|
+
t1 = current_ticks
|
|
256
|
+
sleep(sample_time)
|
|
257
|
+
t2 = current_ticks
|
|
258
|
+
next unless t1 && t2
|
|
259
|
+
|
|
260
|
+
if (u = usage_between_ticks(t1, t2))
|
|
261
|
+
usages << u
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
return nil if usages.empty?
|
|
266
|
+
|
|
267
|
+
(usages.sum / usages.size.to_f).round(1)
|
|
268
|
+
rescue StandardError
|
|
269
|
+
nil
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def self.current_ticks
|
|
273
|
+
cpu_ticks_sysctl || cpu_ticks_host
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
private_class_method :current_ticks
|
|
277
|
+
|
|
278
|
+
def self.usage_between_ticks(t1, t2)
|
|
279
|
+
diff = t2.map.with_index { |v, i| v - t1[i] }
|
|
280
|
+
total = diff.sum
|
|
281
|
+
return nil if total <= 0
|
|
282
|
+
|
|
283
|
+
# host_statistics returns [user, system, idle, nice]
|
|
284
|
+
idle = diff[2] || 0
|
|
285
|
+
(1.0 - (idle.to_f / total)) * 100
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
private_class_method :usage_between_ticks
|
|
289
|
+
|
|
290
|
+
def self.cpu_ticks_sysctl
|
|
291
|
+
cp_time = proc { |ptr|
|
|
292
|
+
len = 5
|
|
293
|
+
size = FFI::MemoryPointer.new(:size_t)
|
|
294
|
+
size.write_ulong(ptr.size)
|
|
295
|
+
|
|
296
|
+
if sysctlbyname('kern.cp_time', ptr, size, nil, 0) < 0
|
|
297
|
+
raise Error, 'sysctlbyname failed'
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
ptr.read_array_of_ulong(len)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
cp_time.call(FFI::MemoryPointer.new(:ulong, 5))
|
|
304
|
+
rescue StandardError
|
|
305
|
+
nil
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
private_class_method :cpu_ticks_sysctl
|
|
309
|
+
|
|
310
|
+
def self.cpu_ticks_host
|
|
311
|
+
host = mach_host_self
|
|
312
|
+
info = FFI::MemoryPointer.new(:uint, HOST_CPU_LOAD_INFO_COUNT)
|
|
313
|
+
count = FFI::MemoryPointer.new(:uint)
|
|
314
|
+
count.write_uint(HOST_CPU_LOAD_INFO_COUNT)
|
|
315
|
+
|
|
316
|
+
kr = host_statistics(host, HOST_CPU_LOAD_INFO, info, count)
|
|
317
|
+
return nil unless kr == 0
|
|
318
|
+
|
|
319
|
+
info.read_array_of_uint(HOST_CPU_LOAD_INFO_COUNT)
|
|
320
|
+
rescue StandardError
|
|
321
|
+
nil
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
private_class_method :cpu_ticks_host
|
|
210
325
|
end
|
|
211
326
|
end
|
data/lib/sys/linux/sys/cpu.rb
CHANGED
|
@@ -10,7 +10,10 @@ module Sys
|
|
|
10
10
|
|
|
11
11
|
cpu_file = '/proc/cpuinfo'
|
|
12
12
|
cpu_hash = {}
|
|
13
|
+
|
|
14
|
+
# rubocop:disable Style/MutableConstant
|
|
13
15
|
CPU_ARRAY = []
|
|
16
|
+
# rubocop:enable Style/MutableConstant
|
|
14
17
|
|
|
15
18
|
private_constant :CPU_ARRAY
|
|
16
19
|
|
|
@@ -97,8 +100,15 @@ module Sys
|
|
|
97
100
|
|
|
98
101
|
# Returns a string indicating the CPU model.
|
|
99
102
|
#
|
|
103
|
+
# Some systems may use slightly different keys in /proc/cpuinfo, so
|
|
104
|
+
# we fall back to other common names and ensure we always return a
|
|
105
|
+
# String.
|
|
100
106
|
def self.model
|
|
101
|
-
CPU_ARRAY.first['model_name']
|
|
107
|
+
CPU_ARRAY.first['model_name'] ||
|
|
108
|
+
CPU_ARRAY.first['model'] ||
|
|
109
|
+
CPU_ARRAY.first['cpu'] ||
|
|
110
|
+
CPU_ARRAY.first['processor'] ||
|
|
111
|
+
''.dup
|
|
102
112
|
end
|
|
103
113
|
|
|
104
114
|
# Returns an integer indicating the speed of the CPU.
|
|
@@ -107,6 +117,62 @@ module Sys
|
|
|
107
117
|
CPU_ARRAY.first['cpu_mhz'].to_f.round
|
|
108
118
|
end
|
|
109
119
|
|
|
120
|
+
# Returns the current CPU usage as a percentage, averaged over a sampling interval.
|
|
121
|
+
#
|
|
122
|
+
# By default, this method samples CPU usage over a 1-second interval and averages two measurements.
|
|
123
|
+
# You can customize the interval and number of samples by passing the +sample_time+ (in seconds)
|
|
124
|
+
# and +samples+ keyword arguments. For example, +cpu_usage(sample_time: 0.5, samples: 4)+ will take four
|
|
125
|
+
# samples, each 0.5 seconds apart,
|
|
126
|
+
# and return the average CPU usage over that period.
|
|
127
|
+
#
|
|
128
|
+
# Passing nil, 0, or a negative value for either argument falls back to the defaults (1.0 seconds and
|
|
129
|
+
# 2 samples) for cross-platform consistency.
|
|
130
|
+
#
|
|
131
|
+
# Returns a Float (percentage), rounded to one decimal place, or nil if CPU usage cannot be determined.
|
|
132
|
+
#
|
|
133
|
+
# Example usage:
|
|
134
|
+
# Sys::CPU.cpu_usage #=> 12.3
|
|
135
|
+
# Sys::CPU.cpu_usage(sample_time: 2, samples: 3) #=> 10.7
|
|
136
|
+
# Sys::CPU.cpu_usage(sample_time: 0, samples: 0) #=> 12.3 # zeros fall back to defaults
|
|
137
|
+
#
|
|
138
|
+
def self.cpu_usage(sample_time: 1.0, samples: 2)
|
|
139
|
+
sample_time = 1.0 if sample_time.nil? || sample_time <= 0
|
|
140
|
+
samples = 2 if samples.nil? || samples <= 0
|
|
141
|
+
|
|
142
|
+
usages = []
|
|
143
|
+
|
|
144
|
+
samples.times do
|
|
145
|
+
stats1 = cpu_stats
|
|
146
|
+
sleep(sample_time)
|
|
147
|
+
stats2 = cpu_stats
|
|
148
|
+
|
|
149
|
+
total_diff = 0.0
|
|
150
|
+
idle_diff = 0.0
|
|
151
|
+
|
|
152
|
+
keys = stats1.key?('cpu') ? ['cpu'] : stats1.keys
|
|
153
|
+
keys.each do |key|
|
|
154
|
+
arr1 = stats1[key]
|
|
155
|
+
arr2 = stats2[key]
|
|
156
|
+
next unless arr1 && arr2
|
|
157
|
+
t1 = arr1.sum
|
|
158
|
+
t2 = arr2.sum
|
|
159
|
+
total = t2 - t1
|
|
160
|
+
idle = (arr2[3] || 0) - (arr1[3] || 0)
|
|
161
|
+
total_diff += total
|
|
162
|
+
idle_diff += idle
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
if total_diff > 0
|
|
166
|
+
usages << ((1.0 - (idle_diff / total_diff)) * 100)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
return nil if usages.empty?
|
|
171
|
+
(usages.sum / usages.size.to_f).round(1)
|
|
172
|
+
rescue StandardError
|
|
173
|
+
nil
|
|
174
|
+
end
|
|
175
|
+
|
|
110
176
|
# Create singleton methods for each of the attributes.
|
|
111
177
|
#
|
|
112
178
|
def self.method_missing(id, arg = 0)
|
|
@@ -165,7 +231,9 @@ module Sys
|
|
|
165
231
|
next
|
|
166
232
|
end
|
|
167
233
|
|
|
168
|
-
|
|
234
|
+
# Keep raw jiffies counts (do not scale by hz) so deltas over short
|
|
235
|
+
# intervals still produce meaningful values.
|
|
236
|
+
vals = array[1..-1].map{ |e| e.to_i }
|
|
169
237
|
hash[array[0]] = vals
|
|
170
238
|
end
|
|
171
239
|
|
data/lib/sys/unix/sys/cpu.rb
CHANGED
|
@@ -19,10 +19,11 @@ module Sys
|
|
|
19
19
|
HW_MODEL = 2 # Specific machine model
|
|
20
20
|
HW_NCPU = 3 # Number of CPU's
|
|
21
21
|
HW_CPU_FREQ = 15 # CPU frequency
|
|
22
|
+
HOST_OS = RbConfig::CONFIG['host_os']
|
|
22
23
|
|
|
23
24
|
private_constant :CTL_HW, :HW_MACHINE, :HW_MODEL, :HW_NCPU, :HW_CPU_FREQ
|
|
24
25
|
|
|
25
|
-
if
|
|
26
|
+
if HOST_OS =~ /bsd|dragonfly/
|
|
26
27
|
HW_MACHINE_ARCH = 11 # Machine architecture
|
|
27
28
|
else
|
|
28
29
|
HW_MACHINE_ARCH = 12 # Machine architecture
|
|
@@ -92,6 +93,7 @@ module Sys
|
|
|
92
93
|
# Do nothing, not supported on this platform.
|
|
93
94
|
end
|
|
94
95
|
|
|
96
|
+
# Private wrapper class for the procinfo struct
|
|
95
97
|
class ProcInfo < FFI::Struct
|
|
96
98
|
layout(
|
|
97
99
|
:pi_state, :int,
|
|
@@ -101,6 +103,8 @@ module Sys
|
|
|
101
103
|
)
|
|
102
104
|
end
|
|
103
105
|
|
|
106
|
+
private_constant :ProcInfo
|
|
107
|
+
|
|
104
108
|
# Returns the cpu's architecture. On most systems this will be identical
|
|
105
109
|
# to the CPU.machine method. On OpenBSD it will be identical to the CPU.model
|
|
106
110
|
# method.
|
|
@@ -238,6 +242,16 @@ module Sys
|
|
|
238
242
|
|
|
239
243
|
# Returns an integer indicating the speed of the CPU.
|
|
240
244
|
#
|
|
245
|
+
# Note that for BSD systems running on an aarch64 cpu this method
|
|
246
|
+
# will default to a hardclock timer value rather than the actual
|
|
247
|
+
# CPU frequency. This will typically be 1000 (or 100 on VM's).
|
|
248
|
+
#--
|
|
249
|
+
# If there's a better way please let me know. In my experiments locally
|
|
250
|
+
# stuff like dev.cpu.0 did NOT have the information that you might
|
|
251
|
+
# expect to find there, so we cannot rely on that either. In my defense,
|
|
252
|
+
# stuff like lscpu or dmesg did not have the freq information either,
|
|
253
|
+
# not on my aarch64 VM anyway.
|
|
254
|
+
#
|
|
241
255
|
def self.freq
|
|
242
256
|
if respond_to?(:sysctlbyname, true)
|
|
243
257
|
optr = FFI::MemoryPointer.new(:long)
|
|
@@ -245,8 +259,12 @@ module Sys
|
|
|
245
259
|
|
|
246
260
|
size.write_long(optr.size)
|
|
247
261
|
|
|
248
|
-
if
|
|
249
|
-
|
|
262
|
+
if HOST_OS =~ /bsd|dragonfly/i
|
|
263
|
+
if architecture =~ /aarch/i
|
|
264
|
+
name = 'kern.hz'
|
|
265
|
+
else
|
|
266
|
+
name = 'hw.clockrate'
|
|
267
|
+
end
|
|
250
268
|
else
|
|
251
269
|
name = 'hw.cpufrequency'
|
|
252
270
|
end
|
|
@@ -291,6 +309,52 @@ module Sys
|
|
|
291
309
|
loadavg.get_array_of_double(0, 3)
|
|
292
310
|
end
|
|
293
311
|
|
|
312
|
+
# Returns CPU usage as a percentage, averaged over a sampling interval.
|
|
313
|
+
#
|
|
314
|
+
# By default, samples CPU times twice, 1 second apart. Arguments are keyword-based
|
|
315
|
+
# (+sample_time:+, +samples:+). Passing nil, 0, or a negative value for either
|
|
316
|
+
# falls back to these defaults for cross-platform consistency.
|
|
317
|
+
#
|
|
318
|
+
def self.cpu_usage(sample_time: 1.0, samples: 2)
|
|
319
|
+
cp_time = proc { |ptr|
|
|
320
|
+
len = 5
|
|
321
|
+
size = FFI::MemoryPointer.new(:size_t)
|
|
322
|
+
size.write_ulong(ptr.size)
|
|
323
|
+
|
|
324
|
+
if sysctlbyname('kern.cp_time', ptr, size, nil, 0) < 0
|
|
325
|
+
raise Error, 'sysctlbyname failed'
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
ptr.read_array_of_ulong(len)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
sample_time = 1.0 if sample_time.nil? || sample_time <= 0
|
|
332
|
+
samples = 2 if samples.nil? || samples <= 0
|
|
333
|
+
|
|
334
|
+
usages = []
|
|
335
|
+
|
|
336
|
+
samples.times do
|
|
337
|
+
t1 = cp_time.call(FFI::MemoryPointer.new(:ulong, 5))
|
|
338
|
+
sleep(sample_time)
|
|
339
|
+
t2 = cp_time.call(FFI::MemoryPointer.new(:ulong, 5))
|
|
340
|
+
|
|
341
|
+
total1 = t1.sum
|
|
342
|
+
total2 = t2.sum
|
|
343
|
+
idle1 = t1[4] || 0
|
|
344
|
+
idle2 = t2[4] || 0
|
|
345
|
+
|
|
346
|
+
total_diff = total2 - total1
|
|
347
|
+
idle_diff = idle2 - idle1
|
|
348
|
+
|
|
349
|
+
usages << ((1.0 - (idle_diff.to_f / total_diff)) * 100) if total_diff > 0
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
return nil if usages.empty?
|
|
353
|
+
(usages.sum / usages.size.to_f).round(1)
|
|
354
|
+
rescue StandardError
|
|
355
|
+
nil
|
|
356
|
+
end
|
|
357
|
+
|
|
294
358
|
# Returns the floating point processor type.
|
|
295
359
|
#
|
|
296
360
|
# Not supported on all platforms.
|
data/lib/sys/windows/sys/cpu.rb
CHANGED
|
@@ -117,6 +117,46 @@ module Sys
|
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
+
# Returns CPU usage as a percentage, averaged over multiple samples.
|
|
121
|
+
#
|
|
122
|
+
# The +sample_time+ keyword specifies the interval (in seconds) between samples.
|
|
123
|
+
# The +samples+ keyword specifies how many samples to take and average.
|
|
124
|
+
# The +cpu_num+ keyword selects which CPU to query (0 for total).
|
|
125
|
+
# The +host+ keyword specifies the target machine (defaults to local).
|
|
126
|
+
#
|
|
127
|
+
#--
|
|
128
|
+
# This method uses the _Total Win32_PerfFormattedData_PerfOS_Processor instance
|
|
129
|
+
# (unless a specific +cpu_num+ is requested) to better match Task Manager's total view.
|
|
130
|
+
#
|
|
131
|
+
# Note: Task Manager reports total CPU usage across all cores. Win32_Processor.LoadPercentage
|
|
132
|
+
# is per-processor (usually per physical socket), so it can differ from Task Manager if it falls back.
|
|
133
|
+
#
|
|
134
|
+
def self.cpu_usage(sample_time: 1.0, samples: 2, cpu_num: 0, host: Socket.gethostname)
|
|
135
|
+
sample_time = 1.0 if sample_time.nil? || sample_time <= 0
|
|
136
|
+
samples = 2 if samples.nil? || samples <= 0
|
|
137
|
+
cpu_num = cpu_num.to_i if cpu_num.respond_to?(:to_i)
|
|
138
|
+
instance = cpu_num == 0 ? '_Total' : cpu_num.to_s
|
|
139
|
+
cs = BASE_CS + "//#{host}/root/cimv2:Win32_PerfFormattedData_PerfOS_Processor='#{instance}'"
|
|
140
|
+
|
|
141
|
+
usages = []
|
|
142
|
+
|
|
143
|
+
samples.times do
|
|
144
|
+
begin
|
|
145
|
+
wmi = WIN32OLE.connect(cs)
|
|
146
|
+
rescue WIN32OLERuntimeError
|
|
147
|
+
usages << load_avg(cpu_num, host)
|
|
148
|
+
else
|
|
149
|
+
result = wmi.PercentProcessorTime
|
|
150
|
+
usages << result.to_i if result
|
|
151
|
+
end
|
|
152
|
+
sleep(sample_time)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
usages.compact!
|
|
156
|
+
return nil if usages.empty?
|
|
157
|
+
(usages.sum / usages.size.to_f).round(1)
|
|
158
|
+
end
|
|
159
|
+
|
|
120
160
|
# Returns a string indicating the cpu model, e.g. Intel Pentium 4.
|
|
121
161
|
#
|
|
122
162
|
def self.model(host = Socket.gethostname)
|
|
@@ -390,6 +430,8 @@ module Sys
|
|
|
390
430
|
'IA64'
|
|
391
431
|
when 9
|
|
392
432
|
'x64'
|
|
433
|
+
when 12
|
|
434
|
+
'ARM64'
|
|
393
435
|
end
|
|
394
436
|
end
|
|
395
437
|
|
data/spec/sys_cpu_bsd_spec.rb
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
require 'sys/cpu'
|
|
9
9
|
require 'spec_helper'
|
|
10
10
|
|
|
11
|
-
RSpec.describe Sys::CPU, :bsd
|
|
11
|
+
RSpec.describe Sys::CPU, :bsd do
|
|
12
12
|
example 'architecture method basic functionality' do
|
|
13
13
|
expect(described_class).to respond_to(:architecture)
|
|
14
14
|
expect{ described_class.architecture }.not_to raise_error
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
example 'architecture method returns a sane value' do
|
|
18
|
-
expect(described_class.architecture).to
|
|
18
|
+
expect(described_class.architecture).to be_a(String)
|
|
19
19
|
expect(described_class.architecture.size).to be > 0
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -29,7 +29,7 @@ RSpec.describe Sys::CPU, :bsd => true do
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
example 'freq method returns expected value' do
|
|
32
|
-
expect(described_class.freq).to
|
|
32
|
+
expect(described_class.freq).to be_a(Integer)
|
|
33
33
|
expect(described_class.freq).to be > 0
|
|
34
34
|
end
|
|
35
35
|
|
|
@@ -43,22 +43,42 @@ RSpec.describe Sys::CPU, :bsd => true do
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
example 'load_avg returns the expected results' do
|
|
46
|
-
expect(described_class.load_avg).to
|
|
46
|
+
expect(described_class.load_avg).to be_a(Array)
|
|
47
47
|
expect(described_class.load_avg.length).to eq(3)
|
|
48
|
-
expect(described_class.load_avg[0]).to
|
|
48
|
+
expect(described_class.load_avg[0]).to be_a(Float)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
example 'load_avg does not accept any arguments' do
|
|
52
52
|
expect{ described_class.load_avg(0) }.to raise_error(ArgumentError)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
example 'cpu_usage works as expected' do
|
|
56
|
+
expect(described_class).to respond_to(:cpu_usage)
|
|
57
|
+
expect{ described_class.cpu_usage }.not_to raise_error
|
|
58
|
+
expect{ described_class.cpu_usage(sample_time: 0.1) }.not_to raise_error
|
|
59
|
+
expect(described_class.cpu_usage).to be_a(Numeric).or be_nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
example 'cpu_usage falls back on non-positive values' do
|
|
63
|
+
expect{ described_class.cpu_usage(sample_time: 0, samples: 0) }.not_to raise_error
|
|
64
|
+
expect{ described_class.cpu_usage(sample_time: -0.5, samples: -1) }.not_to raise_error
|
|
65
|
+
expect(described_class.cpu_usage(sample_time: 0, samples: 0)).to be_a(Numeric).or be_nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
example 'cpu_usage sampling produces a valid range' do
|
|
69
|
+
result = described_class.cpu_usage(sample_time: 0.1)
|
|
70
|
+
expect(result).to be_a(Numeric).or be_nil
|
|
71
|
+
expect(result).to be >= 0 if result
|
|
72
|
+
expect(result).to be <= 100 if result
|
|
73
|
+
end
|
|
74
|
+
|
|
55
75
|
example 'machine method basic functionality' do
|
|
56
76
|
expect(described_class).to respond_to(:machine)
|
|
57
77
|
expect{ described_class.machine }.not_to raise_error
|
|
58
78
|
end
|
|
59
79
|
|
|
60
80
|
example 'machine method returns sane value' do
|
|
61
|
-
expect(described_class.machine).to
|
|
81
|
+
expect(described_class.machine).to be_a(String)
|
|
62
82
|
expect(described_class.machine.size).to be > 0
|
|
63
83
|
end
|
|
64
84
|
|
|
@@ -72,7 +92,7 @@ RSpec.describe Sys::CPU, :bsd => true do
|
|
|
72
92
|
end
|
|
73
93
|
|
|
74
94
|
example 'model method returns sane value' do
|
|
75
|
-
expect(described_class.model).to
|
|
95
|
+
expect(described_class.model).to be_a(String)
|
|
76
96
|
expect(described_class.model.length).to be > 0
|
|
77
97
|
end
|
|
78
98
|
|
|
@@ -86,7 +106,7 @@ RSpec.describe Sys::CPU, :bsd => true do
|
|
|
86
106
|
end
|
|
87
107
|
|
|
88
108
|
example 'num_cpu method returns expected value' do
|
|
89
|
-
expect(described_class.num_cpu).to
|
|
109
|
+
expect(described_class.num_cpu).to be_a(Integer)
|
|
90
110
|
expect(described_class.num_cpu).to be > 0
|
|
91
111
|
end
|
|
92
112
|
|
|
@@ -94,8 +114,8 @@ RSpec.describe Sys::CPU, :bsd => true do
|
|
|
94
114
|
expect{ described_class.num_cpu(0) }.to raise_error(ArgumentError)
|
|
95
115
|
end
|
|
96
116
|
|
|
97
|
-
context
|
|
98
|
-
example
|
|
117
|
+
context 'ffi methods and constants are private' do
|
|
118
|
+
example 'ffi constants are private' do
|
|
99
119
|
constants = described_class.constants
|
|
100
120
|
expect(constants).not_to include(:CTL_HW)
|
|
101
121
|
expect(constants).not_to include(:CPU_TYPE_X86)
|
|
@@ -104,13 +124,13 @@ RSpec.describe Sys::CPU, :bsd => true do
|
|
|
104
124
|
expect(constants).not_to include(:ClockInfo)
|
|
105
125
|
end
|
|
106
126
|
|
|
107
|
-
example
|
|
127
|
+
example 'ffi core methods are private' do
|
|
108
128
|
methods = described_class.methods(false)
|
|
109
129
|
expect(methods).not_to include(:attach_function)
|
|
110
130
|
expect(methods).not_to include(:bitmask)
|
|
111
131
|
end
|
|
112
132
|
|
|
113
|
-
example
|
|
133
|
+
example 'ffi attached methods are private' do
|
|
114
134
|
methods = described_class.methods(false)
|
|
115
135
|
expect(methods).not_to include(:sysctl)
|
|
116
136
|
expect(methods).not_to include(:sysctlbyname)
|
data/spec/sys_cpu_hpux_spec.rb
CHANGED
|
@@ -9,30 +9,30 @@
|
|
|
9
9
|
require 'sys/cpu'
|
|
10
10
|
require 'spec_helper'
|
|
11
11
|
|
|
12
|
-
RSpec.describe Sys::CPU, :hpux
|
|
12
|
+
RSpec.describe Sys::CPU, :hpux do
|
|
13
13
|
example 'cpu_freq' do
|
|
14
14
|
expect(described_class).to respond_to(:freq)
|
|
15
15
|
expect{ described_class.freq }.not_to raise_error
|
|
16
16
|
expect{ described_class.freq(0) }.not_to raise_error
|
|
17
|
-
expect(described_class.freq).to
|
|
17
|
+
expect(described_class.freq).to be_a(Integer)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
example 'num_cpu' do
|
|
21
21
|
expect(described_class).to respond_to(:num_cpu)
|
|
22
22
|
expect{ described_class.num_cpu }.not_to raise_error
|
|
23
|
-
expect(described_class.num_cpu).to
|
|
23
|
+
expect(described_class.num_cpu).to be_a(Integer)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
example 'num_active_cpu' do
|
|
27
27
|
expect(described_class).to respond_to(:num_active_cpu)
|
|
28
28
|
expect{ described_class.num_active_cpu }.not_to raise_error
|
|
29
|
-
expect(described_class.num_active_cpu).to
|
|
29
|
+
expect(described_class.num_active_cpu).to be_a(Integer)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
example 'cpu_architecture' do
|
|
33
33
|
expect(described_class).to respond_to(:architecture)
|
|
34
34
|
expect{ described_class.architecture }.not_to raise_error
|
|
35
|
-
expect(described_class.architecture).to
|
|
35
|
+
expect(described_class.architecture).to be_a(String)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
example 'load_avg basic sanity check' do
|
|
@@ -47,9 +47,29 @@ RSpec.describe Sys::CPU, :hpux => true do
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
example 'load_avg expected results' do
|
|
50
|
-
expect(described_class.load_avg).to
|
|
51
|
-
expect(described_class.load_avg(0)).to
|
|
50
|
+
expect(described_class.load_avg).to be_a(Array)
|
|
51
|
+
expect(described_class.load_avg(0)).to be_a(Array)
|
|
52
52
|
expect(described_class.load_avg.length).to eq(3)
|
|
53
53
|
expect(described_class.load_avg(0).length).to eq(3)
|
|
54
54
|
end
|
|
55
|
+
|
|
56
|
+
example 'cpu_usage works as expected' do
|
|
57
|
+
expect(described_class).to respond_to(:cpu_usage)
|
|
58
|
+
expect{ described_class.cpu_usage }.not_to raise_error
|
|
59
|
+
expect{ described_class.cpu_usage(sample_time: 0.1) }.not_to raise_error
|
|
60
|
+
expect(described_class.cpu_usage).to be_a(Numeric).or be_nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
example 'cpu_usage falls back on non-positive values' do
|
|
64
|
+
expect{ described_class.cpu_usage(sample_time: 0, samples: 0) }.not_to raise_error
|
|
65
|
+
expect{ described_class.cpu_usage(sample_time: -1, samples: -1) }.not_to raise_error
|
|
66
|
+
expect(described_class.cpu_usage(sample_time: 0, samples: 0)).to be_a(Numeric).or be_nil
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
example 'cpu_usage sampling produces a valid range' do
|
|
70
|
+
result = described_class.cpu_usage(sample_time: 0.1)
|
|
71
|
+
expect(result).to be_a(Numeric).or be_nil
|
|
72
|
+
expect(result).to be >= 0 if result
|
|
73
|
+
expect(result).to be <= 100 if result
|
|
74
|
+
end
|
|
55
75
|
end
|
data/spec/sys_cpu_linux_spec.rb
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
require 'sys/cpu'
|
|
10
10
|
require 'spec_helper'
|
|
11
11
|
|
|
12
|
-
RSpec.describe Sys::CPU, :linux
|
|
12
|
+
RSpec.describe Sys::CPU, :linux do
|
|
13
13
|
example 'dynamic methods are defined as expected' do
|
|
14
14
|
expect do
|
|
15
15
|
described_class.processors do |cs|
|
|
@@ -25,28 +25,47 @@ RSpec.describe Sys::CPU, :linux => true do
|
|
|
25
25
|
|
|
26
26
|
example 'cpu_stats works as expected' do
|
|
27
27
|
expect{ described_class.cpu_stats }.not_to raise_error
|
|
28
|
-
expect(described_class.cpu_stats).to
|
|
28
|
+
expect(described_class.cpu_stats).to be_a(Hash)
|
|
29
29
|
expect(described_class.cpu_stats['cpu0'].length).to be >= 4
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
example 'architecture works as expected' do
|
|
33
33
|
expect{ described_class.architecture }.not_to raise_error
|
|
34
|
-
expect(described_class.architecture).to
|
|
34
|
+
expect(described_class.architecture).to be_a(String)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
example 'model works as expected' do
|
|
38
38
|
expect{ described_class.model }.not_to raise_error
|
|
39
|
-
expect(described_class.model).to
|
|
39
|
+
expect(described_class.model).to be_a(String)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
example 'freq works as expected' do
|
|
43
43
|
expect{ described_class.freq }.not_to raise_error
|
|
44
|
-
expect(described_class.freq).to
|
|
44
|
+
expect(described_class.freq).to be_a(Numeric)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
example 'num_cpu works as expected' do
|
|
48
48
|
expect{ described_class.num_cpu }.not_to raise_error
|
|
49
|
-
expect(described_class.num_cpu).to
|
|
49
|
+
expect(described_class.num_cpu).to be_a(Numeric)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
example 'cpu_usage works as expected' do
|
|
53
|
+
expect{ described_class.cpu_usage }.not_to raise_error
|
|
54
|
+
expect(described_class.cpu_usage).to be_a(Numeric)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
example 'cpu_usage falls back on non-positive values' do
|
|
58
|
+
expect{ described_class.cpu_usage(sample_time: 0, samples: 0) }.not_to raise_error
|
|
59
|
+
expect{ described_class.cpu_usage(sample_time: -1, samples: -2) }.not_to raise_error
|
|
60
|
+
expect(described_class.cpu_usage(sample_time: 0, samples: 0)).to be_a(Numeric)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
example 'cpu_usage sampling produces a valid range' do
|
|
64
|
+
# Sampled usage should be a number between 0 and 100.
|
|
65
|
+
result = described_class.cpu_usage(sample_time: 0.1)
|
|
66
|
+
expect(result).to be_a(Numeric)
|
|
67
|
+
expect(result).to be >= 0
|
|
68
|
+
expect(result).to be <= 100
|
|
50
69
|
end
|
|
51
70
|
|
|
52
71
|
example 'bogus methods are not picked up by method_missing' do
|
data/spec/sys_cpu_shared.rb
CHANGED
|
@@ -10,20 +10,20 @@ require 'spec_helper'
|
|
|
10
10
|
require 'sys/cpu'
|
|
11
11
|
require 'socket'
|
|
12
12
|
|
|
13
|
-
RSpec.describe Sys::CPU, :windows
|
|
13
|
+
RSpec.describe Sys::CPU, :windows do
|
|
14
14
|
let(:host) { Socket.gethostname }
|
|
15
15
|
|
|
16
16
|
example 'architecture' do
|
|
17
17
|
expect(described_class).to respond_to(:architecture)
|
|
18
18
|
expect{ described_class.architecture }.not_to raise_error
|
|
19
19
|
expect{ described_class.architecture(host) }.not_to raise_error
|
|
20
|
-
expect(described_class.architecture).to
|
|
20
|
+
expect(described_class.architecture).to be_a(String)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
example 'freq basic functionality' do
|
|
24
24
|
expect(described_class).to respond_to(:freq)
|
|
25
25
|
expect{ described_class.freq }.not_to raise_error
|
|
26
|
-
expect(described_class.freq).to
|
|
26
|
+
expect(described_class.freq).to be_a(Integer)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
example 'freq with arguments' do
|
|
@@ -35,28 +35,49 @@ RSpec.describe Sys::CPU, :windows => true do
|
|
|
35
35
|
expect(described_class).to respond_to(:model)
|
|
36
36
|
expect{ described_class.model }.not_to raise_error
|
|
37
37
|
expect{ described_class.model(host) }.not_to raise_error
|
|
38
|
-
expect(described_class.model).to
|
|
38
|
+
expect(described_class.model).to be_a(String)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
example 'num_cpu' do
|
|
42
42
|
expect(described_class).to respond_to(:num_cpu)
|
|
43
43
|
expect{ described_class.num_cpu }.not_to raise_error
|
|
44
44
|
expect{ described_class.num_cpu(host) }.not_to raise_error
|
|
45
|
-
expect(described_class.num_cpu).to
|
|
45
|
+
expect(described_class.num_cpu).to be_a(Integer)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
example 'cpu_type' do
|
|
49
49
|
expect(described_class).to respond_to(:cpu_type)
|
|
50
50
|
expect{ described_class.cpu_type }.not_to raise_error
|
|
51
51
|
expect{ described_class.cpu_type(host) }.not_to raise_error
|
|
52
|
-
expect(described_class.cpu_type).to
|
|
52
|
+
expect(described_class.cpu_type).to be_a(String)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
example 'load_avg' do
|
|
56
56
|
expect(described_class).to respond_to(:load_avg)
|
|
57
57
|
expect{ described_class.load_avg }.not_to raise_error
|
|
58
58
|
expect{ described_class.load_avg(0, host) }.not_to raise_error
|
|
59
|
-
expect(described_class.load_avg).to
|
|
59
|
+
expect(described_class.load_avg).to be_a(Integer).or be_a(NilClass)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
example 'cpu_usage works as expected' do
|
|
63
|
+
expect(described_class).to respond_to(:cpu_usage)
|
|
64
|
+
expect{ described_class.cpu_usage }.not_to raise_error
|
|
65
|
+
expect{ described_class.cpu_usage(sample_time: 0.1, samples: 0, host: host) }.not_to raise_error
|
|
66
|
+
expect(described_class.cpu_usage).to be_a(Numeric).or be_a(NilClass)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
example 'cpu_usage falls back on non-positive values' do
|
|
70
|
+
expect{ described_class.cpu_usage(sample_time: 0, samples: 0, host: host) }.not_to raise_error
|
|
71
|
+
expect{ described_class.cpu_usage(sample_time: -1, samples: -1, host: host) }.not_to raise_error
|
|
72
|
+
expect(described_class.cpu_usage(sample_time: 0, samples: 0, host: host)).to be_a(Numeric).or be_a(NilClass)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
example 'cpu_usage sampling produces a valid range' do
|
|
76
|
+
# Sampled usage should be a number between 0 and 100.
|
|
77
|
+
result = described_class.cpu_usage(sample_time: 0.1)
|
|
78
|
+
expect(result).to be_a(Numeric).or be_nil
|
|
79
|
+
expect(result).to be >= 0 if result
|
|
80
|
+
expect(result).to be <= 100 if result
|
|
60
81
|
end
|
|
61
82
|
|
|
62
83
|
example 'processors' do
|
data/sys-cpu.gemspec
CHANGED
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = 'sys-cpu'
|
|
5
|
-
spec.version = '1.
|
|
5
|
+
spec.version = '1.3.0'
|
|
6
6
|
spec.author = 'Daniel J. Berger'
|
|
7
7
|
spec.email = 'djberg96@gmail.com'
|
|
8
8
|
spec.license = 'Apache-2.0'
|
|
@@ -17,6 +17,11 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
# and Linux was worth the tradeoff of not having to create 3 separate gems.
|
|
18
18
|
spec.add_dependency('ffi', '~> 1.1')
|
|
19
19
|
|
|
20
|
+
if Gem.win_platform?
|
|
21
|
+
spec.platform = Gem::Platform.new(['universal', 'mingw32'])
|
|
22
|
+
spec.add_dependency('win32ole')
|
|
23
|
+
end
|
|
24
|
+
|
|
20
25
|
spec.add_development_dependency('rake')
|
|
21
26
|
spec.add_development_dependency('rubocop')
|
|
22
27
|
spec.add_development_dependency('rspec', '~> 3.9')
|
|
@@ -30,7 +35,8 @@ Gem::Specification.new do |spec|
|
|
|
30
35
|
'source_code_uri' => 'https://github.com/djberg96/sys-cpu',
|
|
31
36
|
'wiki_uri' => 'https://github.com/djberg96/sys-cpu/wiki',
|
|
32
37
|
'rubygems_mfa_required' => 'true',
|
|
33
|
-
'github_repo' => 'https://github.com/djberg96/sys-cpu'
|
|
38
|
+
'github_repo' => 'https://github.com/djberg96/sys-cpu',
|
|
39
|
+
'funding_uri' => 'https://github.com/sponsors/djberg96'
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
spec.description = <<-EOF
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sys-cpu
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel J. Berger
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain:
|
|
11
10
|
- |
|
|
@@ -35,7 +34,7 @@ cert_chain:
|
|
|
35
34
|
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
|
36
35
|
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
|
37
36
|
-----END CERTIFICATE-----
|
|
38
|
-
date:
|
|
37
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
39
38
|
dependencies:
|
|
40
39
|
- !ruby/object:Gem::Dependency
|
|
41
40
|
name: ffi
|
|
@@ -157,7 +156,7 @@ metadata:
|
|
|
157
156
|
wiki_uri: https://github.com/djberg96/sys-cpu/wiki
|
|
158
157
|
rubygems_mfa_required: 'true'
|
|
159
158
|
github_repo: https://github.com/djberg96/sys-cpu
|
|
160
|
-
|
|
159
|
+
funding_uri: https://github.com/sponsors/djberg96
|
|
161
160
|
rdoc_options: []
|
|
162
161
|
require_paths:
|
|
163
162
|
- lib
|
|
@@ -172,8 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
172
171
|
- !ruby/object:Gem::Version
|
|
173
172
|
version: '0'
|
|
174
173
|
requirements: []
|
|
175
|
-
rubygems_version:
|
|
176
|
-
signing_key:
|
|
174
|
+
rubygems_version: 4.0.3
|
|
177
175
|
specification_version: 4
|
|
178
176
|
summary: A Ruby interface for providing CPU information
|
|
179
177
|
test_files:
|
metadata.gz.sig
CHANGED
|
Binary file
|