sys-cpu 0.6.1-x86-linux → 0.6.2-x86-linux

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.
data/ext/sunos/sunos.c ADDED
@@ -0,0 +1,281 @@
1
+ /*****************************************************************************
2
+ * sunos.c (cpu.c) - Solaris code sys-cpu
3
+ *
4
+ * Interface to provide various types of cpu information.
5
+ * Based on the Unix::Processors Perl module (Wilson Snyder) with ideas from
6
+ * Sys::CPU (Matt Sanford) and Solaris::Kstat (Alan Burlison) as well.
7
+ *
8
+ * The kstat code for load_avg() was taken largely from a post by Casper Dik
9
+ * on comp.unix.solaris.
10
+ *****************************************************************************/
11
+ #include <ruby.h>
12
+ #include "version.h"
13
+ #include <unistd.h>
14
+ #include <sys/types.h>
15
+ #include <sys/processor.h>
16
+ #include <sys/utsname.h>
17
+ #include <sys/param.h>
18
+ #include <kstat.h>
19
+
20
+ #ifdef HAVE_GETLOADAVG
21
+ #include <sys/loadavg.h>
22
+ #endif
23
+
24
+ /* Missing in older header files */
25
+ #ifndef P_POWEROFF
26
+ #define P_POWEROFF 5
27
+ #endif
28
+
29
+ #ifdef __cplusplus
30
+ extern "C"
31
+ {
32
+ #endif
33
+
34
+ VALUE cCPUError;
35
+
36
+ /*
37
+ * call-seq:
38
+ * CPU.freq(cpu_num=0)
39
+ *
40
+ * Returns an integer indicating the speed (i.e. frequency in Mhz) of
41
+ * +cpu_num+, or cpu 0 (zero) if no number is provided. If you provide an
42
+ * invalid cpu number then a CPU::Error is raised.
43
+ */
44
+ static VALUE cpu_freq(int argc, VALUE *argv)
45
+ {
46
+ int ncpu = 0; /* Default value */
47
+ int cpu;
48
+ int last_cpu = 0;
49
+ int clock = 0;
50
+ processor_info_t pi;
51
+ VALUE cpu_num = Qnil;
52
+
53
+ rb_scan_args(argc, argv, "01", &cpu_num);
54
+
55
+ if(cpu_num != Qnil)
56
+ ncpu = NUM2INT(cpu_num);
57
+
58
+ for(cpu = ncpu; cpu < last_cpu+16; cpu++) {
59
+ if(processor_info(cpu, &pi) == 0 && pi.pi_state == P_ONLINE){
60
+ if(clock < pi.pi_clock){
61
+ clock = pi.pi_clock;
62
+ }
63
+ last_cpu = cpu;
64
+ }
65
+ }
66
+
67
+ if(clock == 0)
68
+ rb_raise(cCPUError, "Invalid CPU number?");
69
+
70
+ return INT2NUM(clock);
71
+ }
72
+
73
+ /*
74
+ * call-seq:
75
+ * CPU.state(cpu_num=0)
76
+ *
77
+ * Returns a string indicating the cpu state of +cpu_num+, or cpu 0 if no
78
+ * number is specified. Raises a CPU::Error if an invalid +cpu_num+ is provided.
79
+ */
80
+ static VALUE cpu_state(int argc, VALUE *argv)
81
+ {
82
+ int cpu = 0; /* Default value */
83
+ char* value = NULL;
84
+ processor_info_t pi;
85
+ VALUE cpu_num = Qnil;
86
+
87
+ rb_scan_args(argc, argv, "01", &cpu_num);
88
+
89
+ if(cpu_num != Qnil)
90
+ cpu = NUM2INT(cpu_num);
91
+
92
+ if(processor_info(cpu, &pi) == 0){
93
+ switch (pi.pi_state)
94
+ {
95
+ case P_ONLINE:
96
+ value = "online";
97
+ break;
98
+ case P_OFFLINE:
99
+ value = "offline";
100
+ break;
101
+ case P_POWEROFF:
102
+ value = "poweroff";
103
+ break;
104
+ default:
105
+ value = "unknown";
106
+ }
107
+ }
108
+ else{
109
+ rb_raise(cCPUError, "state() call failed - invalid cpu num?");
110
+ }
111
+
112
+ return rb_str_new2(value);
113
+ }
114
+
115
+ /*
116
+ * call-seq:
117
+ * CPU.num_cpu
118
+ *
119
+ * Returns the number of cpu's on your system.
120
+ */
121
+ static VALUE cpu_num()
122
+ {
123
+ int num_cpu;
124
+ num_cpu = sysconf(_SC_NPROCESSORS_ONLN);
125
+ return INT2NUM(num_cpu);
126
+ }
127
+
128
+ /*
129
+ * call-seq:
130
+ * CPU.cpu_type
131
+ *
132
+ * Returns a string indicating the type of processor. This is the
133
+ * architecture (e.g. sparcv9), not the exact model (e.g. Ultra-IIe).
134
+ * Returns nil if not found.
135
+ *--
136
+ * All cpu must be the same type (right?)
137
+ */
138
+ static VALUE cpu_type()
139
+ {
140
+ int cpu = 0;
141
+ char* value = NULL;
142
+ processor_info_t pi;
143
+
144
+ /* Some systems start the cpu num at 0, others start at 1 */
145
+ if(processor_info(cpu, &pi) == 0)
146
+ value = pi.pi_processor_type;
147
+ else if(processor_info(cpu+1, &pi) == 0)
148
+ value = pi.pi_processor_type;
149
+ else
150
+ return Qnil;
151
+
152
+ return rb_str_new2(value);
153
+ }
154
+
155
+ /*
156
+ * call-seq:
157
+ * CPU.fpu_type
158
+ *
159
+ * Returns a string indicating the type of floating point unit, or nil if
160
+ * not found.
161
+ */
162
+ static VALUE cpu_fpu_type()
163
+ {
164
+ int cpu = 0;
165
+ char* value = NULL;
166
+ processor_info_t pi;
167
+
168
+ /* Some systems start the cpu num at 0, others start at 1 */
169
+ if(processor_info(cpu, &pi) == 0)
170
+ value = pi.pi_fputypes;
171
+ else if(processor_info(cpu+1, &pi) == 0)
172
+ value = pi.pi_fputypes;
173
+ else
174
+ return Qnil;
175
+
176
+ return rb_str_new2(value);
177
+ }
178
+
179
+ /*
180
+ * call-seq:
181
+ * CPU.model
182
+ *
183
+ * Returns a string indicating the cpu model. For now, this is the
184
+ * architecture type, rather than the exact model.
185
+ */
186
+ static VALUE cpu_model()
187
+ {
188
+ struct utsname u;
189
+ uname(&u);
190
+ return rb_str_new2(u.machine);
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * CPU.load_avg
196
+ *
197
+ * Returns an array of 3 floats, the load averages for the last 1, 5 and 15
198
+ * minutes.
199
+ */
200
+ static VALUE cpu_load_avg()
201
+ {
202
+ VALUE la_ary = rb_ary_new();
203
+
204
+ #ifdef HAVE_GETLOADAVG
205
+ double load_avg[3];
206
+
207
+ if(getloadavg(load_avg, sizeof(load_avg)) < 0)
208
+ rb_raise(cCPUError, "getloadavg() error");
209
+
210
+ rb_ary_push(la_ary, rb_float_new(load_avg[0]));
211
+ rb_ary_push(la_ary, rb_float_new(load_avg[1]));
212
+ rb_ary_push(la_ary, rb_float_new(load_avg[2]));
213
+ #else
214
+ kstat_ctl_t* kc;
215
+ kstat_t* ksp;
216
+ kstat_named_t* kn1;
217
+ kstat_named_t* kn5;
218
+ kstat_named_t* kn15;
219
+
220
+ kc = kstat_open();
221
+
222
+ if(kc == 0)
223
+ rb_raise(cCPUError, "kstat_open() error");
224
+
225
+ ksp = kstat_lookup(kc, "unix", 0, "system_misc");
226
+
227
+ if(ksp == 0)
228
+ rb_raise(cCPUError, "kstat_lookup() error");
229
+
230
+ if(kstat_read(kc,ksp,0) == -1)
231
+ rb_raise(cCPUError, "kstat_read() error");
232
+
233
+ kn1 = kstat_data_lookup(ksp, "avenrun_1min");
234
+ kn5 = kstat_data_lookup(ksp, "avenrun_5min");
235
+ kn15 = kstat_data_lookup(ksp, "avenrun_15min");
236
+
237
+ if( (kn1 == 0) || (kn5 == 0) || (kn15 == 0) )
238
+ rb_raise(cCPUError, "kstat_lookup() error");
239
+
240
+ rb_ary_push(la_ary, rb_float_new((double)kn1->value.ui32/FSCALE));
241
+ rb_ary_push(la_ary, rb_float_new((double)kn5->value.ui32/FSCALE));
242
+ rb_ary_push(la_ary, rb_float_new((double)kn15->value.ui32/FSCALE));
243
+
244
+ kstat_close(kc);
245
+ #endif
246
+
247
+ return la_ary;
248
+ }
249
+
250
+ void Init_cpu()
251
+ {
252
+ VALUE mSys, cCPU;
253
+
254
+ /* The Sys module serves as a toplevel namespace only */
255
+ mSys = rb_define_module("Sys");
256
+
257
+ /* The CPU class provides class methods for obtaining CPU information */
258
+ cCPU = rb_define_class_under(mSys, "CPU", rb_cObject);
259
+
260
+ /* The CPU::Error Exception class is raised whenever any of the CPU class
261
+ * methods fail.
262
+ */
263
+ cCPUError = rb_define_class_under(cCPU, "Error", rb_eStandardError);
264
+
265
+ /* 0.6.2: The version of the sys-cpu library */
266
+ rb_define_const(cCPU, "VERSION", rb_str_new2(SYS_CPU_VERSION));
267
+
268
+ /* Class Methods */
269
+ rb_define_singleton_method(cCPU, "freq", cpu_freq, -1);
270
+ rb_define_singleton_method(cCPU, "state", cpu_state, -1);
271
+ rb_define_singleton_method(cCPU, "num_cpu", cpu_num, 0);
272
+ rb_define_singleton_method(cCPU, "cpu_type", cpu_type, 0);
273
+ rb_define_singleton_method(cCPU, "fpu_type", cpu_fpu_type, 0);
274
+ rb_define_singleton_method(cCPU, "model", cpu_model, 0);
275
+ rb_define_singleton_method(cCPU, "load_avg", cpu_load_avg, 0);
276
+
277
+ }
278
+
279
+ #ifdef __cplusplus
280
+ }
281
+ #endif
data/ext/version.h ADDED
@@ -0,0 +1,2 @@
1
+ /* version.h - one version to rule them all */
2
+ #define SYS_CPU_VERSION "0.6.2"
data/install.rb ADDED
@@ -0,0 +1,84 @@
1
+ #######################################################################
2
+ # install.rb
3
+ #
4
+ # For pure Ruby versions only. Generally speaking this script should
5
+ # not be run directly. Use the 'rake install' task instead.
6
+ #######################################################################
7
+ require 'rbconfig'
8
+ require 'fileutils'
9
+ include Config
10
+ install_dir = File.join(CONFIG['sitelibdir'], 'sys')
11
+
12
+ file = ""
13
+
14
+ case CONFIG['host_os']
15
+ when /windows|win32|mingw|cygwin|dos/i
16
+ file = "lib/windows/sys/cpu.rb"
17
+ when /linux/i
18
+ file = "lib/linux/sys/cpu.rb"
19
+ when /sunos|solaris|hpux|freebsd/i
20
+ STDERR.puts "Use 'extconf.rb/make/make site-install' for this platform"
21
+ exit
22
+ else
23
+ STDERR.puts "This platform is not currently supported. Exiting..."
24
+ exit
25
+ end
26
+
27
+ #######################################################################
28
+ # Dynamically generate some of the documentation for linux. If the
29
+ # doc size is already greater than 1.4k, assume that the documentation
30
+ # has already been written at some point previously and skip it.
31
+ #######################################################################
32
+ if CONFIG['host_os'] =~ /linux/
33
+ cpu_file = "/proc/cpuinfo"
34
+ text_file = "doc/linux.txt"
35
+ rb_file = "lib/linux/sys/cpu.rb"
36
+
37
+ if File.size(text_file) > 1400
38
+ puts "You appear to have already created the documentation."
39
+ puts "Skipping..."
40
+ else
41
+ puts "Dynamically generating documentation..."
42
+ fh = File.open(text_file,"a+")
43
+
44
+ IO.foreach(cpu_file){ |line|
45
+ next if line =~ /^$/
46
+ k,v = line.split(":")
47
+ v.strip!.chomp!
48
+ k.strip!.gsub!(/\s+/,"_")
49
+ k.downcase!
50
+ if v =~ /yes|no/i
51
+ k += "?"
52
+ end
53
+ fh.puts("CPU.#{k}")
54
+ if v =~ /yes|no/i
55
+ k.chop!
56
+ msg = " Returns true if a " + k.gsub(/_/," ") + "exists on"
57
+ msg << " this system"
58
+ fh.puts(msg)
59
+ else
60
+ fh.puts(" Returns the " + k.gsub(/_/," "))
61
+ end
62
+ fh.puts # Add a blank line
63
+ }
64
+
65
+ fh.puts(doc)
66
+ fh.close
67
+ puts "Documentation creation complete"
68
+ end
69
+ end
70
+
71
+ # Create the 'sys' toplevel directory if it doesn't already exist
72
+ begin
73
+ unless File.exist?(install_dir)
74
+ Dir.mkdir(install_dir)
75
+ end
76
+ rescue Errno::EACCES => e
77
+ puts "Unable to create #{install_dir}: #{e}"
78
+ exit
79
+ end
80
+
81
+ # Finally, copy the file to the appropriate directory
82
+ FileUtils.cp(file, "#{install_dir}/cpu.rb", :verbose => true)
83
+
84
+ puts "Installation successful"
@@ -0,0 +1,122 @@
1
+ ##########################################################
2
+ # linux.rb (sys-cpu) - pure Ruby version for Linux
3
+ ##########################################################
4
+ module Sys
5
+
6
+ # :stopdoc:
7
+
8
+ cpu_file = "/proc/cpuinfo"
9
+ cpu_hash = {}
10
+ $cpu_array = []
11
+
12
+ # Parse the info out of the /proc/cpuinfo file
13
+ IO.foreach(cpu_file){ |line|
14
+ line.strip!
15
+ next if line.empty?
16
+
17
+ key, val = line.split(":")
18
+ key.strip!
19
+ key.gsub!(/\s+/,"_")
20
+ key.downcase!
21
+ val.strip! if val
22
+
23
+ if cpu_hash.has_key?(key)
24
+ $cpu_array.push(cpu_hash.dup)
25
+ cpu_hash.clear
26
+ end
27
+
28
+ # Turn yes/no attributes into booleans
29
+ if val == 'yes'
30
+ val = true
31
+ elsif val == 'no'
32
+ val = false
33
+ end
34
+
35
+ cpu_hash[key] = val
36
+ }
37
+
38
+ $cpu_array.push(cpu_hash)
39
+
40
+ # :startdoc:
41
+
42
+ class CPU
43
+
44
+ # The version of the sys-cpu library.
45
+ VERSION = '0.6.2'
46
+
47
+ # :stopdoc:
48
+
49
+ CPUStruct = Struct.new("CPUStruct", *$cpu_array.first.keys)
50
+
51
+ # :startdoc:
52
+
53
+ # In block form, yields a CPUStruct for each CPU on the system. In
54
+ # non-block form, returns an Array of CPUStruct's.
55
+ #
56
+ # The exact members of the struct vary on Linux systems.
57
+ #
58
+ def self.processors
59
+ array = []
60
+ $cpu_array.each{ |hash|
61
+ struct = CPUStruct.new
62
+ struct.members.each{ |m| struct.send("#{m}=", hash[m]) }
63
+ if block_given?
64
+ yield struct
65
+ else
66
+ array << struct
67
+ end
68
+ }
69
+ array unless block_given?
70
+ end
71
+
72
+ private
73
+
74
+ # Create singleton methods for each of the attributes.
75
+ #
76
+ def self.method_missing(id, arg=0)
77
+ rv = $cpu_array[arg][id.to_s]
78
+ if rv.nil?
79
+ id = id.to_s + "?"
80
+ rv = $cpu_array[arg][id]
81
+ end
82
+ rv
83
+ end
84
+
85
+ public
86
+
87
+ # Returns a 3 element Array corresponding to the 1, 5 and 15 minute
88
+ # load average for the system.
89
+ #
90
+ def self.load_avg
91
+ load_avg_file = "/proc/loadavg"
92
+ IO.readlines(load_avg_file).first.split[0..2].map{ |e| e.to_f }
93
+ end
94
+
95
+ # Returns a hash of arrays that contain the number of seconds that the
96
+ # system spent in user mode, user mode with low priority (nice), system
97
+ # mode, and the idle task, respectively.
98
+ #
99
+ def self.cpu_stats
100
+ cpu_stat_file = "/proc/stat"
101
+ hash = {} # Hash needed for multi-cpu systems
102
+
103
+ lines = IO.readlines(cpu_stat_file)
104
+
105
+ lines.each_with_index{ |line, i|
106
+ array = line.split
107
+ break unless array[0] =~ /cpu/ # 'cpu' entries always on top
108
+
109
+ # Some machines list a 'cpu' and a 'cpu0'. In this case only
110
+ # return values for the numbered cpu entry.
111
+ if lines[i].split[0] == "cpu" && lines[i+1].split[0] =~ /cpu\d/
112
+ next
113
+ end
114
+
115
+ vals = array[1..-1].map{ |e| e = e.to_i / 100 } # 100 jiffies/sec.
116
+ hash[array[0]] = vals
117
+ }
118
+
119
+ hash
120
+ end
121
+ end
122
+ end