sys-cpu 1.0.2 → 1.0.5
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 +23 -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 +196 -0
- data/lib/sys/linux/sys/cpu.rb +33 -31
- data/lib/sys/unix/sys/cpu.rb +40 -80
- data/lib/sys/windows/sys/cpu.rb +244 -143
- 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 +10 -9
- data.tar.gz.sig +0 -0
- metadata +38 -8
- metadata.gz.sig +0 -0
- data/doc/bsd.txt +0 -49
- data/doc/linux.txt +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7093a05a67945ccf9980c070421462c4a30a40d72ba9645230fad1d86381c0c1
|
4
|
+
data.tar.gz: e411d1a7f0ce381fcd8660e9b7654d60c21c03459b25cb6cdd1b46c379196b10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff952395b1f70fedc9f01818efff2c4655ed19f2120351a84eec82690176a6de5664ca1b17648656b8eeaacaccc805c5077f4c50d79ad2983f1b3df92f14e6a8
|
7
|
+
data.tar.gz: 07344e7816c0ccb3bc2217c4563d2c3c97875bd3e45cc8b463cd516b44f2cc38ba94df7798ae9e086886bd0bbcdae5da514244a19165f0d732c2ddb5179d85ca
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
## 1.0.5 - 10-Aug-2022
|
2
|
+
* Updated the cpu detection handling for Mac M1 systems. Thanks go to
|
3
|
+
Julien W for the spot.
|
4
|
+
|
5
|
+
## 1.0.4 - 10-Jun-2022
|
6
|
+
* The OSX code for the CPU.freq method was updated for arm64 systems.
|
7
|
+
* Some refactoring to the specs and uses shared examples now.
|
8
|
+
* Now makes the new method a private class method. The constructor was never
|
9
|
+
meant to be used with this library, so now it's explicitly forbidden.
|
10
|
+
* Added rubocop and rubocop-rspec as development dependencies, as well as
|
11
|
+
a rubocop rake task, and applied some suggested changes.
|
12
|
+
* Fixed the global Gemfile source issue. Just use the gemspec.
|
13
|
+
* Added some new cpu families for Windows.
|
14
|
+
* Added a respond_to_missing? method to the Linux version since it uses
|
15
|
+
method_missing.
|
16
|
+
* The MS Windows version now assumes Ruby 2.0 or later.
|
17
|
+
|
18
|
+
## 1.0.3 - 28-Jan-2021
|
19
|
+
* The code for OSX was split out into its own source file. This was partly for
|
20
|
+
ease of maintenance, but also because there was confusion with the
|
21
|
+
processor_info function. The original function was only aimed at Solaris, but
|
22
|
+
it turns out OSX has its own, different implementation. This caused segfaults.
|
23
|
+
|
1
24
|
## 1.0.2 - 25-Jan-2021
|
2
25
|
* Fixed issues where things that were meant to be private weren't actually private.
|
3
26
|
|
data/Gemfile
CHANGED
data/MANIFEST.md
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
[](https://github.com/djberg96/sys-cpu/actions/workflows/ruby.yml)
|
2
|
+
|
3
|
+
* Linux
|
4
|
+
* Windows
|
5
|
+
* OSX
|
6
|
+
|
1
7
|
## Description
|
2
8
|
A Ruby interface for getting cpu information.
|
3
9
|
|
@@ -5,15 +11,16 @@ A Ruby interface for getting cpu information.
|
|
5
11
|
`gem install sys-cpu`
|
6
12
|
|
7
13
|
## Adding the trusted cert
|
8
|
-
`gem cert --add <(curl -Ls https://raw.githubusercontent.com/djberg96/sys-cpu/
|
14
|
+
`gem cert --add <(curl -Ls https://raw.githubusercontent.com/djberg96/sys-cpu/main/certs/djberg96_pub.pem)`
|
9
15
|
|
10
16
|
## Notes
|
11
17
|
### Solaris
|
12
|
-
|
13
|
-
|
18
|
+
There is no `processors` iterative method for multi-cpu systems. I was going to
|
19
|
+
add this originally, but since Solaris is basically dead at this point I've
|
20
|
+
dropped the idea.
|
14
21
|
|
15
22
|
### OS X
|
16
|
-
The CPU.model method returns very limited information. I do not yet know
|
23
|
+
The `CPU.model` method returns very limited information. I do not yet know
|
17
24
|
how to get more detailed information.
|
18
25
|
|
19
26
|
### Linux
|
@@ -21,14 +28,14 @@ This is pure Ruby. This version reads information out of /proc/cpuinfo and
|
|
21
28
|
/proc/loadavg, so if /proc isn't mounted it won't work.
|
22
29
|
|
23
30
|
The key-value information in /proc/cpuinfo is stored internally (i.e. in
|
24
|
-
memory) as an array of hashes when you first
|
31
|
+
memory) as an array of hashes when you first `require` this package. This
|
25
32
|
overhead is exceptionally minimal, given that your average cpuinfo file
|
26
33
|
contains less than 1k of text (and I don't store whitespace or newlines).
|
27
34
|
|
28
35
|
The text documentation for Linux is dynamically generated during the
|
29
36
|
build process because the fields vary depending on your setup. So, don't
|
30
|
-
look at it until *after* you've installed it.
|
31
|
-
file after you run
|
37
|
+
look at it until *after* you've installed it. You will see a doc/linux.txt
|
38
|
+
file after you run `rake install` (via install.rb).
|
32
39
|
|
33
40
|
### HP-UX
|
34
41
|
Unlike other platforms, you can get load averages for an individual cpu in
|
@@ -42,10 +49,10 @@ will work just fine.
|
|
42
49
|
This is a pure Ruby implementation using the win32ole package + WMI. The C
|
43
50
|
version has been scrapped.
|
44
51
|
|
45
|
-
As of version 0.5.0, the CPU.usage method has been removed in favor of the
|
46
|
-
CPU.load_avg method. This does not (currently) use a perf counter, so there
|
47
|
-
is no longer any delay. Also, the
|
48
|
-
|
52
|
+
As of version 0.5.0, the `CPU.usage` method has been removed in favor of the
|
53
|
+
`CPU.load_avg` method. This does not (currently) use a perf counter, so there
|
54
|
+
is no longer any delay. Also, the `processors` method has been added and the
|
55
|
+
`supported` method has been dropped. See the documentation for other changes.
|
49
56
|
|
50
57
|
## Acknowledgements
|
51
58
|
Thanks go to the MPlayer team for some source code that helped me on
|
@@ -57,14 +64,14 @@ None that I'm aware of. Please report bugs on the project page at:
|
|
57
64
|
https://github.com/djberg96/sys-cpu
|
58
65
|
|
59
66
|
## Future Plans
|
60
|
-
* Add iterative CPU.processors method.
|
61
|
-
* Add more information in general, such as what
|
67
|
+
* Add iterative `CPU.processors` method.
|
68
|
+
* Add more information in general, such as what `prtdiag` shows.
|
62
69
|
|
63
70
|
## License
|
64
71
|
Apache-2.0
|
65
72
|
|
66
73
|
## Copyright
|
67
|
-
(C) 2003-
|
74
|
+
(C) 2003-2022 Daniel J. Berger, All Rights Reserved
|
68
75
|
|
69
76
|
## Warranty
|
70
77
|
This package is provided "as is" and without any express or
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ require 'rake'
|
|
2
2
|
require 'rake/clean'
|
3
3
|
require 'rbconfig'
|
4
4
|
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
5
6
|
include RbConfig
|
6
7
|
|
7
8
|
CLEAN.include('**/*.gem', '**/*.rbc', '**/*.rbx', '**/*.lock')
|
@@ -10,7 +11,7 @@ namespace 'gem' do
|
|
10
11
|
desc "Create the sys-cpu gem"
|
11
12
|
task :create => [:clean] do
|
12
13
|
require 'rubygems/package'
|
13
|
-
spec =
|
14
|
+
spec = Gem::Specification.load('sys-cpu.gemspec')
|
14
15
|
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
15
16
|
Gem::Package.build(spec)
|
16
17
|
end
|
@@ -44,6 +45,8 @@ task :example => [:clean] do
|
|
44
45
|
|
45
46
|
end
|
46
47
|
|
48
|
+
RuboCop::RakeTask.new
|
49
|
+
|
47
50
|
desc "Run the test suite"
|
48
51
|
RSpec::Core::RakeTask.new(:spec)
|
49
52
|
|
data/doc/bsd.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
## Description
|
2
|
+
|
3
|
+
A Ruby interface for various cpu statistics
|
4
|
+
|
5
|
+
## Synopsis
|
6
|
+
```ruby
|
7
|
+
require 'sys/cpu' # or 'sys-cpu'
|
8
|
+
|
9
|
+
# BSD and OS X
|
10
|
+
puts "Architecture: " + Sys::CPU.architecture
|
11
|
+
puts "Machine: " + Sys::CPU.machine
|
12
|
+
puts "Mhz: " + Sys::CPU.cpu_freq.to_s
|
13
|
+
puts "Number of cpu's on this system: " + Sys::CPU.num_cpu.to_s
|
14
|
+
puts "CPU model: " + Sys::CPU.model
|
15
|
+
puts "Load averages: " + Sys::CPU.load_avg.join(", ")
|
16
|
+
```
|
17
|
+
|
18
|
+
## Constants
|
19
|
+
`VERSION`
|
20
|
+
|
21
|
+
Returns the current version number for this library.
|
22
|
+
|
23
|
+
## Singleton Methods
|
24
|
+
|
25
|
+
`CPU.architecture`
|
26
|
+
|
27
|
+
Returns the cpu's architecture, e.g. "x86_64".
|
28
|
+
|
29
|
+
`CPU.freq`
|
30
|
+
|
31
|
+
Returns an integer indicating the speed (i.e. frequency in Mhz) of
|
32
|
+
the cpu.
|
33
|
+
|
34
|
+
`CPU.load_avg`
|
35
|
+
|
36
|
+
Returns an array of three floats indicating the 1, 5 and 15 minute load
|
37
|
+
average.
|
38
|
+
|
39
|
+
`CPU.machine`
|
40
|
+
|
41
|
+
Returns the class of cpu (probably identical to the architecture).
|
42
|
+
|
43
|
+
`CPU.model`
|
44
|
+
|
45
|
+
Returns a string indicating the cpu model, e.g. "Intel".
|
46
|
+
|
47
|
+
`CPU.num_cpu`
|
48
|
+
|
49
|
+
Returns an integer indicating the number of cpu's on the system.
|
50
|
+
|
51
|
+
## Error Classes
|
52
|
+
`CPU::Error < StandardError`
|
53
|
+
|
54
|
+
Raised is response to internal function errors, usually relating to an
|
55
|
+
invalid cpu number.
|
56
|
+
|
57
|
+
## More Information
|
58
|
+
See the `README.md` file for more information.
|
data/doc/linux.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
## Description
|
2
|
+
Sys::CPU - An interface for various cpu statistics
|
3
|
+
|
4
|
+
## Synopsis
|
5
|
+
```ruby
|
6
|
+
require 'sys-cpu' # Or "sys/cpu"
|
7
|
+
|
8
|
+
Sys::CPU.processors{ |cs|
|
9
|
+
cs.members.each{ |m|
|
10
|
+
puts "#{m}: " + cs[m].to_s
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
Sys::CPU.bogomips(1) # -> returns bogomips for cpu #2
|
15
|
+
```
|
16
|
+
|
17
|
+
## Notes
|
18
|
+
|
19
|
+
Portions of this documentation were built dynamically.
|
20
|
+
|
21
|
+
## Constants
|
22
|
+
|
23
|
+
VERSION
|
24
|
+
|
25
|
+
Returns the current version number for this library as a string.
|
26
|
+
|
27
|
+
## Class Methods
|
28
|
+
`CPU.load_avg`
|
29
|
+
|
30
|
+
Returns an array of three floats indicating the 1, 5 and 15 minute load average.
|
31
|
+
|
32
|
+
`CPU.cpu_stats`
|
33
|
+
|
34
|
+
Returns a hash, with the cpu number as the key and an array as the value.
|
35
|
+
The array contains the number of seconds that the system spent in
|
36
|
+
user mode, user mode with low priority (nice), system mode, and the
|
37
|
+
idle task, respectively, for that cpu.
|
38
|
+
|
39
|
+
`CPU.processors{ |cpu_struct| ... }`
|
40
|
+
|
41
|
+
Calls the block for each processor on your system, yielding a `CPUStruct` to the block.
|
42
|
+
|
43
|
+
The exact members of the `CPUStruct` are the same as the singleton method names, except
|
44
|
+
for `Sys::CPU.processors` (although you may optionally omit the "?" when referring to a
|
45
|
+
struct member). These were determined when you installed this library because they
|
46
|
+
vary from one chip architecture to another.
|
data/install.rb
CHANGED
@@ -31,7 +31,7 @@ end
|
|
31
31
|
#######################################################################
|
32
32
|
if CONFIG['host_os'] =~ /linux/
|
33
33
|
cpu_file = "/proc/cpuinfo"
|
34
|
-
text_file = "doc/linux.
|
34
|
+
text_file = "doc/linux.md"
|
35
35
|
rb_file = "lib/linux/sys/cpu.rb"
|
36
36
|
|
37
37
|
if File.size(text_file) > 1400
|
@@ -44,7 +44,7 @@ if CONFIG['host_os'] =~ /linux/
|
|
44
44
|
IO.foreach(cpu_file){ |line|
|
45
45
|
next if line =~ /^$/
|
46
46
|
k,v = line.split(":")
|
47
|
-
|
47
|
+
|
48
48
|
v = v.strip.chomp
|
49
49
|
k = k.strip.gsub(/\s+/, '_').downcase
|
50
50
|
|
data/lib/sys/cpu.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This is just a stub file that requires the appropriate version
|
2
4
|
# depending on which platform you're on.
|
3
5
|
require 'rbconfig'
|
4
6
|
|
7
|
+
# The Sys module is a namespace only.
|
5
8
|
module Sys
|
9
|
+
# The CPU class encapsulates information about the physical cpu's on your system.
|
10
|
+
# This class is reopened for each of the supported platforms/operating systems.
|
6
11
|
class CPU
|
7
12
|
# The version of the sys-cpu gem.
|
8
|
-
VERSION = '1.0.
|
13
|
+
VERSION = '1.0.5'
|
14
|
+
|
15
|
+
private_class_method :new
|
9
16
|
end
|
10
17
|
end
|
11
18
|
|
@@ -14,6 +21,8 @@ case RbConfig::CONFIG['host_os']
|
|
14
21
|
require_relative('linux/sys/cpu')
|
15
22
|
when /windows|mswin|mingw|cygwin|dos/i
|
16
23
|
require_relative('windows/sys/cpu')
|
24
|
+
when /darwin|mach|osx/i
|
25
|
+
require_relative('darwin/sys/cpu')
|
17
26
|
else
|
18
27
|
require_relative('unix/sys/cpu')
|
19
28
|
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
require 'rbconfig'
|
5
|
+
|
6
|
+
# The Sys module serves as a namespace only.
|
7
|
+
module Sys
|
8
|
+
# The CPU class encapsulates information about the physical cpu's on your system.
|
9
|
+
class CPU
|
10
|
+
extend FFI::Library
|
11
|
+
ffi_lib FFI::Library::LIBC
|
12
|
+
|
13
|
+
# Error raised if any of the CPU methods fail.
|
14
|
+
class Error < StandardError; end
|
15
|
+
|
16
|
+
CTL_HW = 6 # Generic hardware/cpu
|
17
|
+
|
18
|
+
HW_MACHINE = 1 # Machine class
|
19
|
+
HW_MODEL = 2 # Specific machine model
|
20
|
+
HW_NCPU = 3 # Number of CPU's
|
21
|
+
HW_CPU_FREQ = 15 # CPU frequency
|
22
|
+
HW_MACHINE_ARCH = 12 # Machine architecture
|
23
|
+
|
24
|
+
SI_MACHINE = 5
|
25
|
+
SI_ARCHITECTURE = 6
|
26
|
+
SC_NPROCESSORS_ONLN = 15
|
27
|
+
|
28
|
+
P_OFFLINE = 1
|
29
|
+
P_ONLINE = 2
|
30
|
+
P_FAULTED = 4
|
31
|
+
P_POWEROFF = 5
|
32
|
+
P_NOINTR = 6
|
33
|
+
P_SPARE = 7
|
34
|
+
|
35
|
+
CPU_ARCH_ABI64 = 0x01000000
|
36
|
+
CPU_TYPE_X86 = 7
|
37
|
+
CPU_TYPE_X86_64 = (CPU_TYPE_X86 | CPU_ARCH_ABI64)
|
38
|
+
CPU_TYPE_SPARC = 14
|
39
|
+
CPU_TYPE_POWERPC = 18
|
40
|
+
CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
|
41
|
+
|
42
|
+
attach_function(
|
43
|
+
:sysctl,
|
44
|
+
%i[pointer uint pointer pointer pointer size_t],
|
45
|
+
:int
|
46
|
+
)
|
47
|
+
|
48
|
+
private_class_method :sysctl
|
49
|
+
|
50
|
+
attach_function(
|
51
|
+
:sysctlbyname,
|
52
|
+
%i[string pointer pointer pointer size_t],
|
53
|
+
:int
|
54
|
+
)
|
55
|
+
|
56
|
+
private_class_method :sysctlbyname
|
57
|
+
|
58
|
+
attach_function :getloadavg, %i[pointer int], :int
|
59
|
+
attach_function :processor_info, %i[int int string pointer pointer], :int
|
60
|
+
attach_function :sysconf, [:int], :long
|
61
|
+
|
62
|
+
private_class_method :getloadavg
|
63
|
+
private_class_method :processor_info
|
64
|
+
private_class_method :sysconf
|
65
|
+
|
66
|
+
class ClockInfo < FFI::Struct
|
67
|
+
layout(
|
68
|
+
:hz, :int,
|
69
|
+
:tick, :int,
|
70
|
+
:spare, :int,
|
71
|
+
:stathz, :int,
|
72
|
+
:profhz, :int
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the cpu's architecture. On most systems this will be identical
|
77
|
+
# to the CPU.machine method. On OpenBSD it will be identical to the CPU.model
|
78
|
+
# method.
|
79
|
+
#
|
80
|
+
def self.architecture
|
81
|
+
optr = FFI::MemoryPointer.new(:char, 256)
|
82
|
+
size = FFI::MemoryPointer.new(:size_t)
|
83
|
+
|
84
|
+
size.write_int(optr.size)
|
85
|
+
|
86
|
+
if sysctlbyname('hw.machine', optr, size, nil, 0) < 0
|
87
|
+
raise Error, 'sysctlbyname function failed'
|
88
|
+
end
|
89
|
+
|
90
|
+
optr.read_string
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the number of cpu's on your system. Note that each core on
|
94
|
+
# multi-core systems are counted as a cpu, e.g. one dual core cpu would
|
95
|
+
# return 2, not 1.
|
96
|
+
#
|
97
|
+
def self.num_cpu
|
98
|
+
optr = FFI::MemoryPointer.new(:long)
|
99
|
+
size = FFI::MemoryPointer.new(:size_t)
|
100
|
+
|
101
|
+
size.write_long(optr.size)
|
102
|
+
|
103
|
+
if sysctlbyname('hw.ncpu', optr, size, nil, 0) < 0
|
104
|
+
raise Error, 'sysctlbyname failed'
|
105
|
+
end
|
106
|
+
|
107
|
+
optr.read_long
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns the cpu's class type. On most systems this will be identical
|
111
|
+
# to the CPU.architecture method. On OpenBSD it will be identical to the
|
112
|
+
# CPU.model method.
|
113
|
+
#
|
114
|
+
def self.machine
|
115
|
+
buf = 0.chr * 32
|
116
|
+
mib = FFI::MemoryPointer.new(:int, 2)
|
117
|
+
size = FFI::MemoryPointer.new(:long, 1)
|
118
|
+
|
119
|
+
mib.write_array_of_int([CTL_HW, HW_MACHINE])
|
120
|
+
size.write_int(buf.size)
|
121
|
+
|
122
|
+
if sysctl(mib, 2, buf, size, nil, 0) < 0
|
123
|
+
raise Error, 'sysctl function failed'
|
124
|
+
end
|
125
|
+
|
126
|
+
buf.strip
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns a string indicating the cpu model.
|
130
|
+
#
|
131
|
+
def self.model
|
132
|
+
ptr = FFI::MemoryPointer.new(:long)
|
133
|
+
size = FFI::MemoryPointer.new(:size_t)
|
134
|
+
|
135
|
+
size.write_long(ptr.size)
|
136
|
+
|
137
|
+
if sysctlbyname('hw.cputype', ptr, size, nil, 0) < 0
|
138
|
+
raise 'sysctlbyname function failed'
|
139
|
+
end
|
140
|
+
|
141
|
+
case ptr.read_long
|
142
|
+
when CPU_TYPE_X86, CPU_TYPE_X86_64
|
143
|
+
'Intel'
|
144
|
+
when CPU_TYPE_SPARC
|
145
|
+
'Sparc'
|
146
|
+
when CPU_TYPE_POWERPC, CPU_TYPE_POWERPC64
|
147
|
+
'PowerPC'
|
148
|
+
else
|
149
|
+
'Unknown'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Returns an integer indicating the speed of the CPU.
|
154
|
+
#
|
155
|
+
def self.freq
|
156
|
+
optr = FFI::MemoryPointer.new(:long)
|
157
|
+
size = FFI::MemoryPointer.new(:size_t)
|
158
|
+
|
159
|
+
size.write_long(optr.size)
|
160
|
+
|
161
|
+
if RbConfig::CONFIG['host_cpu'] =~ /^arm|^aarch/i
|
162
|
+
if sysctlbyname('hw.tbfrequency', optr, size, nil, 0) < 0
|
163
|
+
raise Error, 'sysctlbyname failed on hw.tbfrequency'
|
164
|
+
end
|
165
|
+
|
166
|
+
size.clear
|
167
|
+
clock = ClockInfo.new
|
168
|
+
size.write_long(clock.size)
|
169
|
+
|
170
|
+
if sysctlbyname('kern.clockrate', clock, size, nil, 0) < 0
|
171
|
+
raise Error, 'sysctlbyname failed on kern.clockrate'
|
172
|
+
end
|
173
|
+
|
174
|
+
(optr.read_long * clock[:hz]) / 1_000_000
|
175
|
+
else
|
176
|
+
if sysctlbyname('hw.cpufrequency', optr, size, nil, 0) < 0
|
177
|
+
raise Error, 'sysctlbyname failed on hw.cpufrequency' if result < 0
|
178
|
+
end
|
179
|
+
optr.read_long / 1_000_000
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Returns an array of three floats indicating the 1, 5 and 15 minute load
|
184
|
+
# average.
|
185
|
+
#
|
186
|
+
def self.load_avg
|
187
|
+
loadavg = FFI::MemoryPointer.new(:double, 3)
|
188
|
+
|
189
|
+
if getloadavg(loadavg, loadavg.size) < 0
|
190
|
+
raise Error, 'getloadavg function failed'
|
191
|
+
end
|
192
|
+
|
193
|
+
loadavg.get_array_of_double(0, 3)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
data/lib/sys/linux/sys/cpu.rb
CHANGED
@@ -1,48 +1,48 @@
|
|
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
|
-
cpu_file
|
9
|
-
cpu_hash
|
11
|
+
cpu_file = '/proc/cpuinfo'
|
12
|
+
cpu_hash = {}
|
10
13
|
CPU_ARRAY = []
|
11
14
|
|
12
15
|
private_constant :CPU_ARRAY
|
13
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
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
42
|
# :startdoc:
|
43
43
|
|
44
|
+
# The CPU class encapsulates information about physical CPUs on your system.
|
44
45
|
class CPU
|
45
|
-
|
46
46
|
# :stopdoc:
|
47
47
|
|
48
48
|
CPUStruct = Struct.new('CPUStruct', *CPU_ARRAY.first.keys)
|
@@ -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
|
|
@@ -103,16 +101,20 @@ module Sys
|
|
103
101
|
|
104
102
|
# Create singleton methods for each of the attributes.
|
105
103
|
#
|
106
|
-
def self.method_missing(id, arg=0)
|
107
|
-
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)
|
108
106
|
rv = CPU_ARRAY[arg][id.to_s]
|
109
107
|
if rv.nil?
|
110
|
-
id = id
|
108
|
+
id = "#{id}?"
|
111
109
|
rv = CPU_ARRAY[arg][id]
|
112
110
|
end
|
113
111
|
rv
|
114
112
|
end
|
115
113
|
|
114
|
+
def self.respond_to_missing?(method, _private_methods = false)
|
115
|
+
CPU_ARRAY.first.keys.include?(method.to_s)
|
116
|
+
end
|
117
|
+
|
116
118
|
private_class_method :method_missing
|
117
119
|
|
118
120
|
# Returns a 3 element Array corresponding to the 1, 5 and 15 minute
|
@@ -120,7 +122,7 @@ module Sys
|
|
120
122
|
#
|
121
123
|
def self.load_avg
|
122
124
|
load_avg_file = '/proc/loadavg'
|
123
|
-
|
125
|
+
File.readlines(load_avg_file).first.split[0..2].map(&:to_f)
|
124
126
|
end
|
125
127
|
|
126
128
|
# Returns a hash of arrays that contains an array of the following
|
@@ -143,21 +145,21 @@ module Sys
|
|
143
145
|
cpu_stat_file = '/proc/stat'
|
144
146
|
hash = {} # Hash needed for multi-cpu systems
|
145
147
|
|
146
|
-
lines =
|
148
|
+
lines = File.readlines(cpu_stat_file)
|
147
149
|
|
148
|
-
lines.each_with_index
|
150
|
+
lines.each_with_index do |line, i|
|
149
151
|
array = line.split
|
150
|
-
break unless array[0] =~ /cpu/
|
152
|
+
break unless array[0] =~ /cpu/ # 'cpu' entries always on top
|
151
153
|
|
152
154
|
# Some machines list a 'cpu' and a 'cpu0'. In this case only
|
153
155
|
# return values for the numbered cpu entry.
|
154
|
-
if lines[i].split[0] == 'cpu' && lines[i+1].split[0] =~ /cpu\d/
|
156
|
+
if lines[i].split[0] == 'cpu' && lines[i + 1].split[0] =~ /cpu\d/
|
155
157
|
next
|
156
158
|
end
|
157
159
|
|
158
160
|
vals = array[1..-1].map{ |e| e.to_i / 100 } # 100 jiffies/sec.
|
159
161
|
hash[array[0]] = vals
|
160
|
-
|
162
|
+
end
|
161
163
|
|
162
164
|
hash
|
163
165
|
end
|