sys-cpu 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,15 @@
1
+ == 0.6.0 - 26-Apr-2007
2
+ * Added support for most BSD flavors, including OS X. The freebsd.c file is
3
+ now just bsd.c.
4
+ * The CPU.type method for Solaris has been changed to CPU.cpu_type to avoid
5
+ conflicting with the Object.type method.
6
+ * Added a Rakefile. There are now tasks for building, testing and installing,
7
+ among other things. Run 'rake -T' to check your options.
8
+ * Many internal directory layout changes - C source files are now under the
9
+ 'ext' directory.
10
+ * Improved RDoc comments in the C source files.
11
+ * Changed CPUError to CPU::Error.
12
+
1
13
  == 0.5.5 - 17-Nov-2006
2
14
  * Fixed a bug in the Linux version where there could be a key but no
3
15
  associated value, causing a String#strip! call to fail. Now the value is
data/MANIFEST ADDED
@@ -0,0 +1,28 @@
1
+ * install.rb
2
+ * MANIFEST
3
+ * CHANGES
4
+ * Rakefile
5
+ * README
6
+ * sys-cpu.gemspec
7
+ * doc/bsd.txt
8
+ * doc/hpux.txt
9
+ * doc/linux.txt
10
+ * doc/sunos.txt
11
+ * doc/windows.txt
12
+ * examples/test_cpu_freebsd.rb
13
+ * examples/test_cpu_hpux.rb
14
+ * examples/test_cpu_linux.rb
15
+ * examples/test_cpu_sunos.rb
16
+ * examples/test_cpu_windows.rb
17
+ * ext/extconf.rb
18
+ * ext/version.h
19
+ * ext/bsd/bsd.c
20
+ * ext/hpux/hpux.c
21
+ * ext/sunos/sunos.c
22
+ * lib/sys/linux.rb
23
+ * lib/sys/windows.rb
24
+ * test/tc_bsd.rb
25
+ * test/tc_hpux.rb
26
+ * test/tc_sunos.rb
27
+ * test/tc_linux.rb
28
+ * test/tc_windows.rb
data/README CHANGED
@@ -2,26 +2,27 @@
2
2
  A Ruby interface for getting cpu information.
3
3
 
4
4
  = Installation
5
- === Linux and Windows:
6
- ruby test/ts_all.rb (optional)
7
- ruby install.rb
8
-
9
- === All other platforms:
10
- ruby extconf.rb
11
- make
12
- ruby test/ts_all.rb (optional)
13
- make site-install
5
+ == Standard Installation
6
+ rake test (optional)
7
+ rake install (non-gem)
8
+ == Gem installation
9
+ rake test (optional)
10
+ ruby sys-cpu.gemspec
11
+ gem install sys-cpu-X.Y.Z.gem # where 'X.Y.Z' corresponds to the version.
14
12
 
15
13
  = Notes
16
14
  === All Platforms
17
15
  As of version 0.5.0 Ruby 1.8.0 or later is required. It may work with
18
- earlier versions, but I will not support it. In addition, a test file is
19
- no longer auto-generated for you. If wish to run the test suite, cd to the
20
- 'test' directory and run the test suite appropriate for your platform.
16
+ earlier versions, but I will not support it.
21
17
 
22
18
  === Solaris
23
19
  Currently there is no 'processors()' iterative method for multi-cpu systems.
24
20
  I plan to add it this in a future release.
21
+
22
+ === OS X
23
+ The CPU.freq method is not supported at the moment. The sysctl() approach
24
+ returns a bogus, hard coded value of some sort. I suspect it's possible
25
+ by using kernel modules via kldload(), but I'm not sure how yet.
25
26
 
26
27
  === Linux
27
28
  This is pure Ruby. This version reads information out of /proc/cpuinfo and
@@ -35,14 +36,14 @@
35
36
  The text documentation for Linux is dynamically generated during the
36
37
  build process because the fields vary depending on your setup. So, don't
37
38
  look at it until *after* you've installed it. You will see a doc/linux.txt
38
- file after you run install.rb.
39
+ file after you run 'rake install' (via install.rb).
39
40
 
40
41
  === HP-UX
41
42
  Unlike other platforms, you can get load averages for an individual cpu (in
42
- multi-cpu systems). See documentation for more details.
43
+ multi-cpu systems). See documentation for more details.
43
44
 
44
- === Win32
45
- This is a pure Ruby implementation using the win32ole package + WMI. The C
45
+ === MS Windows
46
+ This is a pure Ruby implementation using the win32ole package + WMI. The C
46
47
  version has been scrapped.
