From 52e25213825024b8bb446eb26b03bedc9d5c2103 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:00:29 +0200 Subject: Adding upstream version 3.2.2. Signed-off-by: Daniel Baumann --- Affinity.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 Affinity.c (limited to 'Affinity.c') diff --git a/Affinity.c b/Affinity.c new file mode 100644 index 0000000..dc6a7fb --- /dev/null +++ b/Affinity.c @@ -0,0 +1,115 @@ +/* +htop - Affinity.c +(C) 2004-2011 Hisham H. Muhammad +(C) 2020 Red Hat, Inc. All Rights Reserved. +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include "config.h" // IWYU pragma: keep + +#include "Affinity.h" + +#include + +#include "XUtils.h" + +#if defined(HAVE_LIBHWLOC) +#include +#include +#ifdef __linux__ +#define HTOP_HWLOC_CPUBIND_FLAG HWLOC_CPUBIND_THREAD +#else +#define HTOP_HWLOC_CPUBIND_FLAG HWLOC_CPUBIND_PROCESS +#endif +#elif defined(HAVE_AFFINITY) +#include +#endif + + +Affinity* Affinity_new(ProcessList* pl) { + Affinity* this = xCalloc(1, sizeof(Affinity)); + this->size = 8; + this->cpus = xCalloc(this->size, sizeof(unsigned int)); + this->pl = pl; + return this; +} + +void Affinity_delete(Affinity* this) { + free(this->cpus); + free(this); +} + +void Affinity_add(Affinity* this, unsigned int id) { + if (this->used == this->size) { + this->size *= 2; + this->cpus = xRealloc(this->cpus, sizeof(unsigned int) * this->size); + } + this->cpus[this->used] = id; + this->used++; +} + + +#if defined(HAVE_LIBHWLOC) + +Affinity* Affinity_get(const Process* proc, ProcessList* pl) { + hwloc_cpuset_t cpuset = hwloc_bitmap_alloc(); + bool ok = (hwloc_get_proc_cpubind(pl->topology, proc->pid, cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0); + Affinity* affinity = NULL; + if (ok) { + affinity = Affinity_new(pl); + if (hwloc_bitmap_last(cpuset) == -1) { + for (unsigned int i = 0; i < pl->existingCPUs; i++) { + Affinity_add(affinity, i); + } + } else { + int id; + hwloc_bitmap_foreach_begin(id, cpuset) + Affinity_add(affinity, (unsigned)id); + hwloc_bitmap_foreach_end(); + } + } + hwloc_bitmap_free(cpuset); + return affinity; +} + +bool Affinity_set(Process* proc, Arg arg) { + Affinity* this = arg.v; + hwloc_cpuset_t cpuset = hwloc_bitmap_alloc(); + for (unsigned int i = 0; i < this->used; i++) { + hwloc_bitmap_set(cpuset, this->cpus[i]); + } + bool ok = (hwloc_set_proc_cpubind(this->pl->topology, proc->pid, cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0); + hwloc_bitmap_free(cpuset); + return ok; +} + +#elif defined(HAVE_AFFINITY) + +Affinity* Affinity_get(const Process* proc, ProcessList* pl) { + cpu_set_t cpuset; + bool ok = (sched_getaffinity(proc->pid, sizeof(cpu_set_t), &cpuset) == 0); + if (!ok) + return NULL; + + Affinity* affinity = Affinity_new(pl); + for (unsigned int i = 0; i < pl->existingCPUs; i++) { + if (CPU_ISSET(i, &cpuset)) { + Affinity_add(affinity, i); + } + } + return affinity; +} + +bool Affinity_set(Process* proc, Arg arg) { + Affinity* this = arg.v; + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + for (unsigned int i = 0; i < this->used; i++) { + CPU_SET(this->cpus[i], &cpuset); + } + bool ok = (sched_setaffinity(proc->pid, sizeof(unsigned long), &cpuset) == 0); + return ok; +} + +#endif -- cgit v1.2.3