27
27
#include < stdlib.h> /* getexecname() */
28
28
#include < strings.h> /* strncpy() */
29
29
30
+ #include < kstat.h>
31
+ #include < errno.h>
32
+ #include < inttypes.h>
33
+ #include < sys/types.h>
30
34
31
35
#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
32
36
#define PROCFS_FILE_OFFSET_BITS_HACK 1
@@ -46,6 +50,7 @@ namespace node {
46
50
47
51
using namespace v8 ;
48
52
53
+
49
54
char ** Platform::SetupArgs (int argc, char *argv[]) {
50
55
return argv;
51
56
}
@@ -108,11 +113,103 @@ int Platform::GetExecutablePath(char* buffer, size_t* size) {
108
113
}
109
114
110
115
111
- // TODO: libkstat provides all this info. Need to link it though.
116
+ static Handle <Value> data_named (kstat_named_t *knp) {
117
+ Handle <Value> val;
118
+
119
+ switch (knp->data_type ) {
120
+ case KSTAT_DATA_CHAR:
121
+ val = Number::New (knp->value .c [0 ]);
122
+ break ;
123
+ case KSTAT_DATA_INT32:
124
+ val = Number::New (knp->value .i32 );
125
+ break ;
126
+ case KSTAT_DATA_UINT32:
127
+ val = Number::New (knp->value .ui32 );
128
+ break ;
129
+ case KSTAT_DATA_INT64:
130
+ val = Number::New (knp->value .i64 );
131
+ break ;
132
+ case KSTAT_DATA_UINT64:
133
+ val = Number::New (knp->value .ui64 );
134
+ break ;
135
+ case KSTAT_DATA_STRING:
136
+ val = String::New (KSTAT_NAMED_STR_PTR (knp));
137
+ break ;
138
+ default :
139
+ throw (String::New (" unrecognized data type" ));
140
+ }
141
+
142
+ return (val);
143
+ }
112
144
113
145
114
146
int Platform::GetCPUInfo (Local<Array> *cpus) {
115
- // http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/psrinfo/psrinfo.pl
147
+ HandleScope scope;
148
+ Local<Object> cpuinfo;
149
+ Local<Object> cputimes;
150
+
151
+ int lookup_instance;
152
+ kstat_ctl_t *kc;
153
+ kstat_t *ksp;
154
+ kstat_named_t *knp;
155
+
156
+ if ((kc = kstat_open ()) == NULL )
157
+ throw " could not open kstat" ;
158
+
159
+ *cpus = Array::New ();
160
+
161
+ lookup_instance = 0 ;
162
+ while (ksp = kstat_lookup (kc, " cpu_info" , lookup_instance, NULL )){
163
+ cpuinfo = Object::New ();
164
+
165
+ if (kstat_read (kc, ksp, NULL ) == -1 ) {
166
+ /*
167
+ * It is deeply annoying, but some kstats can return errors
168
+ * under otherwise routine conditions. (ACPI is one
169
+ * offender; there are surely others.) To prevent these
170
+ * fouled kstats from completely ruining our day, we assign
171
+ * an "error" member to the return value that consists of
172
+ * the strerror().
173
+ */
174
+ cpuinfo->Set (String::New (" error" ), String::New (strerror (errno)));
175
+ (*cpus)->Set (lookup_instance, cpuinfo);
176
+ } else {
177
+ knp = (kstat_named_t *) kstat_data_lookup (ksp, " clock_MHz" );
178
+ cpuinfo->Set (String::New (" speed" ), data_named (knp));
179
+ knp = (kstat_named_t *) kstat_data_lookup (ksp, " brand" );
180
+ cpuinfo->Set (String::New (" model" ), data_named (knp));
181
+ (*cpus)->Set (lookup_instance, cpuinfo);
182
+ }
183
+
184
+ lookup_instance++;
185
+ }
186
+
187
+ lookup_instance = 0 ;
188
+ while (ksp = kstat_lookup (kc, " cpu" , lookup_instance, " sys" )){
189
+ cpuinfo = (*cpus)->Get (lookup_instance)->ToObject ();
190
+ cputimes = Object::New ();
191
+
192
+ if (kstat_read (kc, ksp, NULL ) == -1 ) {
193
+ cputimes->Set (String::New (" error" ), String::New (strerror (errno)));
194
+ cpuinfo->Set (String::New (" times" ), cpuinfo);
195
+ } else {
196
+ knp = (kstat_named_t *) kstat_data_lookup (ksp, " cpu_ticks_kernel" );
197
+ cputimes->Set (String::New (" system" ), data_named (knp));
198
+ knp = (kstat_named_t *) kstat_data_lookup (ksp, " cpu_ticks_user" );
199
+ cputimes->Set (String::New (" user" ), data_named (knp));
200
+ knp = (kstat_named_t *) kstat_data_lookup (ksp, " cpu_ticks_idle" );
201
+ cputimes->Set (String::New (" idle" ), data_named (knp));
202
+ knp = (kstat_named_t *) kstat_data_lookup (ksp, " intr" );
203
+ cputimes->Set (String::New (" irq" ), data_named (knp));
204
+
205
+ cpuinfo->Set (String::New (" times" ), cputimes);
206
+ }
207
+
208
+ lookup_instance++;
209
+ }
210
+
211
+ kstat_close (kc);
212
+
116
213
return 0 ;
117
214
}
118
215
@@ -126,12 +223,30 @@ double Platform::GetTotalMemory() {
126
223
return 0.0 ;
127
224
}
128
225
129
-
130
226
double Platform::GetUptime () {
131
- // http://munin-monitoring.org/attachment/ticket/419/uptime
132
- return 0.0 ;
133
- }
227
+ kstat_ctl_t *kc;
228
+ kstat_t *ksp;
229
+ kstat_named_t *knp;
230
+
231
+ long hz = sysconf (_SC_CLK_TCK);
232
+ ulong_t clk_intr;
233
+
234
+ if ((kc = kstat_open ()) == NULL )
235
+ throw " could not open kstat" ;
236
+
237
+ ksp = kstat_lookup (kc, " unix" , 0 , " system_misc" );
134
238
239
+ if (kstat_read (kc, ksp, NULL ) == -1 ) {
240
+ throw " unable to read kstat" ;
241
+ } else {
242
+ knp = (kstat_named_t *) kstat_data_lookup (ksp, " clk_intr" );
243
+ clk_intr = knp->value .ul ;
244
+ }
245
+
246
+ kstat_close (kc);
247
+
248
+ return static_cast <double >( clk_intr / hz );
249
+ }
135
250
136
251
int Platform::GetLoadAvg (Local<Array> *loads) {
137
252
return 0 ;
0 commit comments