1 /* Copyright (c) 1993-2002
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Copyright (c) 1987 Oliver Laumann
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, see
18 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 ****************************************************************
24 #include <sys/types.h>
27 # include <sys/fixpoint.h>
30 /* mach stuff included here to prevent index macro conflict */
32 # include <sys/version.h>
33 # if KERNEL_MAJOR_VERSION > 2
34 # include <mach/mach.h>
47 static int GetLoadav
__P((void));
49 static LOADAV_TYPE loadav
[LOADAV_NUM
];
54 /***************************************************************/
56 #if defined(linux) && !defined(LOADAV_DONE)
59 * This is the easy way. It relies in /proc being mounted.
60 * For the big and ugly way refer to previous screen version.
76 if ((fp
= secfopen("/proc/loadavg", "r")) == NULL
)
79 fgets(buf
, sizeof(buf
), fp
);
81 /* can't use fscanf because the decimal point symbol depends on
82 * the locale but the kernel uses always '.'.
85 for (i
= 0; i
< (LOADAV_NUM
> 3 ? 3 : LOADAV_NUM
); i
++)
96 else if (*s
>= '0' && *s
<= '9')
98 d
= d
* 10 + (*s
- '0');
106 loadav
[i
] = e
? d
/ e
: d
;
112 /***************************************************************/
114 #if defined(LOADAV_GETLOADAVG) && !defined(LOADAV_DONE)
125 return getloadavg(loadav
, LOADAV_NUM
);
129 /***************************************************************/
131 #if defined(apollo) && !defined(LOADAV_DONE)
142 proc1_$
get_loadav(loadav
);
147 /***************************************************************/
149 #if defined(NeXT) && !defined(LOADAV_DONE)
152 static processor_set_t default_set
;
159 error
= processor_set_default(host_self(), &default_set
);
160 if (error
!= KERN_SUCCESS
)
161 mach_error("Error calling processor_set_default", error
);
169 unsigned int info_count
;
170 struct processor_set_basic_info info
;
173 info_count
= PROCESSOR_SET_BASIC_INFO_COUNT
;
174 if (processor_set_info(default_set
, PROCESSOR_SET_BASIC_INFO
, &host
, (processor_set_info_t
)&info
, &info_count
) != KERN_SUCCESS
)
176 loadav
[0] = (float)info
.load_average
/ LOAD_SCALE
;
181 /***************************************************************/
183 #if defined(sun) && defined(SVR4) && !defined(LOADAV_DONE)
188 static kstat_ctl_t
*kc
;
193 loadok
= (kc
= kstat_open()) != 0;
200 kstat_named_t
*avgs
[3];
203 kstat_chain_update(kc
);
204 if ((ks
= kstat_lookup(kc
, "unix", -1, "system_misc")) == 0 || kstat_read(kc
, ks
, (void *)0) == -1)
206 avgs
[0] = kstat_data_lookup(ks
, "avenrun_1min");
207 avgs
[1] = kstat_data_lookup(ks
, "avenrun_5min");
208 avgs
[2] = kstat_data_lookup(ks
, "avenrun_15min");
209 for (i
= 0; i
< 3; i
++)
211 if (avgs
[i
] == 0 || avgs
[i
]->data_type
!= KSTAT_DATA_ULONG
)
213 loadav
[i
] = avgs
[i
]->value
.ul
;
220 /***************************************************************/
222 #if defined(__osf__) && defined(__alpha) && !defined(LOADAV_DONE)
225 struct rtentry
; struct mbuf
; /* shut up gcc on OSF/1 4.0 */
226 #include <sys/table.h>
237 struct tbl_loadavg tbl
;
240 if (table(TBL_LOADAVG
, 0, &tbl
, 1, sizeof(struct tbl_loadavg
)) != 1)
246 for (i
= 0; i
< LOADAV_NUM
; i
++)
247 loadav
[i
] = (double) tbl
.tl_avenrun
.l
[i
] / tbl
.tl_lscale
;
252 for (i
= 0; i
< LOADAV_NUM
; i
++)
253 loadav
[i
] = tbl
.tl_avenrun
.d
[i
];
259 /***************************************************************/
261 #if !defined(LOADAV_DONE)
263 * The old fashion way: open kernel and read avenrun
265 * Header File includes
273 # ifndef NLIST_DECLARED
274 extern int nlist
__P((char *, struct nlist
*));
277 #ifdef LOADAV_USE_NLIST64
278 # define nlist nlist64
281 static struct nlist nl
[2];
285 # define nlist(u,l) knlist(l,1,sizeof(*l))
291 debug("Init Kmem...\n");
292 if ((kmemf
= open("/dev/kmem", O_RDONLY
)) == -1)
294 # if !defined(_AUX_SOURCE) && !defined(AUX)
295 # ifdef NLIST_NAME_UNION
296 nl
[0].n_un
.n_name
= LOADAV_AVENRUN
;
298 nl
[0].n_name
= LOADAV_AVENRUN
;
301 strncpy(nl
[0].n_name
, LOADAV_AVENRUN
, sizeof(nl
[0].n_name
));
303 debug2("Searching in %s for %s\n", LOADAV_UNIX
, nl
[0].n_name
);
304 nlist(LOADAV_UNIX
, nl
);
305 if (nl
[0].n_value
== 0)
310 # if 0 /* no longer needed (Al.Smith@aeschi.ch.eu.org) */
312 nl
[0].n_value
&= (unsigned long)-1 >> 1; /* clear upper bit */
315 debug1("AvenrunSym found (0x%lx)!!\n", nl
[0].n_value
);
322 if (lseek(kmemf
, (off_t
) nl
[0].n_value
, 0) == (off_t
)-1)
324 if (read(kmemf
, (char *) loadav
, sizeof(loadav
)) != sizeof(loadav
))
330 /***************************************************************/
333 #define FIX_TO_DBL(l) ((double)(l) / LOADAV_SCALE)
344 for (i
= 0; i
< j
; i
++)
346 sprintf(p
, " %2.2f" + !i
, FIX_TO_DBL(loadav
[i
]));