[lttng-dev] [PATCH lttng-ust] compat: work around broken _SC_NPROCESSORS_CONF on MUSL libc
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Wed Mar 20 11:49:53 EDT 2019
Merged into lttng-ust master, 2.11, 2.10, 2.9, thanks!
Mathieu
----- On Mar 20, 2019, at 11:07 AM, Michael Jeanson mjeanson at efficios.com wrote:
> On MUSL libc the _SC_NPROCESSORS_CONF sysconf will report the number of
> CPUs allocated to the task based on the affinity mask instead of the
> total number of CPUs configured on the system.
>
> Signed-off-by: Michael Jeanson <mjeanson at efficios.com>
> ---
> libringbuffer/smp.c | 66 +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 66 insertions(+)
>
> diff --git a/libringbuffer/smp.c b/libringbuffer/smp.c
> index 9e7114be..656a75da 100644
> --- a/libringbuffer/smp.c
> +++ b/libringbuffer/smp.c
> @@ -2,6 +2,7 @@
> * libringbuffer/smp.c
> *
> * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> + * Copyright (C) 2019 Michael Jeanson <mjeanson at efficios.com>
> *
> * This library is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public
> @@ -26,6 +27,7 @@
>
> int __num_possible_cpus;
>
> +#if (defined(__GLIBC__) || defined( __UCLIBC__))
> void _get_num_possible_cpus(void)
> {
> int result;
> @@ -43,3 +45,67 @@ void _get_num_possible_cpus(void)
> return;
> __num_possible_cpus = result;
> }
> +
> +#else
> +
> +/*
> + * The MUSL libc implementation of the _SC_NPROCESSORS_CONF sysconf does not
> + * return the number of configured CPUs in the system but relies on the cpu
> + * affinity mask of the current task.
> + *
> + * So instead we use a strategy similar to GLIBC's, counting the cpu
> + * directories in "/sys/devices/system/cpu" and fallback on the value from
> + * sysconf if it fails.
> + */
> +
> +#include <dirent.h>
> +#include <limits.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/types.h>
> +
> +#define __max(a,b) ((a)>(b)?(a):(b))
> +
> +void _get_num_possible_cpus(void)
> +{
> + int result, count = 0;
> + DIR *cpudir;
> + struct dirent *entry;
> +
> + cpudir = opendir("/sys/devices/system/cpu");
> + if (cpudir == NULL)
> + goto end;
> +
> + /*
> + * Count the number of directories named "cpu" followed by and
> + * integer. This is the same strategy as glibc uses.
> + */
> + while ((entry = readdir(cpudir))) {
> + if (entry->d_type == DT_DIR &&
> + strncmp(entry->d_name, "cpu", 3) == 0) {
> +
> + char *endptr;
> + unsigned long cpu_num;
> +
> + cpu_num = strtoul(entry->d_name + 3, &endptr, 10);
> + if ((cpu_num < ULONG_MAX) && (endptr != entry->d_name + 3)
> + && (*endptr == '\0')) {
> + count++;
> + }
> + }
> + }
> +
> +end:
> + /*
> + * Get the sysconf value as a fallback. Keep the highest number.
> + */
> + result = __max(sysconf(_SC_NPROCESSORS_CONF), count);
> +
> + /*
> + * If both methods failed, don't store the value.
> + */
> + if (result < 1)
> + return;
> + __num_possible_cpus = result;
> +}
> +#endif
> --
> 2.17.1
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list