wmbattery: Remove Debian-specific distribution and urgency from ChangeLog.
[dockapps.git] / wmmemload / src / mem_freebsd.c
blob00d10b1493538e7380003b94d9c4528a08531dae
1 /*
2 * mem_freebsd.c - module to get memory/swap usages in percent, for FreeBSD
4 * Copyright(c) 2001 Seiichi SATO <ssato@sh.rim.or.jp>
6 * licensed under the GPL
7 */
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include "mem.h"
18 #include <kvm.h>
19 #include <fcntl.h>
20 #include <sys/vmmeter.h>
21 #include <time.h>
23 static kvm_t *kvm_data = NULL;
24 static int pageshift;
25 static struct nlist nlst[] = { {"_cp_time"}, {"_cnt"}, {0} };
27 /* initialize function */
28 void mem_init(void)
30 int pagesize = getpagesize();
31 pageshift = 0;
33 while (pagesize > 1) {
34 pageshift++;
35 pagesize >>= 1;
38 kvm_data = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open");
40 if (kvm_data == NULL) {
41 fprintf(stderr, "can't open kernel virtual memory");
42 exit(1);
44 kvm_nlist(kvm_data, nlst);
46 if (nlst[0].n_type == 0 || nlst[1].n_type == 0) {
47 fprintf(stderr, "error extracting symbols");
48 exit(1);
50 /* drop setgid & setuid (the latter should not be there really) */
51 seteuid(getuid());
52 setegid(getgid());
54 if (geteuid() != getuid() || getegid() != getgid()) {
55 fprintf(stderr, "unable to drop privileges");
56 exit(1);
61 /* return mem/swap usage in percent 0 to 100 */
62 void mem_getusage(int *per_mem, int *per_swap, const struct mem_options *opts)
64 struct vmmeter vm;
65 int bufspace;
66 static int swap_firsttime = 1;
67 static int swappgsin = -1;
68 static int swappgsout = -1;
69 static int swapmax = 0, swapused = 0;
70 time_t cur_time;
71 static time_t last_time_swap = 0;
72 u_int mused;
74 /* get mem usage */
75 if (kvm_read(kvm_data, nlst[0].n_value, &bufspace, sizeof(bufspace)) !=
76 sizeof(bufspace))
77 exit(1);
78 if (kvm_read(kvm_data, nlst[1].n_value, &vm, sizeof(vm)) != sizeof(vm))
79 exit(1);
81 /* get swap usage */
82 /* only calculate when first time or when changes took place */
83 /* do not call it more than 1 time per 2 seconds */
84 /* otherwise it can eat up to 50% of CPU time on heavy swap activity */
85 cur_time = time(NULL);
86 if (swap_firsttime ||
87 (((vm.v_swappgsin > swappgsin) || (vm.v_swappgsout > swappgsout))
88 && cur_time > last_time_swap + 1)) {
90 struct kvm_swap swap;
91 int n;
93 swapmax = 0;
94 swapused = 0;
96 n = kvm_getswapinfo(kvm_data, &swap, 1, 0);
97 if (n >= 0 && swap.ksw_total != 0) {
98 swapmax = swap.ksw_total;
99 swapused = swap.ksw_used;
102 swap_firsttime = 0;
103 last_time_swap = cur_time;
105 swappgsin = vm.v_swappgsin;
106 swappgsout = vm.v_swappgsout;
108 #ifdef DEBUG
109 printf ("-------------------\n");
110 printf ("total:%10d\n", vm.v_page_count * vm.v_page_size);
111 printf ("free :%10d\n", vm.v_free_count * vm.v_page_size);
112 printf ("act :%10d\n", vm.v_active_count * vm.v_page_size);
113 printf ("inact:%10d\n", vm.v_inactive_count * vm.v_page_size);
114 printf ("wired:%10d\n", vm.v_wire_count * vm.v_page_size);
115 printf ("cache:%10d\n", vm.v_cache_count * vm.v_page_size);
116 printf ("-------------------\n");
117 #endif
119 /* calc mem/swap usage in percent */
120 mused = vm.v_page_count - vm.v_free_count;
121 if (opts->ignore_wired) mused -= vm.v_wire_count;
122 if (opts->ignore_cached) mused -= vm.v_cache_count;
124 *per_mem = 100 * (double) mused / (double) vm.v_page_count;
125 *per_swap = 100 * (double) swapused / (double) swapmax;
127 if (*per_mem > 97) *per_mem = 100;