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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d1988f097f8efd9447e33fd135d373fccc9cbfa699a2c67257361e50367a661
4
- data.tar.gz: e2abfb34d4afe062b47cac1bc1a73fb79a609dc55c5070d03bee09f7c841f9d9
3
+ metadata.gz: 7624e670375df3b2fd1055c43ac391b592c9288462fbaf2687b3c94d149434e2
4
+ data.tar.gz: d9b4acf3a644bed915050950bbdd19136700ddc544f7b2de06a1a54af3910411
5
5
  SHA512:
6
- metadata.gz: 9fd5d3cabaf78df0ea92dae46081325dcd9569cfd10af7c071cf2532d87b09ec191d15377fe1ce5aa2acf34db49d09ccfee0c6c4bdb7dec914ba4be61e57565d
7
- data.tar.gz: c11064f1318983072179f78c2fb3b2eb4ac23b8bbe0b266c0e0ba7174e3f77b4b9ccb27184b4ffdb70c07bcef771ec36ee55b8cb3a8c0a85c2c2ee3374dfd97f
6
+ metadata.gz: f4ff44d8420830dd6cc1da28a8c016587226a38870612c3858dc4fee9f9c2038615c2cc7f24160a00467f9bde67ac45a174d5dff80d7b22682dd7399969ce061
7
+ data.tar.gz: a2c59fd8f0243d97fdddcb8ea333a27a71028c19218fc4ebedde57b209d5f6f970f1e21c3798fbcaacc387becfd1895cf78b2b3e035f8f2c50778e31a7a8d808
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGES.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 1.0.4 - 10-Jun-2022
2
+ * The OSX code for the CPU.freq method was updated for arm64 systems.
3
+ * Some refactoring to the specs and uses shared examples now.
4
+ * Now makes the new method a private class method. The constructor was never
5
+ meant to be used with this library, so now it's explicitly forbidden.
6
+ * Added rubocop and rubocop-rspec as development dependencies, as well as
7
+ a rubocop rake task, and applied some suggested changes.
8
+ * Fixed the global Gemfile source issue. Just use the gemspec.
9
+ * Added some new cpu families for Windows.
10
+ * Added a respond_to_missing? method to the Linux version since it uses
11
+ method_missing.
12
+ * The MS Windows version now assumes Ruby 2.0 or later.
13
+
14
+ ## 1.0.3 - 28-Jan-2021
15
+ * The code for OSX was split out into its own source file. This was partly for
16
+ ease of maintenance, but also because there was confusion with the
17
+ processor_info function. The original function was only aimed at Solaris, but
18
+ it turns out OSX has its own, different implementation. This caused segfaults.
19
+
20
+ ## 1.0.2 - 25-Jan-2021
21
+ * Fixed issues where things that were meant to be private weren't actually private.
22
+
1
23
  ## 1.0.1 - 20-Dec-2020
2
24
  * Switched from rdoc to markdown.
3
25
 
data/Gemfile CHANGED
@@ -1,7 +1,2 @@
1
- source 'https://rubygems.org' do
2
- gem 'ffi', '~> 1.1'
3
- group 'test' do
4
- gem 'rake'
5
- gem 'rspec', '~> 3.9'
6
- end
7
- end
1
+ source 'https://rubygems.org'
2
+ gemspec
data/MANIFEST.md CHANGED
@@ -17,6 +17,7 @@
17
17
  * examples/example_sys_cpu_sunos.rb
18
18
  * examples/example_sys_cpu_windows.rb
19
19
  * lib/sys/cpu.rb
20
+ * lib/sys/darwin/sys/cpu.rb
20
21
  * lib/sys/linux/sys/cpu.rb
21
22
  * lib/sys/unix/sys/cpu.rb
22
23
  * lib/sys/windows/sys/cpu.rb
data/README.md CHANGED
@@ -1,3 +1,9 @@
1
+ [![Ruby](https://github.com/djberg96/sys-cpu/actions/workflows/ruby.yml/badge.svg)](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/ffi/certs/djberg96_pub.pem)`
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
- Currently there is no +processors+ iterative method for multi-cpu systems.
13
- I plan to add it this in a future release.
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 +require+ this package. This
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. You will see a doc/linux.txt
31
- file after you run +rake install+ (via install.rb).
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 +processors+ method has been added and the
48
- +supported+ method has been dropped. See the documentation for other changes.
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 +prtdiag+ shows.
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-2020 Daniel J. Berger, All Rights Reserved
74
+ (C) 2003-2021 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 = eval(IO.read('sys-cpu.gemspec'))
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.txt"
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.1'.freeze
13
+ VERSION = '1.0.4'
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,198 @@
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'].downcase == 'arm64'
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
197
+
198
+ p Sys::CPU.freq