47
48
 
48
49
  As of version 0.5.0, the CPU.usage method has been removed in favor of the
@@ -56,15 +57,15 @@
56
57
  http://www.rubyforge.org/projects/sysutils.
57
58
 
58
59
  = Future Plans
59
- === Solaris
60
60
  Add iterative CPU.processors method.
61
+ Make CPU.freq work on OS X.
61
62
  Add more information in general, such as what 'prtdiag' shows.
62
63
 
63
64
  = License
64
65
  Ruby's.
65
66
 
66
67
  = Copyright
67
- (C) 2003-2006 Daniel J. Berger
68
+ (C) 2003-2007 Daniel J. Berger
68
69
  All Rights Reserved
69
70
 
70
71
  = Warranty
@@ -74,5 +75,5 @@
74
75
 
75
76
  = Author
76
77
  Daniel J. Berger
77
- djberg96 at gmail dot com
78
+ djberg96 at nospam at gmail dot com
78
79
  imperator on IRC (irc.freenode.net)
@@ -5,7 +5,7 @@
5
5
  require "sys/cpu"
6
6
  include Sys
7
7
 
8
- # FreeBSD
8
+ # BSD and OS X
9
9
  puts "Architecture: " + CPU.architecture
10
10
  puts "Machine: " + CPU.machine
11
11
  puts "Mhz: " + CPU.cpu_freq.to_s
@@ -24,6 +24,8 @@ CPU.architecture
24
24
  CPU.freq
25
25
  Returns an integer indicating the speed (i.e. frequency in Mhz) of
26
26
  the cpu.
27
+
28
+ Not supported on OS X.
27
29
 
28
30
  CPU.load_avg
29
31
  Returns an array of three floats indicating the 1, 5 and 15 minute load
@@ -39,16 +41,16 @@ CPU.num_cpu
39
41
  Returns an integer indicating the number of cpu's on the system.
40
42
 
41
43
  = Error Classes
42
- CPUError < StandardError
44
+ CPU::Error < StandardError
43
45
  Raised is response to internal function errors, usually relating to an
44
46
  invalid cpu number.
45
47
 
46
48
  = Known Bugs
47
49
  None known. Please post bug reports to the SourceForge home page at
48
- http://www.rubyforge.org/projects/sysutils
50
+ http://www.rubyforge.org/projects/sysutils
49
51
 
50
52
  = Copyright
51
- (C) 2003-2006 Daniel J. Berger
53
+ (C) 2003-2007 Daniel J. Berger
52
54
  All Rights Reserved
53
55
 
54
56
  = Warranty
@@ -61,5 +63,5 @@ CPUError < StandardError
61
63
 
62
64
  = Author
63
65
  Daniel J. Berger
64
- djberg96 at yahoo dot com
65
- imperator/rubyhacker1 on IRC (Freenode)
66
+ djberg96 at nospam at gmail dot com
67
+ imperator on IRC (Freenode)
data/doc/hpux.txt CHANGED
@@ -46,7 +46,7 @@ CPU.num_active_cpu
46
46
  Returns an integer indicating the number of active cpu's on the system.
47
47
 
48
48
  = Error Classes
49
- CPUError < StandardError
49
+ CPU::Error < StandardError
50
50
  Raised is response to internal function errors, usually relating to an
51
51
  invalid cpu number.
52
52
 
@@ -58,7 +58,7 @@ CPUError < StandardError
58
58
  Add cpu model and type
59
59
 
60
60
  = Copyright
61
- (C) 2003-2006 Daniel J. Berger
61
+ (C) 2003-2007 Daniel J. Berger
62
62
  All Rights Reserved
63
63
 
64
64
  = Warranty
@@ -71,5 +71,5 @@ CPUError < StandardError
71
71
 
72
72
  = Author
73
73
  Daniel J. Berger
74
- djberg96 at yahoo dot com
75
- imperator/rubyhacker1 on IRC (Freenode)
74
+ djberg96 at nospam at gmail dot com
75
+ imperator on IRC (Freenode)
data/doc/sunos.txt CHANGED
@@ -48,7 +48,7 @@ CPU.state(cpu_num)
48
48
  Returns a string indicating the cpu state of 'cpu_num'.
49
49
 
50
50
  = Error Classes
51
- CPUError < StandardError
51
+ CPU::Error < StandardError
52
52
  Raised is response to internal function errors, usually relating to an
53
53
  invalid cpu number.
54
54
 
