2 * Contains FreeBSD specific stuff
13 #include <sys/param.h>
14 #include <sys/types.h>
16 #include <sys/resource.h>
17 #include <sys/sysctl.h>
18 #include <sys/vmmeter.h>
19 #include <sys/dkstat.h>
22 #include <sys/socket.h>
24 #include <net/if_mib.h>
25 #include <sys/socket.h>
30 #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
31 #define KELVTOC(x) ((x - 2732) / 10.0)
33 #if defined(i386) || defined(__i386__)
34 static unsigned int get_timer();
35 static unsigned int get_cpu_speed(void);
36 static inline unsigned long long int rdtsc(void);
38 /* cpu frequency detection code based on mplayer's one */
40 static unsigned int get_timer()
44 gettimeofday(&tv, &tz);
46 return (tv.tv_sec * 1000000 + tv.tv_usec);
49 static inline unsigned long long int rdtsc(void)
51 unsigned long long int retval;
52 __asm __volatile("rdtsc":"=A"(retval)::"memory");
56 static unsigned int get_cpu_speed(void)
58 unsigned long long int tscstart, tscstop;
59 unsigned int start, stop;
67 return ((tscstop - tscstart) / ((stop - start) / 1000.0));
71 static int getsysctl(char *name, void *ptr, size_t len)
74 if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
85 static kvm_t *kd = NULL;
86 struct ifmibdata *data = NULL;
89 static int swapmode(int *retavail, int *retfree)
92 int pagesize = getpagesize();
93 struct kvm_swap swapary[1];
94 static int kd_init = 1;
98 if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null",
99 O_RDONLY, "kvm_open")) == NULL) {
100 (void) fprintf(stderr, "Cannot read kvm.");
112 #define CONVERT(v) ((quad_t)(v) * pagesize / 1024)
114 n = kvm_getswapinfo(kd, swapary, 1, 0);
115 if (n < 0 || swapary[0].ksw_total == 0)
118 *retavail = CONVERT(swapary[0].ksw_total);
119 *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used);
121 n = (int) ((double) swapary[0].ksw_used * 100.0 /
122 (double) swapary[0].ksw_total);
127 void prepare_update()
133 int mib[2] = { CTL_KERN, KERN_BOOTTIME };
134 struct timeval boottime;
136 size_t size = sizeof(boottime);
138 if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
139 && (boottime.tv_sec != 0)) {
141 info.uptime = now - boottime.tv_sec;
143 (void) fprintf(stderr, "Could not get uptime\n");
148 void update_meminfo()
150 int total_pages, inactive_pages, free_pages;
151 int swap_avail, swap_free;
153 int pagesize = getpagesize();
155 if (GETSYSCTL("vm.stats.vm.v_page_count", total_pages))
156 (void) fprintf(stderr,
157 "Cannot read sysctl \"vm.stats.vm.v_page_count\"");
159 if (GETSYSCTL("vm.stats.vm.v_free_count", free_pages))
160 (void) fprintf(stderr,
161 "Cannot read sysctl \"vm.stats.vm.v_free_count\"");
163 if (GETSYSCTL("vm.stats.vm.v_inactive_count", inactive_pages))
164 (void) fprintf(stderr,
165 "Cannot read sysctl \"vm.stats.vm.v_inactive_count\"");
167 info.memmax = (total_pages * pagesize) >> 10;
169 ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
172 if ((swapmode(&swap_avail, &swap_free)) >= 0) {
173 info.swapmax = swap_avail;
174 info.swap = (swap_avail - swap_free);
181 void update_net_stats()
185 long long r, t, last_recv, last_trans;
186 struct ifaddrs *ifap, *ifa;
191 delta = current_update_time - last_update_time;
195 if (getifaddrs(&ifap) < 0)
198 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
199 ns = get_net_stat((const char *) ifa->ifa_name);
201 if (ifa->ifa_flags & IFF_UP) {
202 last_recv = ns->recv;
203 last_trans = ns->trans;
205 if (ifa->ifa_addr->sa_family != AF_LINK)
208 ifd = (struct if_data *) ifa->ifa_data;
212 if (r < ns->last_read_recv)
214 ((long long) 4294967295U -
215 ns->last_read_recv) + r;
217 ns->recv += (r - ns->last_read_recv);
219 ns->last_read_recv = r;
221 if (t < ns->last_read_trans)
223 ((long long) 4294967295U -
224 ns->last_read_trans) + t;
226 ns->trans += (t - ns->last_read_trans);
228 ns->last_read_trans = t;
231 /* calculate speeds */
232 ns->recv_speed = (ns->recv - last_recv) / delta;
233 ns->trans_speed = (ns->trans - last_trans) / delta;
240 void update_total_processes()
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()
424 float get_freq_dynamic()
426 /* TODO: implement */
432 /* First, try to obtain CPU frequency via dev.cpu.0.freq sysctl
433 * (cpufreq(4)). If failed, do i386 magic. */
436 if (GETSYSCTL("dev.cpu.0.freq", freq) == 0)
439 #if defined(i386) || defined(__i386__)
443 if ((i = get_cpu_speed()) > 0) {
444 return (float)(i / 1000);
458 void update_wifi_stats()