1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-01 10:06:57 +03:00

Linux: implement getloadavg(3) using sysinfo(2)

Signed-off-by: Cristian Rodríguez <crrodriguez@opensuse.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
Cristian Rodríguez
2021-08-06 15:17:48 -04:00
committed by Adhemerval Zanella
parent f3c6c19038
commit b5c8a3aa82

View File

@ -1,4 +1,4 @@
/* Get system load averages. Linux (/proc/loadavg) version. /* Get system load averages. Linux version.
Copyright (C) 1999-2021 Free Software Foundation, Inc. Copyright (C) 1999-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
@ -16,53 +16,31 @@
License along with the GNU C Library; if not, see License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */ <https://www.gnu.org/licenses/>. */
#include <errno.h> #include <array_length.h>
#include <fcntl.h> #include <sys/param.h>
#include <locale.h> #include <sys/sysinfo.h>
#include <stdlib.h>
#include <unistd.h>
#include <not-cancel.h>
/* Put the 1 minute, 5 minute and 15 minute load averages /* Put the 1 minute, 5 minute and 15 minute load averages
into the first NELEM elements of LOADAVG. into the first NELEM elements of LOADAVG.
Return the number written (never more than 3, but may be less than NELEM), Return the number written (never more than 3, but may be less than NELEM),
or -1 if an error occurred. */ or -1 if an error occurred. */
#define CLAMP(v, lo, hi) MIN (MAX (v, lo), hi)
#define SYSINFO_LOADS_SCALE (1 << SI_LOAD_SHIFT)
int int
getloadavg (double loadavg[], int nelem) getloadavg (double loadavg[], int nelem)
{ {
int fd; struct sysinfo info;
fd = __open_nocancel ("/proc/loadavg", O_RDONLY); if (__sysinfo (&info) != 0)
if (fd < 0)
return -1; return -1;
else
{
char buf[65], *p;
ssize_t nread;
int i;
nread = __read_nocancel (fd, buf, sizeof buf - 1); nelem = CLAMP (nelem, 0, array_length (info.loads));
__close_nocancel_nostatus (fd);
if (nread <= 0)
return -1;
buf[nread - 1] = '\0';
if (nelem > 3) for (int i = 0; i < nelem; i++)
nelem = 3; loadavg[i] = (double) info.loads[i] / SYSINFO_LOADS_SCALE;
p = buf;
for (i = 0; i < nelem; ++i)
{
char *endp;
loadavg[i] = __strtod_l (p, &endp, _nl_C_locobj_ptr);
if (endp == p)
/* This should not happen. The format of /proc/loadavg
must have changed. Don't return with what we have,
signal an error. */
return -1;
p = endp;
}
return i; return nelem;
}
} }