From: Amaury Denoyelle Date: Wed, 14 Apr 2021 13:03:51 +0000 (+0200) Subject: MINOR: cpuset: define a platform-independent cpuset type X-Git-Tag: v2.4-dev17~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f75c640f7b58de309daa2a95d99abd10ee5be494;p=thirdparty%2Fhaproxy.git MINOR: cpuset: define a platform-independent cpuset type This module can be used to manipulate a cpu sets in a platform agnostic way. Use the type cpu_set_t/cpuset_t if available on the platform, or fallback to unsigned long, which limits de facto the maximum cpu index to LONGBITS. --- diff --git a/Makefile b/Makefile index 3c9109b793..46ae734d92 100644 --- a/Makefile +++ b/Makefile @@ -563,6 +563,10 @@ ifneq ($(USE_BACKTRACE),) OPTIONS_LDFLAGS += -Wl,$(if $(EXPORT_SYMBOL),$(EXPORT_SYMBOL),--export-dynamic) endif +ifneq ($(USE_CPU_AFFINITY),) +OPTIONS_OBJS += src/cpuset.o +endif + ifneq ($(USE_OPENSSL),) SSL_INC = SSL_LIB = diff --git a/include/haproxy/cpuset-t.h b/include/haproxy/cpuset-t.h new file mode 100644 index 0000000000..f1c532d2e2 --- /dev/null +++ b/include/haproxy/cpuset-t.h @@ -0,0 +1,40 @@ +#define _GNU_SOURCE +#include + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) +#include +#ifdef __FreeBSD__ +#include +#include +#endif +#endif + +#ifndef _HAPROXY_CPUSET_T_H +#define _HAPROXY_CPUSET_T_H + +#if defined(__linux__) || defined(__DragonFly__) + +# define CPUSET_REPR cpu_set_t +# define CPUSET_USE_CPUSET + +#elif defined(__FreeBSD__) || defined(__NetBSD__) + +# define CPUSET_REPR cpuset_t +# define CPUSET_USE_FREEBSD_CPUSET + +#elif defined(__APPLE__) + +# define CPUSET_REPR unsigned long +# define CPUSET_USE_ULONG + +#else + +# error "No cpuset support implemented on this platform" + +#endif + +struct hap_cpuset { + CPUSET_REPR cpuset; +}; + +#endif /* _HAPROXY_CPUSET_T_H */ diff --git a/include/haproxy/cpuset.h b/include/haproxy/cpuset.h new file mode 100644 index 0000000000..f6cea43255 --- /dev/null +++ b/include/haproxy/cpuset.h @@ -0,0 +1,42 @@ +#ifndef _HAPROXY_CPUSET_H +#define _HAPROXY_CPUSET_H + +#include + +/* Unset all indexes in . + */ +void ha_cpuset_zero(struct hap_cpuset *set); + +/* Set index in if not present. + * Returns 0 on success otherwise non-zero. + */ +int ha_cpuset_set(struct hap_cpuset *set, int cpu); + +/* Clear index in if present. + * Returns 0 on success otherwise non-zero. + */ +int ha_cpuset_clr(struct hap_cpuset *set, int cpu); + +/* Bitwise and equivalent operation between and stored in . + */ +void ha_cpuset_and(struct hap_cpuset *dst, const struct hap_cpuset *src); + +/* Returns the count of set index in . + */ +int ha_cpuset_count(const struct hap_cpuset *set); + +/* Returns the first index set plus one in starting from the lowest. + * Returns 0 if no index set. + * Do not forget to substract the result by one if using it for set/clr. + */ +int ha_cpuset_ffs(const struct hap_cpuset *set); + +/* Copy set into . + */ +void ha_cpuset_assign(struct hap_cpuset *dst, const struct hap_cpuset *src); + +/* Returns the biggest index plus one usable on the platform. + */ +int ha_cpuset_size(); + +#endif /* _HAPROXY_CPUSET_H */ diff --git a/src/cpuset.c b/src/cpuset.c new file mode 100644 index 0000000000..e4310b696d --- /dev/null +++ b/src/cpuset.c @@ -0,0 +1,121 @@ +#define _GNU_SOURCE +#include + +#include +#include +#include + +void ha_cpuset_zero(struct hap_cpuset *set) +{ +#if defined(CPUSET_USE_CPUSET) || defined(CPUSET_USE_FREEBSD_CPUSET) + CPU_ZERO(&set->cpuset); + +#elif defined(CPUSET_USE_ULONG) + set->cpuset = 0; +#endif +} + +int ha_cpuset_set(struct hap_cpuset *set, int cpu) +{ + if (cpu >= ha_cpuset_size()) + return 1; + +#if defined(CPUSET_USE_CPUSET) || defined(CPUSET_USE_FREEBSD_CPUSET) + CPU_SET(cpu, &set->cpuset); + return 0; + +#elif defined(CPUSET_USE_ULONG) + set->cpuset |= (0x1 << cpu); + return 0; +#endif +} + +int ha_cpuset_clr(struct hap_cpuset *set, int cpu) +{ + if (cpu >= ha_cpuset_size()) + return 1; + +#if defined(CPUSET_USE_CPUSET) || defined(CPUSET_USE_FREEBSD_CPUSET) + CPU_CLR(cpu, &set->cpuset); + return 0; + +#elif defined(CPUSET_USE_ULONG) + set->cpuset &= ~(0x1 << cpu); + return 0; +#endif +} + +void ha_cpuset_and(struct hap_cpuset *dst, const struct hap_cpuset *src) +{ +#if defined(CPUSET_USE_CPUSET) + CPU_AND(&dst->cpuset, &dst->cpuset, &src->cpuset); + +#elif defined(CPUSET_USE_FREEBSD_CPUSET) + CPU_AND(&dst->cpuset, &src->cpuset); + +#elif defined(CPUSET_USE_ULONG) + dst->cpuset &= src->cpuset; +#endif +} + +int ha_cpuset_count(const struct hap_cpuset *set) +{ +#if defined(CPUSET_USE_CPUSET) || defined(CPUSET_USE_FREEBSD_CPUSET) + return CPU_COUNT(&set->cpuset); + +#elif defined(CPUSET_USE_ULONG) + return my_popcountl(set->cpuset); +#endif +} + +int ha_cpuset_ffs(const struct hap_cpuset *set) +{ +#if defined(CPUSET_USE_CPUSET) + int n; + + if (!CPU_COUNT(&set->cpuset)) + return 0; + + for (n = 0; !CPU_ISSET(n, &set->cpuset); ++n) + ; + + return n + 1; + +#elif defined(CPUSET_USE_FREEBSD_CPUSET) + return CPU_FFS(&set->cpuset); + +#elif defined(CPUSET_USE_ULONG) + if (!set->cpuset) + return 0; + + return my_ffsl(set->cpuset); +#endif +} + +void ha_cpuset_assign(struct hap_cpuset *dst, const struct hap_cpuset *src) +{ +#if defined(CPUSET_USE_CPUSET) + CPU_ZERO(&dst->cpuset); + CPU_OR(&dst->cpuset, &dst->cpuset, &src->cpuset); + +#elif defined(CPUSET_USE_FREEBSD_CPUSET) + CPU_COPY(&src->cpuset, &dst->cpuset); + +#elif defined(CPUSET_USE_ULONG) + dst->cpuset = src->cpuset; +#endif +} + +int ha_cpuset_size() +{ +#if defined(CPUSET_USE_CPUSET) + return CPU_SETSIZE; + +#elif defined(CPUSET_USE_FREEBSD_CPUSET) + return MAXCPU; + +#elif defined(CPUSET_USE_ULONG) + return LONGBITS; + +#endif +}