1 /* Copyright (C) 1998 Joshua Sled
2    This file is part of LibGTop 1.0.
3 
4    Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998.
5 
6    LibGTop is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License,
9    or (at your option) any later version.
10 
11    LibGTop is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14    for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with LibGTop; see the file COPYING. If not, write to the
18    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19    Boston, MA 02110-1301, USA.
20 */
21 
22 #include <config.h>
23 #include <glibtop.h>
24 #include <glibtop/error.h>
25 #include <glibtop/mem.h>
26 
27 #include <sys/types.h>
28 #include <sys/sysctl.h>
29 
30 static const unsigned long _glibtop_sysdeps_mem =
31 (1L << GLIBTOP_MEM_TOTAL) + (1L << GLIBTOP_MEM_USED) +
32 (1L << GLIBTOP_MEM_FREE) + (1L << GLIBTOP_MEM_SHARED) +
33 (1L << GLIBTOP_MEM_BUFFER) + (1L << GLIBTOP_MEM_CACHED) +
34 (1L << GLIBTOP_MEM_USER);
35 
36 /* these are for getting the memory statistics */
37 static int pagesize;
38 
39 /* Init function. */
40 void
_glibtop_init_mem_s(glibtop * server)41 _glibtop_init_mem_s (glibtop *server)
42 {
43 	pagesize = getpagesize ();
44 
45 	server->sysdeps.mem = _glibtop_sysdeps_mem;
46 }
47 
mem_get_by_bytes(glibtop * server,const char * name)48 static gulong mem_get_by_bytes (glibtop *server, const char *name) {
49 	gulong result = 0;
50 	size_t len = sizeof (result);
51 
52 	if (sysctlbyname (name, &result, &len, NULL, 0)) {
53 		glibtop_warn_io_r (server, "sysctl (%s)", name);
54 	}
55 	return result;
56 }
57 
try_mem_get_by_bytes(glibtop * server,const char * name)58 static gulong try_mem_get_by_bytes (glibtop *server, const char *name) {
59 	gulong result = 0;
60 	size_t len = sizeof (result);
61 
62 	if (sysctlbyname (name, &result, &len, NULL, 0)) {
63 		return 0;
64 	}
65 	return result;
66 }
67 
mem_get_by_pages(glibtop * server,const char * name)68 static gulong mem_get_by_pages (glibtop *server, const char *name) {
69 	guint result = 0;
70 	size_t len = sizeof (result);
71 
72 	if (sysctlbyname (name, &result, &len, NULL, 0)) {
73 		glibtop_warn_io_r (server, "sysctl (%s)", name);
74 	}
75 	return (gulong) result * pagesize;
76 }
77 
78 void
glibtop_get_mem_s(glibtop * server,glibtop_mem * buf)79 glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
80 {
81 	gulong memtotal;
82 	gulong memactive;
83 	gulong meminactive;
84 	gulong memlaundry;
85 	gulong memwired;
86 	gulong memcached;
87 	gulong membuffer;
88 	gulong memfree;
89 	gulong zfs_arc_size;
90 
91 	memset (buf, 0, sizeof *buf);
92 
93 	memtotal = mem_get_by_bytes (server, "hw.physmem");
94 	memactive = mem_get_by_pages (server, "vm.stats.vm.v_active_count");
95 	meminactive = mem_get_by_pages (server, "vm.stats.vm.v_inactive_count");
96 	memlaundry = mem_get_by_pages (server, "vm.stats.vm.v_laundry_count");
97 	memwired = mem_get_by_pages (server, "vm.stats.vm.v_wire_count");
98 	memcached = mem_get_by_pages (server, "vm.stats.vm.v_cache_count");
99 	membuffer = mem_get_by_bytes (server, "vfs.bufspace");
100 	memfree = mem_get_by_pages (server, "vm.stats.vm.v_free_count");
101 
102 	zfs_arc_size = try_mem_get_by_bytes (server, "kstat.zfs.misc.arcstats.size");
103 
104 	buf->total = memtotal;
105 	buf->used = memtotal - memfree;
106 	buf->free = memfree;
107 	buf->shared = 0;
108 	buf->buffer = membuffer;
109 	buf->cached = memcached + zfs_arc_size;
110 	buf->locked = 0;
111 
112 	buf->user = memactive + memlaundry + memwired - zfs_arc_size;
113 
114 	buf->flags = _glibtop_sysdeps_mem;
115 }
116