sys-cpu 0.6.4-universal-linux

Sign up to get free protection for your applications and to get access to all the features.
data/ext/extconf.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'mkmf'
2
+ require 'fileutils'
3
+ require 'rbconfig'
4
+
5
+ File.delete('cpu.c') if File.exists?('cpu.c')
6
+
7
+ case Config::CONFIG['host_os']
8
+ when /hpux/i
9
+ FileUtils.cp("hpux/hpux.c", "cpu.c")
10
+ when /sunos|solaris/i
11
+ FileUtils.cp("sunos/sunos.c", "cpu.c")
12
+ unless have_func("getloadavg")
13
+ have_library("kstat")
14
+ end
15
+ when /bsd|darwin/i
16
+ FileUtils.cp("bsd/bsd.c", "cpu.c")
17
+ have_func("sysctlbyname")
18
+ have_library("kvm")
19
+ have_header("kvm.h")
20
+ when /linux|dos|windows|win32|mingw|cygwin/i
21
+ STDERR.puts "Run 'rake gem:install' instead for this platform"
22
+ else
23
+ STDERR.puts "This platform is not currently supported. Exiting..."
24
+ end
25
+
26
+ create_makefile("sys/cpu")
data/ext/hpux/hpux.c ADDED
@@ -0,0 +1,219 @@
1
+ /*****************************************************************************
2
+ * hpux.c (cpu.c) - sys-cpu extension for HP-UX
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
+ #include <ruby.h>
11
+ #include "version.h"
12
+ #include <unistd.h>
13
+ #include <sys/pstat.h>
14
+
15
+ #ifndef PST_MAX_PROCS
16
+ #define PST_MAX_PROCS 32
17
+ #endif
18
+
19
+ #ifdef __cplusplus
20
+ extern "C"
21
+ {
22
+ #endif
23
+
24
+ VALUE cCPUError;
25
+
26
+ /*
27
+ * call-seq:
28
+ * CPU.load_avg
29
+ * CPU.load_avg(cpu_num)
30
+ * CPU.load_avg{ block }
31
+ *
32
+ * In non-block form returns an array of three floats indicating the 1, 5
33
+ * and 15 minute overall load average.
34
+ *
35
+ * In block form, it returns an array of three floats indicating the 1, 5
36
+ * and 15 minute load average for each cpu. Only useful on multi-cpu
37
+ * systems.
38
+ *
39
+ * If 'cpu_num' is provided, returns the load average (as a 3-element
40
+ * array) for that cpu only.
41
+ *
42
+ * You cannot provide +cpu_num+ and use block form at the same time.
43
+ */
44
+ static VALUE cpu_load_avg(int argc, VALUE *argv)
45
+ {
46
+ struct pst_processor psp[PST_MAX_PROCS];
47
+ struct pst_dynamic psd;
48
+ int i, num_cpu;
49
+ VALUE ncpu = Qnil;
50
+ VALUE la_ary = rb_ary_new();
51
+
52
+ rb_scan_args(argc,argv,"01",&ncpu);
53
+
54
+ if( (ncpu != Qnil) && (rb_block_given_p()) )
55
+ {
56
+ rb_raise(rb_eArgError,"Can't use block form when CPU number is provided");
57
+ }
58
+
59
+ if( (ncpu != Qnil) || ((ncpu == Qnil) && (rb_block_given_p())) )
60
+ {
61
+ num_cpu = pstat_getprocessor(psp,sizeof(struct pst_processor),PST_MAX_PROCS,0);
62
+ if(num_cpu < 0)
63
+ {
64
+ rb_raise(cCPUError,"Call to pstat_getprocessor() failed.");
65
+ }
66
+ else
67
+ {
68
+ for(i = 0; i < num_cpu; i++)
69
+ {
70
+ if( (ncpu != Qnil) && (NUM2INT(ncpu)) != i){ continue; }
71
+
72
+ rb_ary_push(la_ary,rb_float_new(psp[i].psp_avg_1_min));
73
+ rb_ary_push(la_ary,rb_float_new(psp[i].psp_avg_5_min));
74
+ rb_ary_push(la_ary,rb_float_new(psp[i].psp_avg_15_min));
75
+ if(rb_block_given_p())
76
+ {
77
+ rb_yield(la_ary);
78
+ }
79
+ else
80
+ {
81
+ return la_ary;
82
+ }
83
+ rb_ary_clear(la_ary);
84
+ }
85
+ }
86
+ }
87
+ else
88
+ {
89
+ if(pstat_getdynamic(&psd,sizeof(psd), (size_t)1, 0) == -1)
90
+ {
91
+ rb_raise(cCPUError,"Call to pstat_getdynamic() failed.");
92
+ }
93
+ else
94
+ {
95
+ rb_ary_push(la_ary,rb_float_new(psd.psd_avg_1_min));
96
+ rb_ary_push(la_ary,rb_float_new(psd.psd_avg_5_min));
97
+ rb_ary_push(la_ary,rb_float_new(psd.psd_avg_15_min));
98
+ return la_ary;
99
+ }
100
+ }
101
+
102
+ return Qnil;
103
+ }
104
+
105
+ /*
106
+ * call-seq:
107
+ * CPU.num_cpu
108
+ *
109
+ * Returns the number of CPU's on the system.
110
+ */
111
+ static VALUE cpu_num()
112
+ {
113
+ struct pst_dynamic dyn;
114
+ pstat_getdynamic(&dyn, sizeof(dyn), 0, 0);
115
+ return INT2NUM(dyn.psd_max_proc_cnt);
116
+ }
117
+
118
+ /* call-seq:
119
+ * CPU.num_active_cpu
120
+ *
121
+ * Returns the number of active CPU's on the system.
122
+ */
123
+ static VALUE cpu_num_active()
124
+ {
125
+ struct pst_dynamic dyn;
126
+ pstat_getdynamic(&dyn, sizeof(dyn), 0, 0);
127
+ return INT2NUM(dyn.psd_proc_cnt);
128
+ }
129
+
130
+ /*
131
+ * call-seq:
132
+ * CPU.architecture
133
+ *
134
+ * Returns the cpu architecture, e.g. PA RISC 1.2, etc, or nil if it
135
+ * cannot be determined.
136
+ */
137
+ static VALUE cpu_architecture()
138
+ {
139
+ long cpu_ver = sysconf(_SC_CPU_VERSION);
140
+
141
+ if(cpu_ver == CPU_HP_MC68020){ return rb_str_new2("Motorola MC68020"); }
142
+ if(cpu_ver == CPU_HP_MC68030){ return rb_str_new2("Motorola MC68030"); }
143
+ if(cpu_ver == CPU_HP_MC68040){ return rb_str_new2("Motorola MC68040"); }
144
+ if(cpu_ver == CPU_PA_RISC1_0){ return rb_str_new2("HP PA-RISC 1.0"); }
145
+ if(cpu_ver == CPU_PA_RISC1_1){ return rb_str_new2("HP PA-RISC 1.1"); }
146
+ if(cpu_ver == CPU_PA_RISC1_2){ return rb_str_new2("HP PA-RISC 1.2"); }
147
+ if(cpu_ver == CPU_PA_RISC2_0){ return rb_str_new2("HP PA-RISC 2.0"); }
148
+
149
+ return Qnil;
150
+ }
151
+
152
+ /*
153
+ * call-seq:
154
+ * CPU.freq(cpu_num=0)
155
+ *
156
+ * Returns an integer indicating the speed (i.e. frequency in Mhz) of
157
+ * +cpu_num+, or CPU 0 if no +cpu_num+ is specified.
158
+ */
159
+ static VALUE cpu_freq(int argc, VALUE *argv)
160
+ {
161
+ int cpu_num = 0; /* default value */
162
+ struct pst_processor psp;
163
+ unsigned long int clock_speed, scclktick;
164
+ VALUE ncpu = Qnil;
165
+
166
+ rb_scan_args(argc, argv, "01", &ncpu);
167
+
168
+ if(ncpu != Qnil)
169
+ {
170
+ Check_Type(ncpu,T_FIXNUM);
171
+ cpu_num = NUM2INT(ncpu);
172
+ }
173
+
174
+ if((pstat_getprocessor(&psp,sizeof(psp),(size_t)1,cpu_num)) == -1)
175
+ rb_raise(cCPUError, "Invalid CPU number?");
176
+
177
+ scclktick=sysconf(_SC_CLK_TCK);
178
+ clock_speed = (psp.psp_iticksperclktick * scclktick) / 1000000;
179
+
180
+ /************************************************************************/
181
+ /* It appears that pstat_getprocessor does not return a failure code */
182
+ /* for an invalid processor number. So, we'll assume that if the clock */
183
+ /* speed is 0 that an invalid number was provided. */
184
+ /************************************************************************/
185
+ if(clock_speed <= 0)
186
+ rb_raise(cCPUError, "Invalid CPU number?");
187
+
188
+ return UINT2NUM(clock_speed);
189
+ }
190
+
191
+ void Init_cpu()
192
+ {
193
+ VALUE mSys, cCPU;
194
+
195
+ /* The Sys module serves as a toplevel namespace only */
196
+ mSys = rb_define_module("Sys");
197
+
198
+ /* The CPU class provides class methods for obtaining CPU information */
199
+ cCPU = rb_define_class_under(mSys, "CPU", rb_cObject);
200
+
201
+ /* The CPU::Error Exception class is raised whenever any of the CPU class
202
+ * methods fail.
203
+ */
204
+ cCPUError = rb_define_class_under(cCPU, "Error", rb_eStandardError);
205
+
206
+ /* 0.6.4: The version of the sys-cpu library */
207
+ rb_define_const(cCPU, "VERSION", rb_str_new2(SYS_CPU_VERSION));
208
+
209
+ /* Class Methods */
210
+ rb_define_singleton_method(cCPU, "freq", cpu_freq, -1);
211
+ rb_define_singleton_method(cCPU, "num_cpu", cpu_num, 0);
212
+ rb_define_singleton_method(cCPU, "num_active_cpu", cpu_num_active, 0);
213
+ rb_define_singleton_method(cCPU, "load_avg", cpu_load_avg, -1);
214
+ rb_define_singleton_method(cCPU, "architecture", cpu_architecture, 0);
215
+ }
216
+
217
+ #ifdef __cplusplus
218
+ }
219
+ #endif
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.4: 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