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.
This commit is contained in:
Amaury Denoyelle 2021-04-14 15:03:51 +02:00
parent de9d605aa5
commit f75c640f7b
4 changed files with 207 additions and 0 deletions

View File

@ -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 =

View File

@ -0,0 +1,40 @@
#define _GNU_SOURCE
#include <sched.h>
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
#include <sys/param.h>
#ifdef __FreeBSD__
#include <sys/_cpuset.h>
#include <sys/cpuset.h>
#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 */

42
include/haproxy/cpuset.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef _HAPROXY_CPUSET_H
#define _HAPROXY_CPUSET_H
#include <haproxy/cpuset-t.h>
/* Unset all indexes in <set>.
*/
void ha_cpuset_zero(struct hap_cpuset *set);
/* Set <cpu> index in <set> if not present.
* Returns 0 on success otherwise non-zero.
*/
int ha_cpuset_set(struct hap_cpuset *set, int cpu);
/* Clear <cpu> index in <set> if present.
* Returns 0 on success otherwise non-zero.
*/
int ha_cpuset_clr(struct hap_cpuset *set, int cpu);
/* Bitwise and equivalent operation between <src> and <dst> stored in <dst>.
*/
void ha_cpuset_and(struct hap_cpuset *dst, const struct hap_cpuset *src);
/* Returns the count of set index in <set>.
*/
int ha_cpuset_count(const struct hap_cpuset *set);
/* Returns the first index set plus one in <set> 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 <src> set into <dst>.
*/
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 */

121
src/cpuset.c Normal file
View File

@ -0,0 +1,121 @@
#define _GNU_SOURCE
#include <sched.h>
#include <haproxy/compat.h>
#include <haproxy/cpuset.h>
#include <haproxy/intops.h>
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
}