@@ -61,7 +61,7 @@ CPUError < StandardError
61
61
  Get the model() method to display more specific information.
62
62
 
63
63
  = Copyright
64
- (C) 2003-2006 Daniel J. Berger
64
+ (C) 2003-2007 Daniel J. Berger
65
65
  All Rights Reserved
66
66
 
67
67
  = Warranty
@@ -74,3 +74,5 @@ CPUError < StandardError
74
74
 
75
75
  = Author
76
76
  Daniel J. Berger
77
+ djberg96 at nospam at gmail dot com
78
+ imperator on IRC (Freenode)
data/doc/windows.txt CHANGED
@@ -102,7 +102,7 @@ CPU.type(host=localhost)
102
102
  Returns a string indicating the type of processor, e.g. GenuineIntel.
103
103
 
104
104
  = Exception Classes
105
- CPUError < StandardError
105
+ CPU::Error < StandardError
106
106
  Raised is response to internal function errors, most likely to be raised
107
107
  in the event that in invalid cpu number is provided for the 'freq'
108
108
  method.
@@ -135,7 +135,7 @@ CPUError < StandardError
135
135
  Win32_PerfFormattedData_PerfOS_Processor class.
136
136
 
137
137
  = Copyright
138
- (C) 2003-2006 Daniel J. Berger
138
+ (C) 2003-2007 Daniel J. Berger
139
139
  All Rights Reserved
140
140
 
141
141
  = Warranty
@@ -148,5 +148,5 @@ CPUError < StandardError
148
148
 
149
149
  = Author
150
150
  Daniel J. Berger
151
- djberg96 at yahoo dot com
151
+ djberg96 at nospam at gmail dot com
152
152
  imperator/rubyhacker1 on IRC (Freenode)
