Annotation of src/usr.bin/systat/pool.c, Revision 1.2
1.2 ! canacar 1: /* $OpenBSD: pool.c,v 1.1 2008/11/02 06:23:28 canacar Exp $ */
1.1 canacar 2: /*
3: * Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: #include <sys/types.h>
19: #include <sys/param.h>
20: #include <sys/sysctl.h>
21: #include <sys/pool.h>
22: #include <errno.h>
23: #include <stdlib.h>
24:
25: #include "systat.h"
26:
27: void print_pool(void);
28: int read_pool(void);
29: void sort_pool(void);
30: int select_pool(void);
31: void showpool(int k);
32:
33: /* qsort callbacks */
34: int sort_name_callback(const void *s1, const void *s2);
1.2 ! canacar 35: int sort_req_callback(const void *s1, const void *s2);
1.1 canacar 36:
37: struct pool_info {
38: char name[32];
39: struct pool pool;
40: };
41:
42:
43: int num_pools = 0;
44: struct pool_info *pools = NULL;
45:
46:
47: field_def fields_pool[] = {
48: {"NAME", 11, 32, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
49: {"SIZE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
50: {"REQUESTS", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
51: {"FAIL", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
52: {"INUSE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
53: {"PGREQ", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
54: {"PGREL", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
55: {"NPAGE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
56: {"HIWAT", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
57: {"MINPG", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
58: {"MAXPG", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
59: {"IDLE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}
60: };
61:
62:
63: #define FIELD_ADDR(x) (&fields_pool[x])
64:
65: #define FLD_POOL_NAME FIELD_ADDR(0)
66: #define FLD_POOL_SIZE FIELD_ADDR(1)
67: #define FLD_POOL_REQS FIELD_ADDR(2)
68: #define FLD_POOL_FAIL FIELD_ADDR(3)
69: #define FLD_POOL_INUSE FIELD_ADDR(4)
70: #define FLD_POOL_PGREQ FIELD_ADDR(5)
71: #define FLD_POOL_PGREL FIELD_ADDR(6)
72: #define FLD_POOL_NPAGE FIELD_ADDR(7)
73: #define FLD_POOL_HIWAT FIELD_ADDR(8)
74: #define FLD_POOL_MINPG FIELD_ADDR(9)
75: #define FLD_POOL_MAXPG FIELD_ADDR(10)
76: #define FLD_POOL_IDLE FIELD_ADDR(11)
77:
78: /* Define views */
79: field_def *view_pool_0[] = {
80: FLD_POOL_NAME, FLD_POOL_SIZE, FLD_POOL_REQS, FLD_POOL_FAIL,
81: FLD_POOL_INUSE, FLD_POOL_PGREQ, FLD_POOL_PGREL, FLD_POOL_NPAGE,
82: FLD_POOL_HIWAT, FLD_POOL_MINPG, FLD_POOL_MAXPG, FLD_POOL_IDLE, NULL
83: };
84:
85: order_type pool_order_list[] = {
1.2 ! canacar 86: {"name", "name", 'N', sort_name_callback},
! 87: {"requests", "requests", 'Q', sort_req_callback},
1.1 canacar 88: {NULL, NULL, 0, NULL}
89: };
90:
91: /* Define view managers */
92: struct view_manager pool_mgr = {
93: "Pool", select_pool, read_pool, sort_pool, print_header,
94: print_pool, keyboard_callback, pool_order_list, pool_order_list
95: };
96:
97: field_view views_pool[] = {
98: {view_pool_0, "pool", '5', &pool_mgr},
99: {NULL, NULL, 0, NULL}
100: };
101:
102:
103: int
104: sort_name_callback(const void *s1, const void *s2)
105: {
106: struct pool_info *p1, *p2;
107: p1 = (struct pool_info *)s1;
108: p2 = (struct pool_info *)s2;
109:
1.2 ! canacar 110: return strcmp(p1->name, p2->name) * sortdir;
! 111: }
! 112:
! 113: int
! 114: sort_req_callback(const void *s1, const void *s2)
! 115: {
! 116: struct pool_info *p1, *p2;
! 117: p1 = (struct pool_info *)s1;
! 118: p2 = (struct pool_info *)s2;
! 119:
! 120: if (p1->pool.pr_nget < p2->pool.pr_nget)
! 121: return sortdir;
! 122: if (p1->pool.pr_nget > p2->pool.pr_nget)
! 123: return -sortdir;
! 124:
! 125: return sort_name_callback(s1, s2);
1.1 canacar 126: }
127:
128: void
129: sort_pool(void)
130: {
131: order_type *ordering;
132:
133: if (curr_mgr == NULL)
134: return;
135:
136: ordering = curr_mgr->order_curr;
137:
138: if (ordering == NULL)
139: return;
140: if (ordering->func == NULL)
141: return;
142: if (pools == NULL)
143: return;
144: if (num_pools <= 0)
145: return;
146:
1.2 ! canacar 147: mergesort(pools, num_pools, sizeof(struct pool_info), ordering->func);
1.1 canacar 148: }
149:
150: int
151: select_pool(void)
152: {
153: num_disp = num_pools;
154: return (0);
155: }
156:
157: int
158: read_pool(void)
159: {
160: int mib[4], np, i;
161: size_t size;
162:
163: mib[0] = CTL_KERN;
164: mib[1] = KERN_POOL;
165: mib[2] = KERN_POOL_NPOOLS;
166: size = sizeof(np);
167:
168: if (sysctl(mib, 3, &np, &size, NULL, 0) < 0) {
169: error("sysctl(npools): %s", strerror(errno));
170: return (-1);
171: }
172:
173: if (np <= 0) {
174: num_pools = 0;
175: return (0);
176: }
177:
178: if (np > num_pools || pools == NULL) {
179: struct pool_info *p = realloc(pools, sizeof(*pools) * np);
180: if (p == NULL) {
181: error("realloc: %s", strerror(errno));
182: return (-1);
183: }
184: pools = p;
185: num_pools = np;
186: }
187:
188: for (i = 0; i < num_pools; i++) {
189: mib[0] = CTL_KERN;
190: mib[1] = KERN_POOL;
191: mib[2] = KERN_POOL_POOL;
192: mib[3] = i + 1;
193: size = sizeof(struct pool);
194: if (sysctl(mib, 4, &pools[i].pool, &size, NULL, 0) < 0) {
195: error("sysctl(pool): %s", strerror(errno));
196: break;
197: }
198: mib[2] = KERN_POOL_NAME;
199: size = sizeof(pools[i].name);
200: if (sysctl(mib, 4, &pools[i].name, &size, NULL, 0) < 0) {
201: error("sysctl(pool_name): %s", strerror(errno));
202: break;
203: }
204: }
205:
206: if (i != num_pools) {
207: memset(pools, 0, sizeof(*pools) * num_pools);
208: return (-1);
209: }
210:
211: return 0;
212: }
213:
214:
215: void
216: print_pool(void)
217: {
218: int n, count = 0;
219:
220: if (pools == NULL)
221: return;
222:
223: for (n = dispstart; n < num_disp; n++) {
224: showpool(n);
225: count++;
226: if (maxprint > 0 && count >= maxprint)
227: break;
228: }
229: }
230:
231: int
232: initpool(void)
233: {
234: field_view *v;
235:
236: for (v = views_pool; v->name != NULL; v++)
237: add_view(v);
238:
239: read_pool();
240:
241: return(0);
242: }
243:
244: void
245: showpool(int k)
246: {
247: struct pool_info *p = pools + k;
248:
249: if (k < 0 || k >= num_pools)
250: return;
251:
252: print_fld_str(FLD_POOL_NAME, p->name);
253: print_fld_uint(FLD_POOL_SIZE, p->pool.pr_size);
254:
255: print_fld_size(FLD_POOL_REQS, p->pool.pr_nget);
256: print_fld_size(FLD_POOL_FAIL, p->pool.pr_nfail);
257: print_fld_ssize(FLD_POOL_INUSE, p->pool.pr_nget - p->pool.pr_nput);
258: print_fld_size(FLD_POOL_PGREQ, p->pool.pr_npagealloc);
259: print_fld_size(FLD_POOL_PGREL, p->pool.pr_npagefree);
260:
261: print_fld_size(FLD_POOL_NPAGE, p->pool.pr_npages);
262: print_fld_size(FLD_POOL_HIWAT, p->pool.pr_hiwat);
263: print_fld_size(FLD_POOL_MINPG, p->pool.pr_minpages);
264:
265: if (p->pool.pr_maxpages == UINT_MAX)
266: print_fld_str(FLD_POOL_MAXPG, "inf");
267: else
268: print_fld_size(FLD_POOL_MAXPG, p->pool.pr_maxpages);
269:
270: print_fld_size(FLD_POOL_IDLE, p->pool.pr_nidle);
271:
272: end_line();
273: }