[PATCH 3/4] linux: Use /sys/devices/system/cpu/possible on __get_nprocs_conf
Adhemerval Zanella
adhemerval.zanella@linaro.org
Wed May 5 16:53:06 GMT 2021
Ping.
On 29/03/2021 15:25, Adhemerval Zanella wrote:
> Instead of iterate over all the cpu in the sysfs folder. It consumes
> slight less resources on large system (which might require extra
> getdents call) and memory (a limited stack buffer instead a large
> malloced one for opendir).
>
> Checked on x86_64-linux-gnu, aarch64-linux-gnu, and
> powerpc64le-linux-gnu.
> ---
> sysdeps/unix/sysv/linux/getsysstats.c | 51 +++++++++++++++------------
> 1 file changed, 29 insertions(+), 22 deletions(-)
>
> diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
> index f8a4a31d1b..5069951246 100644
> --- a/sysdeps/unix/sysv/linux/getsysstats.c
> +++ b/sysdeps/unix/sysv/linux/getsysstats.c
> @@ -17,7 +17,8 @@
> License along with the GNU C Library; if not, see
> <https://www.gnu.org/licenses/>. */
>
> -#include <dirent.h>
> +#include <ctype.h>
> +#include <intprops.h>
> #include <not-cancel.h>
> #include <scratch_buffer.h>
> #include <stdio.h>
> @@ -63,33 +64,39 @@ weak_alias (__get_nprocs, get_nprocs)
> int
> __get_nprocs_conf (void)
> {
> - /* XXX Here will come a test for the new system call. */
> + int result = 1;
>
> /* Try to use the sysfs filesystem. It has actual information about
> online processors. */
> - DIR *dir = __opendir ("/sys/devices/system/cpu");
> - if (dir != NULL)
> + int fd = __open64_nocancel ("/sys/devices/system/cpu/possible", O_RDONLY);
> + if (fd != -1)
> {
> - int count = 0;
> - struct dirent64 *d;
> -
> - while ((d = __readdir64 (dir)) != NULL)
> - /* NB: the sysfs has d_type support. */
> - if (d->d_type == DT_DIR && strncmp (d->d_name, "cpu", 3) == 0)
> - {
> - char *endp;
> - unsigned long int nr = strtoul (d->d_name + 3, &endp, 10);
> - if (nr != ULONG_MAX && endp != d->d_name + 3 && *endp == '\0')
> - ++count;
> - }
> -
> - __closedir (dir);
> -
> - return count;
> + /* The entry is in the form of '[cpuX]-[cpuY]'. */
> + char buf[2 * INT_STRLEN_BOUND (unsigned int) + 1];
> +
> + ssize_t n = __read_nocancel (fd, buf, sizeof (buf));
> + if (n > 0)
> + {
> + buf[n] = '\0';
> +
> + /* Start on the right, to find highest node number. */
> + int m = 1;
> + while (--n)
> + {
> + if ((buf[n] == ',') || (buf[n] == '-'))
> + break;
> + /* Ignore '\n' */
> + if (! isdigit (buf[n]))
> + continue;
> + result += (buf[n] - '0') * m;
> + m *= 10;
> + }
> + }
> +
> + __close_nocancel (fd);
> + return result + 1;
> }
>
> - int result = 1;
> -
> #ifdef GET_NPROCS_CONF_PARSER
> /* If we haven't found an appropriate entry return 1. */
> FILE *fp = fopen ("/proc/cpuinfo", "rce");
>
More information about the Libc-alpha
mailing list