data/ext/bsd/bsd.c ADDED
@@ -0,0 +1,252 @@
1
+ /*****************************************************************************
2
+ * bsd.c (cpu.c) - sys-cpu extension for the various BSD flavors and OS X.
3
+ *
4
+ * Author: Daniel J. Berger
5
+ *
6
+ * Interface to provide various types of cpu information.
7
+ * Based on the Unix::Processors Perl module (Wilson Snyder) with ideas from
8
+ * Sys::CPU (Matt Sanford) and Solaris::Kstat (Alan Burlison) as well.
9
+ *
10
+ * Portions of this code lifted from the MPlayer source (cpuinfo.c).
11
+ *****************************************************************************/
12
+ #include <ruby.h>
13
+ #include "version.h"
14
+ #include <kvm.h>
15
+ #include <sys/sysctl.h>
16
+ #include <sys/types.h>
17
+ #include <string.h>
18
+ #include <errno.h>
19
+
20
+ #ifndef MISSING_USLEEP
21
+ #include <unistd.h>
22
+ #endif
23
+
24
+ VALUE cCPUError;
25
+
26
+ /****************************************************************************
27
+ * Used for FreeBSD 4.x to determine CPU clock speed. Stolen from cpuinfo.c
28
+ * in the MPlayer source code.
29
+ ****************************************************************************/
30
+ #if defined (__FreeBSD__) && (__FreeBSD__ < 5 )
31
+ static int64_t rdtsc(void){
32
+ unsigned int i, j;
33
+ #define RDTSC ".byte 0x0f, 0x31; "
34
+ asm(RDTSC : "=a"(i), "=d"(j) : );
35
+ return ((int64_t)j<<32) + (int64_t)i;
36
+ }
37
+ #endif
38
+
39
+ /*
40
+ * call-seq:
41
+ * CPU.load_average
42
+ *
43
+ * Returns an array of three floats indicating the 1, 5 and 15 minute load
44
+ * average.
45
+ */
46
+ static VALUE cpu_load_avg(VALUE klass){
47
+ kvm_t* k;
48
+ double avgs[3];
49
+ int n, max = 3;
50
+ VALUE v_num_array = rb_ary_new();
51
+
52
+ k = malloc(sizeof(kvm_t*));
53
+
54
+ if(!kvm_getloadavg(k, avgs, max))
55
+ rb_raise(cCPUError, "error calling kvm_getloadavg(): %s", strerror(errno));
56
+
57
+ for(n = 0; n < 3; n++)
58
+ rb_ary_push(v_num_array, rb_float_new(avgs[n]));
59
+
60
+ free(k);
61
+
62
+ return v_num_array;
63
+ }
64
+
65
+ /*
66
+ * call-seq:
67
+ * CPU.num_cpu
68
+ *
69
+ * Returns the number of cpu's on your system. Note that each core on
70
+ * multi-core systems are counted as a cpu, e.g. one dual core cpu would
71
+ * return 2, not 1.
72
+ */
73
+ static VALUE cpu_num(VALUE klass){
74
+ int num_cpu;
75
+ size_t len = sizeof(num_cpu);
76
+
77
+ #ifdef HAVE_SYSCTLBYNAME
78
+ if(sysctlbyname("hw.ncpu", &num_cpu, &len, NULL, 0))
79
+ rb_raise(cCPUError, "error calling sysctlbyname(): %s", strerror(errno));
80
+ #else
81
+ int mib[2];
82
+ mib[0] = CTL_HW;
83
+ mib[1] = HW_NCPU;
84
+
85
+ if(sysctl(mib, 2, &num_cpu, &len, NULL, 0))
86
+ rb_raise(cCPUError, "error calling sysctl(): %s", strerror(errno));
87
+ #endif
88
+
89
+ return INT2NUM(num_cpu);
90
+ }
91
+
92
+ /*
93
+ * call-seq:
94
+ * CPU.model
95
+ *
96
+ * Returns a string indicating the cpu model.
97
+ */
98
+ static VALUE cpu_model(VALUE klass){
99
+ char model[64];
100
+ size_t len = sizeof(model);
101
+
102
+ #ifdef HAVE_SYSCTLBYNAME
103
+ if(sysctlbyname("hw.model", &model, &len, NULL, 0))
104
+ rb_raise(cCPUError, "error calling sysctlbyname(): %s", strerror(errno));
105
+ #else
106
+ int mib[2];
107
+ mib[0] = CTL_HW;
108
+ mib[1] = HW_MODEL;
109
+
110
+ if(sysctl(mib, 2, &model, &len, NULL, 0))
111
+ rb_raise(cCPUError, "error calling sysctl(): %s", strerror(errno));
112
+ #endif
113
+
114
+ return rb_str_new2(model);
115
+ }
116
+
117
+ /*
118
+ * call-seq:
119
+ * CPU.architecture
120
+ *
121
+ * Returns the cpu's architecture. On most systems this will be identical
122
+ * to the CPU.machine method.
123
+ */
124
+ static VALUE cpu_architecture(VALUE klass){
125
+ char arch[32];
126
+ size_t len = sizeof(arch);
127
+
128
+ #ifdef HAVE_SYSCTLBYNAME
129
+ #if defined(__MACH__) && defined(__APPLE__)
130
+ if(sysctlbyname("hw.machine", &arch, &len, NULL, 0))
131
+ rb_raise(cCPUError, "error calling sysctlbyname(): %s", strerror(errno));
132
+ #else
133
+ if(sysctlbyname("hw.machine_arch", &arch, &len, NULL, 0))
134
+ rb_raise(cCPUError, "error calling sysctlbyname(): %s", strerror(errno));
135
+ #endif
136
+ #else
137
+ int mib[2];
138
+ mib[0] = CTL_HW;
139
+ mib[1] = HW_MACHINE_ARCH;
140
+
141
+ if(sysctl(mib, 2, &arch, &len, NULL, 0))
142
+ rb_raise(cCPUError, "error calling sysctl(): %s", strerror(errno));
143
+ #endif
144
+
145
+ return rb_str_new2(arch);
146
+ }
147
+
148
+ /*
149
+ * call-seq:
150
+ * CPU.machine
151
+ *
152
+ * Returns the cpu's class type. On most systems this will be identical
153
+ * to the CPU.architecture method.
154
+ */
155
+ static VALUE cpu_machine(VALUE klass){
156
+ char machine[32];
157
+ size_t len = sizeof(machine);
158
+
159
+ #ifdef HAVE_SYSCTLBYNAME
160
+ if(sysctlbyname("hw.machine", &machine, &len, NULL, 0))
161
+ rb_raise(cCPUError, "error calling sysctlbyname(): %s", strerror(errno));
162
+ #else
163
+ int mib[2];
164
+ mib[0] = CTL_HW;
165
+ mib[1] = HW_MACHINE;
166
+
167
+ if(sysctl(mib, 2, &machine, &len, NULL, 0))
168
+ rb_raise(cCPUError, "error calling sysctl(): %s", strerror(errno));
169
+ #endif
170
+
171
+ return rb_str_new2(machine);
172
+ }
173
+
174
+ /*
175
+ * call-seq:
176
+ * CPU.freq
177
+ *
178
+ * Returns an integer indicating the speed (i.e. frequency in Mhz) of the cpu.
179
+ *
180
+ * Not supported on OS X.
181
+ *--
182
+ * Not supported on OS X currently. The sysctl() approach returns a bogus
183
+ * hard-coded value.
184
+ *
185
+ * TODO: Fix for OS X.
186
+ */
187
+ static VALUE cpu_freq(VALUE klass){
188
+ int mhz;
189
+ #if defined (__FreeBSD__) && (__FreeBSD__ < 5)
190
+ int64_t tsc_start, tsc_end;
191
+ struct timeval tv_start, tv_end;
192
+ int usec_delay;
193
+
194
+ tsc_start = rdtsc();
195
+ gettimeofday(&tv_start,NULL);
196
+ #ifdef MISSING_USLEEP
197
+ sleep(1);
198
+ #else
199
+ usleep(100000);
200
+ #endif
201
+ tsc_end = rdtsc();
202
+ gettimeofday(&tv_end,NULL);
203
+
204
+ usec_delay = 1000000 * (tv_end.tv_sec - tv_start.tv_sec)
205
+ + (tv_end.tv_usec - tv_start.tv_usec);
206
+
207
+ mhz = ((tsc_end - tsc_start) / usec_delay);
208
+ #else
209
+ size_t len = sizeof(mhz);
210
+ #ifdef HAVE_SYSCTLBYNAME
211
+ if(sysctlbyname("hw.clockrate", &mhz, &len, 0, 0))
212
+ rb_raise(cCPUError, "error calling sysctlbyname(): %s", strerror(errno));
213
+ #else
214
+ int mib[2];
215
+
216
+ mib[0] = CTL_KERN;
217
+ mib[1] = KERN_CLOCKRATE;
218
+
219
+ if(sysctl(mib, 2, &mhz, &len, NULL, 0)
220
+ rb_raise(cCPUError,"error calling sysctlbyname(): %s", strerror(errno));
221
+ #endif
222
+ #endif
223
+
224
+ return INT2NUM(mhz);
225
+ }
226
+
227
+ void Init_cpu()
228
+ {
229
+ VALUE mSys, cCPU;
230
+
231
+ /* The Sys module serves as a toplevel namespace only */
232
+ mSys = rb_define_module("Sys");
233
+
234
+ /* The CPU class provides class methods for obtaining CPU information */
235
+ cCPU = rb_define_class_under(mSys, "CPU", rb_cObject);
236
+
237
+ /* The CPU::Error Exception class is raised whenever any of the CPU class
238
+ * methods fail.
239
+ */
240
+ cCPUError = rb_define_class_under(cCPU, "Error", rb_eStandardError);
241
+
242
+ /* 0.6.0: The version of this package, returned as a String */
243
+ rb_define_const(cCPU, "VERSION", rb_str_new2(SYS_CPU_VERSION));
244
+
245
+ /* Class Methods */
246
+ rb_define_singleton_method(cCPU, "architecture", cpu_architecture, 0);
247
+ rb_define_singleton_method(cCPU, "freq", cpu_freq, 0);
248
+ rb_define_singleton_method(cCPU, "load_avg", cpu_load_avg, 0);
249
+ rb_define_singleton_method(cCPU, "machine", cpu_machine, 0);
250
+ rb_define_singleton_method(cCPU, "model", cpu_model, 0);
251
+ rb_define_singleton_method(cCPU, "num_cpu", cpu_num, 0);
252
+ }
data/ext/extconf.rb ADDED
@@ -0,0 +1,24 @@
1
+ require "mkmf"
2
+ require "fileutils"
3
+
4
+ File.delete('cpu.c') if File.exists?('cpu.c')
5
+
6
+ case RUBY_PLATFORM
7
+ when /hpux/i
8
+ FileUtils.cp("hpux/hpux.c", "cpu.c")
9
+ when /sunos|solaris/i
10
+ FileUtils.cp("sunos/sunos.c", "cpu.c")
11
+ unless have_func("getloadavg")
12
+ have_library("kstat")
13
+ end
14
+ when /bsd|darwin/i
15
+ FileUtils.cp("bsd/bsd.c", "cpu.c")
16
+ have_func("sysctlbyname")
17
+ have_library("kvm")
18
+ when /linux|dos|windows|win32|mingw|cygwin/i
19
+ STDERR.puts "Run 'ruby install.rb' instead for this platform"
20
+ else
21
+ STDERR.puts "This platform is not currently supported. Exiting..."
22
+ end
23
+
24
+ create_makefile("sys/cpu")