11 #include <sys/resource.h>
12 #include <sys/sysctl.h>
13 #include <sys/vmmeter.h>
14 #include <sys/dkstat.h>
17 #include <sys/socket.h>
19 #include <net/if_mib.h>
20 #include <sys/socket.h>
23 #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
24 #define KELVTOC(x) ((x - 2732) / 10.0)
26 #if defined(i386) || defined(__i386__)
27 static unsigned int get_timer();
28 static unsigned int get_cpu_speed(void);
29 static inline unsigned long long int rdtsc(void);
31 /* cpu frequency detection code based on mplayer's one */
33 static unsigned int get_timer()
37 gettimeofday(&tv, &tz);
39 return (tv.tv_sec * 1000000 + tv.tv_usec);
42 static inline unsigned long long int rdtsc(void)
44 unsigned long long int retval;
45 __asm __volatile("rdtsc":"=A"(retval)::"memory");
49 static unsigned int get_cpu_speed(void)
51 unsigned long long int tscstart, tscstop;
52 unsigned int start, stop;
60 return ((tscstop - tscstart) / ((stop - start) / 1000.0));
65 static int getsysctl(char *name, void *ptr, size_t len)
68 if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
79 static kvm_t *kd = NULL;
80 struct ifmibdata *data = NULL;
84 static int swapmode(int *retavail, int *retfree)
87 int pagesize = getpagesize();
88 struct kvm_swap swapary[1];
89 static int kd_init = 1;
93 if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null",
94 O_RDONLY, "kvm_open")) == NULL) {
95 (void) fprintf(stderr, "Cannot read kvm.");
107 #define CONVERT(v) ((quad_t)(v) * pagesize / 1024)
109 n = kvm_getswapinfo(kd, swapary, 1, 0);
110 if (n < 0 || swapary[0].ksw_total == 0)
113 *retavail = CONVERT(swapary[0].ksw_total);
114 *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used);
116 n = (int) ((double) swapary[0].ksw_used * 100.0 /
117 (double) swapary[0].ksw_total);
123 void prepare_update()
127 /*double get_uptime() */
130 int mib[2] = { CTL_KERN, KERN_BOOTTIME };
131 struct timeval boottime;
133 size_t size = sizeof(boottime);
135 if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
136 && (boottime.tv_sec != 0)) {
138 info.uptime = now - boottime.tv_sec;
140 (void) fprintf(stderr, "Could not get uptime\n");
146 void update_meminfo()
148 int total_pages, inactive_pages, free_pages;
149 int swap_avail, swap_free;
151 int pagesize = getpagesize();
153 if (GETSYSCTL("vm.stats.vm.v_page_count", total_pages))
154 (void) fprintf(stderr,
155 "Cannot read sysctl \"vm.stats.vm.v_page_count\"");
157 if (GETSYSCTL("vm.stats.vm.v_free_count", free_pages))
158 (void) fprintf(stderr,
159 "Cannot read sysctl \"vm.stats.vm.v_free_count\"");
161 if (GETSYSCTL("vm.stats.vm.v_inactive_count", inactive_pages))
162 (void) fprintf(stderr,
163 "Cannot read sysctl \"vm.stats.vm.v_inactive_count\"");
165 info.memmax = (total_pages * pagesize) >> 10;
167 ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
170 if ((swapmode(&swap_avail, &swap_free)) >= 0) {
171 info.swapmax = swap_avail;
172 info.swap = (swap_avail - swap_free);
179 void update_net_stats()
183 long long r, t, last_recv, last_trans;
184 struct ifaddrs *ifap, *ifa;
189 delta = current_update_time - last_update_time;
193 if (getifaddrs(&ifap) < 0)
196 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
197 ns = get_net_stat((const char *) ifa->ifa_name);
199 if (ifa->ifa_flags & IFF_UP) {
200 last_recv = ns->recv;
201 last_trans = ns->trans;
203 if (ifa->ifa_addr->sa_family != AF_LINK)
206 ifd = (struct if_data *) ifa->ifa_data;
210 if (r < ns->last_read_recv)
212 ((long long) 4294967295U -
213 ns->last_read_recv) + r;
215 ns->recv += (r - ns->last_read_recv);
217 ns->last_read_recv = r;
219 if (t < ns->last_read_trans)
221 ((long long) 4294967295U -
222 ns->last_read_trans) + t;
224 ns->trans += (t - ns->last_read_trans);
226 ns->last_read_trans = t;
229 /* calculate speeds */
230 ns->recv_speed = (ns->recv - last_recv) / delta;
231 ns->trans_speed = (ns->trans - last_trans) / delta;
238 void update_total_processes()
240 /* It's easier to use kvm here than sysctl */
243 static int kd_init = 1;
247 if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null",
248 O_RDONLY, "kvm_open")) == NULL) {
249 (void) fprintf(stderr, "Cannot read kvm.");
256 kvm_getprocs(kd, KERN_PROC_ALL, 0, &n_processes);
260 info.procs = n_processes;
263 void update_running_processes()
265 static int kd_init = 1;
266 struct kinfo_proc *p;
273 kvm_open("/dev/null", "/dev/null", "/dev/null",
274 O_RDONLY, "kvm_open")) == NULL) {
275 (void) fprintf(stderr, "Cannot read kvm.");
280 p = kvm_getprocs(kd, KERN_PROC_ALL, 0, &n_processes);
281 for (i = 0; i < n_processes; i++) {
283 if (p[i].kp_proc.p_stat == SRUN)
285 if (p[i].ki_stat == SRUN)
292 info.run_procs = cnt;
295 struct cpu_load_struct {
296 unsigned long load[5];
299 struct cpu_load_struct fresh = { {0, 0, 0, 0, 0} };
300 long cpu_used, oldtotal, oldused;
302 void update_cpu_usage()
305 long cp_time[CPUSTATES];
306 size_t len = sizeof(cp_time);
308 if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0) {
309 (void) fprintf(stderr, "Cannot get kern.cp_time");
312 fresh.load[0] = cp_time[CP_USER];
313 fresh.load[1] = cp_time[CP_NICE];
314 fresh.load[2] = cp_time[CP_SYS];
315 fresh.load[3] = cp_time[CP_IDLE];
316 fresh.load[4] = cp_time[CP_IDLE];
318 used = fresh.load[0] + fresh.load[1] + fresh.load[2];
320 fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
322 if ((total - oldtotal) != 0) {
324 ((double) (used - oldused)) / (double) (total -
334 double get_i2c_info(int *fd, int arg, char *devtype, char *type)
339 void update_load_average()
344 info.loadavg[0] = (float) v[0];
345 info.loadavg[1] = (float) v[1];
346 info.loadavg[2] = (float) v[2];
349 double get_acpi_temperature(int fd)
353 if (GETSYSCTL("hw.acpi.thermal.tz0.temperature", temp)) {
354 (void) fprintf(stderr,
355 "Cannot read sysctl \"hw.acpi.thermal.tz0.temperature\"\n");
359 return KELVTOC(temp);
362 void get_battery_stuff(char *buf, unsigned int n, const char *bat)
366 if (GETSYSCTL("hw.acpi.battery.time", battime))
367 (void) fprintf(stderr,
368 "Cannot read sysctl \"hw.acpi.battery.time\"\n");
371 snprintf(buf, n, "Discharging, remaining %d:%2.2d",
372 battime / 60, battime % 60);
374 snprintf(buf, n, "Battery is charging");
378 open_i2c_sensor(const char *dev, const char *type, int n, int *div,
384 int open_acpi_temperature(const char *name)
389 char *get_acpi_ac_adapter(void)
392 char *acstate = (char *) malloc(100);
394 if (GETSYSCTL("hw.acpi.acline", state)) {
395 (void) fprintf(stderr,
396 "Cannot read sysctl \"hw.acpi.acline\"\n");
402 strcpy(acstate, "Running on AC Power");
404 strcpy(acstate, "Running on battery");
414 char *get_adt746x_cpu()
419 char *get_adt746x_fan()
426 #if defined(i386) || defined(__i386__)
430 if ((cpuspeed = (char *) malloc(16)) == NULL) {
431 CRIT_ERR("get_freq()");
435 if ((i = get_cpu_speed()) > 0) {
437 i += 50; /* for rounding */
438 snprintf(cpuspeed, 15, "%d.%d MHz", i / 1000,
441 snprintf(cpuspeed, 15, "%d MHz", i / 1000);
457 void update_wifi_stats()