|
1 /* |
|
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. |
|
3 * |
|
4 * U.S. Government Rights - Commercial software. Government users are subject |
|
5 * to the Sun Microsystems, Inc. standard license agreement and applicable |
|
6 * provisions of the FAR and its supplements. |
|
7 * |
|
8 * |
|
9 * This distribution may include materials developed by third parties. Sun, |
|
10 * Sun Microsystems, the Sun logo and Solaris are trademarks or registered |
|
11 * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. |
|
12 * |
|
13 */ |
|
14 |
|
15 |
|
16 #if 0 |
|
17 #include <stdio.h> |
|
18 #endif |
|
19 #include <kstat.h> |
|
20 #include <sys/types.h> |
|
21 #include <sys/swap.h> |
|
22 #include <vm/anon.h> |
|
23 #include <unistd.h> |
|
24 #include <string.h> |
|
25 |
|
26 #define ONEMB 1048576 |
|
27 |
|
28 extern int first_time; |
|
29 extern kstat_ctl_t *kc; |
|
30 extern void initialize_everything(); |
|
31 |
|
32 static ulong_t page_size = 0; |
|
33 |
|
34 /* |
|
35 * Return value of named statistic for given kstat_named kstat. |
|
36 * Return 0 if named statistic is not in list. |
|
37 */ |
|
38 static u_longlong_t |
|
39 kstat_named_value(kstat_t *ksp, char *name) |
|
40 { |
|
41 kstat_named_t *knp; |
|
42 |
|
43 if (ksp == NULL) |
|
44 return (0); |
|
45 |
|
46 knp = kstat_data_lookup(ksp, name); |
|
47 if (knp != NULL) { |
|
48 switch (knp->data_type) { |
|
49 case KSTAT_DATA_UINT64: |
|
50 return (knp->value.ull); |
|
51 case KSTAT_DATA_UINT32: |
|
52 default: |
|
53 return (knp->value.ul); |
|
54 } |
|
55 } else { |
|
56 return (0); |
|
57 } |
|
58 } |
|
59 |
|
60 int |
|
61 krgetmemusage (int *mem_avail, int *mem_inuse, int *mem_free) |
|
62 { |
|
63 int intfactor; |
|
64 |
|
65 if ((first_time) || (!kc)) |
|
66 initialize_everything(); |
|
67 |
|
68 if (page_size == 0) |
|
69 page_size = sysconf(_SC_PAGESIZE); |
|
70 |
|
71 /* do ops differently dependent on pagesize to avoid overflow |
|
72 * note that: pagesize & ONEMB will both be powers of 2 therefore |
|
73 * the bigger one will be exactly divisible by the smaller |
|
74 */ |
|
75 if(page_size < ONEMB){ |
|
76 intfactor = ONEMB/page_size; |
|
77 |
|
78 /* The following line is commented out because the value returned is less |
|
79 than the actual number of pages in the machine. More research has got be |
|
80 done about what is the value that kstat returns |
|
81 *mem_avail = kstat_named_value(ksp, "physmem") / intfactor; */ |
|
82 |
|
83 *mem_avail = sysconf(_SC_PHYS_PAGES) / intfactor; |
|
84 *mem_free = sysconf(_SC_AVPHYS_PAGES) / intfactor; |
|
85 *mem_inuse = *mem_avail - *mem_free; |
|
86 } |
|
87 else{ /* page_size >= ONEMB */ |
|
88 intfactor = page_size/ONEMB; |
|
89 /* *mem_avail = kstat_named_value(ksp, "physmem") * intfactor; */ |
|
90 *mem_avail = sysconf(_SC_PHYS_PAGES) * intfactor; |
|
91 *mem_free = sysconf(_SC_AVPHYS_PAGES) * intfactor; |
|
92 *mem_inuse = *mem_avail - *mem_free; |
|
93 } |
|
94 return 0; |
|
95 } |
|
96 |
|
97 |
|
98 u_int convert_ticks_to_bytes(u_int input) { |
|
99 |
|
100 static float factor = -1; |
|
101 |
|
102 if (factor == -1) |
|
103 factor = (float)(sysconf(_SC_PAGESIZE))/1024;/* in KB */ |
|
104 return (input*(u_int)factor); |
|
105 } |
|
106 |
|
107 |
|
108 int |
|
109 krgetswapusage (int *swap_avail, int *swap_resv, int *swap_alloc, int *swap_used, int *swap_total) |
|
110 { |
|
111 |
|
112 struct anoninfo ai; |
|
113 |
|
114 if (swapctl(SC_AINFO, &ai) == -1) { |
|
115 /* perror("Error in swapctl ..............."); */ |
|
116 return (-1); |
|
117 } |
|
118 *swap_avail = convert_ticks_to_bytes(ai.ani_max - ai.ani_resv); |
|
119 *swap_resv = convert_ticks_to_bytes(ai.ani_resv - ai.ani_max + ai.ani_free); |
|
120 *swap_alloc = convert_ticks_to_bytes(ai.ani_max - ai.ani_free); |
|
121 *swap_used = convert_ticks_to_bytes(ai.ani_resv); |
|
122 *swap_total = (*swap_used) + (*swap_avail); |
|
123 return 0; |
|
124 } |
|
125 |
|
126 /* |
|
127 * returns information about the "kmem_cache" buffer of name |
|
128 * "cache_name". If the last character is an asterisk, it |
|
129 * returns the sum of the statistics over all caches that |
|
130 * match. |
|
131 */ |
|
132 int |
|
133 krgetkmemdetail (const char *cache_name, int *alloc, int *alloc_fail, int *buf_size, int *buf_avail, int *buf_total, int *buf_max) |
|
134 { |
|
135 kstat_t *ksp; |
|
136 int length = 0; |
|
137 |
|
138 if ((first_time) || (!kc)) |
|
139 initialize_everything(); |
|
140 |
|
141 if (cache_name[strlen(cache_name) - 1] == '*') |
|
142 length = strlen(cache_name) - 1; |
|
143 else |
|
144 length = 256; |
|
145 |
|
146 *alloc = 0; |
|
147 *alloc_fail = 0; |
|
148 *buf_size = 0; |
|
149 *buf_avail = 0; |
|
150 *buf_total = 0; |
|
151 *buf_max = 0; |
|
152 |
|
153 for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { |
|
154 if (strcmp(ksp->ks_class, "kmem_cache") != 0) |
|
155 continue; |
|
156 if (strncmp(ksp->ks_name, cache_name, length) != 0) |
|
157 continue; |
|
158 if (kstat_read(kc, ksp, NULL) == -1) |
|
159 return -1; |
|
160 *alloc += kstat_named_value(ksp, "alloc"); |
|
161 *alloc_fail += kstat_named_value(ksp, "alloc_fail"); |
|
162 *buf_size += kstat_named_value(ksp, "buf_size"); |
|
163 *buf_avail += kstat_named_value(ksp, "buf_avail"); |
|
164 *buf_total += kstat_named_value(ksp, "buf_total"); |
|
165 *buf_max += kstat_named_value(ksp, "buf_max"); |
|
166 } |
|
167 return 0; |
|
168 |
|
169 } |
|
170 |