wmshutdown: Bump to version 1.6
[dockapps.git] / wmSMPmon / wmSMPmon / sysinfo-solaris.c
bloba5abefe680238e650e3cf18659178a3b162fcf9f
1 /*
2 * sysinfo-solaris.c
4 * System information gathering for Solaris
5 */
7 #include "general.h"
8 #include "standards.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <strings.h>
12 #include <stdint.h>
13 #include <kstat.h>
14 #include <sys/sysinfo.h>
15 #include <sys/swap.h>
18 * The index field is for a fast lookup on the string.
19 * A -1 tells stat_data_lookup() that we need to locate
20 * the string. Once stat_data_lookup() has located the
21 * string, it will set the index of were we found it.
23 typedef struct cpu_states_info {
24 char *field_name;
25 int index;
26 } cpu_states_info_t;
28 #define CPU_STATES 4
29 static struct cpu_states_info cpu_states[CPU_STATES] = {
30 {"cpu_ticks_idle", -1},
31 {"cpu_ticks_user", -1},
32 {"cpu_ticks_kernel", -1},
33 {"cpu_ticks_wait", -1}
36 static kstat_ctl_t *kcp = NULL;
37 static kstat_t *ksp_old;
39 static uint64_t physmem = 0;
41 /* NumCPUs_DoInit returns the number of CPUs present in the system and
42 performs any initialization necessary for the sysinfo-XXX module */
43 unsigned int NumCpus_DoInit(void)
45 int smp_num_cpus;
46 int i;
48 kcp = kstat_open();
49 if (kcp == NULL)
50 exit(1);
52 physmem = sysconf(_SC_PHYS_PAGES);
53 smp_num_cpus = sysconf(_SC_NPROCESSORS_CONF);
54 if (smp_num_cpus < 1) {
55 smp_num_cpus = 1; /* SPARC glibc is buggy */
58 if (smp_num_cpus > 255) {
59 /* we don't support more than 255 CPUs (well, in fact no more
60 than two ate the moment... */
61 smp_num_cpus = 255;
64 ksp_old = malloc(smp_num_cpus * sizeof (kstat_t));
65 if (ksp_old == NULL) {
66 kstat_close(kcp);
67 fprintf(stderr, "ERROR: Can't allocate cpu load history.\n");
68 exit(1);
71 for (i = 0; i < smp_num_cpus; i++) {
72 ksp_old[i].ks_data = NULL;
73 ksp_old[i].ks_data_size = 0;
76 return smp_num_cpus;
80 * If index_ptr integer value is > -1 then the index points to the
81 * string entry in the ks_data that we are interested in. Otherwise
82 * we will need to walk the array.
84 void *stat_data_lookup(kstat_t *ksp, char *name, int *index_ptr)
86 int i;
87 int size;
88 int index;
89 char *namep, *datap;
91 switch (ksp->ks_type) {
92 case KSTAT_TYPE_NAMED:
93 size = sizeof (kstat_named_t);
94 namep = KSTAT_NAMED_PTR(ksp)->name;
95 break;
96 case KSTAT_TYPE_TIMER:
97 size = sizeof (kstat_timer_t);
98 namep = KSTAT_TIMER_PTR(ksp)->name;
99 break;
100 default:
101 errno = EINVAL;
102 return (NULL);
105 index = *index_ptr;
106 if (index >= 0) {
107 /* Short cut to the information. */
108 datap = ksp->ks_data;
109 datap = &datap[size*index];
110 return (datap);
113 /* Need to go find the string. */
114 datap = ksp->ks_data;
115 for (i = 0; i < ksp->ks_ndata; i++) {
116 if (strcmp(name, namep) == 0) {
117 *index_ptr = i;
118 return (datap);
120 namep += size;
121 datap += size;
123 errno = ENOENT;
124 return (NULL);
127 uint64_t kstat_delta(kstat_t *old, kstat_t *new, char *name, int *index)
129 kstat_named_t *knew = stat_data_lookup(new, name, index);
131 if (old && old->ks_data) {
132 kstat_named_t *kold = stat_data_lookup(old, name, index);
133 return (knew->value.ui64 - kold->value.ui64);
135 return (knew->value.ui64);
138 uint64_t cpu_ticks_delta(kstat_t *old, kstat_t *new)
140 uint64_t ticks = 0;
141 size_t i;
143 for (i = 0; i < CPU_STATES; i++) {
144 ticks += kstat_delta(old, new, cpu_states[i].field_name,
145 &cpu_states[i].index);
147 return ((ticks == 0) ? 1 : ticks);
150 int kstat_copy(const kstat_t *src, kstat_t *dst)
152 void *dst_data = NULL;
154 if (dst->ks_data && dst->ks_data_size < src->ks_data_size)
155 free((void *)dst->ks_data);
156 else
157 dst_data = dst->ks_data;
159 *dst = *src;
161 if (src->ks_data != NULL) {
162 if (dst_data)
163 dst->ks_data = dst_data;
164 else if ((dst->ks_data = malloc(src->ks_data_size)) == NULL)
165 return (-1);
166 bcopy(src->ks_data, dst->ks_data, src->ks_data_size);
167 } else {
168 if (dst_data)
169 free((void *)dst_data);
170 dst->ks_data = NULL;
171 dst->ks_data_size = 0;
173 return (0);
176 /* Get_CPU_Load returns an array of CPU loads, one for each CPU, scaled
177 to HAUTEUR. The array is defined and allocated by the main program
178 and passed to the function as '*load'. The number of CPUs present
179 is given in 'Cpu_tot' */
180 unsigned int *Get_CPU_Load(unsigned int *load, unsigned int Cpu_tot)
182 kstat_t *ksp_new;
183 double factor;
184 uint64_t cur_load;
185 int i;
187 if (kcp == NULL || ksp_old == NULL)
188 return (load);
190 for (i = 0; i < Cpu_tot; i++) {
191 if ((ksp_new = kstat_lookup(kcp, "cpu", i, "sys")) == NULL) {
192 load[i] = 0;
193 continue;
196 if (kstat_read(kcp, ksp_new, NULL) == -1) {
197 load[i] = 0;
198 continue;
201 cur_load = cpu_ticks_delta(&ksp_old[i], ksp_new);
202 factor = HAUTEUR / (double)cur_load;
204 cur_load = kstat_delta(&ksp_old[i], ksp_new,
205 cpu_states[1].field_name, &cpu_states[1].index) +
206 kstat_delta(&ksp_old[i], ksp_new, cpu_states[2].field_name,
207 &cpu_states[2].index);
208 if (ksp_old[i].ks_data) {
209 load[i] = factor * cur_load;
211 kstat_copy(ksp_new, &ksp_old[i]);
214 return (load);
217 /* return current memory/swap usage on a scale from 0-100 */
218 unsigned int Get_Memory(void)
220 kstat_t *ksp_new;
221 static vminfo_t *vm_new = NULL;
222 static vminfo_t *vm_old = NULL;
223 vminfo_t *vm_swap;
224 static uint64_t freemem = 0;
226 if ((ksp_new = kstat_lookup(kcp, "unix", 0, "vminfo")) == NULL) {
227 return (0);
230 if (vm_new == NULL && (vm_new = malloc(sizeof (vminfo_t))) == NULL) {
231 return (0);
234 if (kstat_read(kcp, ksp_new, vm_new) == -1) {
235 return (0);
238 if (vm_old != NULL) {
239 uint64_t step = vm_new->updates - vm_old->updates;
241 if (step > 0) {
242 freemem = (vm_new->freemem - vm_old->freemem) / step;
246 vm_swap = vm_new;
247 vm_new = vm_old;
248 vm_old = vm_swap;
250 if (vm_new == NULL)
251 return (0);
253 return (100 * (physmem - freemem) / physmem);
256 unsigned int Get_Swap(void)
258 struct anoninfo ai;
260 if (swapctl(SC_AINFO, &ai) == -1) {
261 return (0);
264 return (100 * (ai.ani_max - ai.ani_free) / ai.ani_max);