~ubuntu-branches/ubuntu/edgy/wmmemload/edgy

« back to all changes in this revision

Viewing changes to src/mem_freebsd.c

  • Committer: Bazaar Package Importer
  • Author(s): Gordon Fraser
  • Date: 2003-11-02 17:32:49 UTC
  • Revision ID: james.westby@ubuntu.com-20031102173249-hlogkg7ndc3hu8sh
Tags: upstream-0.1.5
ImportĀ upstreamĀ versionĀ 0.1.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * mem_freebsd.c - module to get memory/swap usages in percent, for FreeBSD
 
3
 *
 
4
 * Copyright(c) 2001 Seiichi SATO <ssato@sh.rim.or.jp>
 
5
 *
 
6
 * licensed under the GPL
 
7
 */
 
8
 
 
9
#ifdef HAVE_CONFIG_H
 
10
#include "config.h"
 
11
#endif
 
12
 
 
13
#include <stdio.h>
 
14
#include <unistd.h>
 
15
#include <stdlib.h>
 
16
#include "mem.h"
 
17
 
 
18
#include <kvm.h>
 
19
#include <fcntl.h>
 
20
#include <sys/vmmeter.h>
 
21
#include <time.h>
 
22
 
 
23
static kvm_t *kvm_data = NULL;
 
24
static int pageshift;
 
25
static struct nlist nlst[] = { {"_cp_time"}, {"_cnt"}, {0} };
 
26
 
 
27
/* initialize function */
 
28
void mem_init(void)
 
29
{
 
30
    int pagesize = getpagesize();
 
31
    pageshift = 0;
 
32
 
 
33
    while (pagesize > 1) {
 
34
        pageshift++;
 
35
        pagesize >>= 1;
 
36
    }
 
37
 
 
38
    kvm_data = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open");
 
39
 
 
40
    if (kvm_data == NULL) {
 
41
        fprintf(stderr, "can't open kernel virtual memory");
 
42
        exit(1);
 
43
    }
 
44
    kvm_nlist(kvm_data, nlst);
 
45
 
 
46
    if (nlst[0].n_type == 0 || nlst[1].n_type == 0) {
 
47
        fprintf(stderr, "error extracting symbols");
 
48
        exit(1);
 
49
    }
 
50
    /* drop setgid & setuid (the latter should not be there really) */
 
51
    seteuid(getuid());
 
52
    setegid(getgid());
 
53
 
 
54
    if (geteuid() != getuid() || getegid() != getgid()) {
 
55
        fprintf(stderr, "unable to drop privileges");
 
56
        exit(1);
 
57
    }
 
58
}
 
59
 
 
60
 
 
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)
 
63
{
 
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;
 
73
 
 
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);
 
80
 
 
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)) {
 
89
 
 
90
        struct kvm_swap swap;
 
91
        int n;
 
92
 
 
93
        swapmax = 0;
 
94
        swapused = 0;
 
95
 
 
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;
 
100
        }
 
101
 
 
102
        swap_firsttime = 0;
 
103
        last_time_swap = cur_time;
 
104
    }
 
105
    swappgsin = vm.v_swappgsin;
 
106
    swappgsout = vm.v_swappgsout;
 
107
 
 
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
 
118
 
 
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;
 
123
 
 
124
    *per_mem = 100 * (double) mused / (double) vm.v_page_count;
 
125
    *per_swap = 100 * (double) swapused / (double) swapmax;
 
126
 
 
127
    if (*per_mem > 97) *per_mem = 100;
 
128
}