123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*
- 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 <assert.h>
- #include <stdlib.h>
- #include "Process.h"
- #include "XUtils.h"
- #if defined(HAVE_LIBHWLOC)
- #include <hwloc.h>
- #include <hwloc/bitmap.h>
- #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 <sched.h>
- #endif
- Affinity* Affinity_new(Machine* host) {
- Affinity* this = xCalloc(1, sizeof(Affinity));
- this->size = 8;
- this->cpus = xCalloc(this->size, sizeof(unsigned int));
- this->host = host;
- 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)
- static Affinity* Affinity_get(const Process* p, Machine* host) {
- hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
- bool ok = (hwloc_get_proc_cpubind(host->topology, Process_getPid(p), cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0);
- Affinity* affinity = NULL;
- if (ok) {
- affinity = Affinity_new(host);
- if (hwloc_bitmap_last(cpuset) == -1) {
- for (unsigned int i = 0; i < host->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;
- }
- static bool Affinity_set(Process* p, 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->host->topology, Process_getPid(p), cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0);
- hwloc_bitmap_free(cpuset);
- return ok;
- }
- #elif defined(HAVE_AFFINITY)
- static Affinity* Affinity_get(const Process* p, Machine* host) {
- cpu_set_t cpuset;
- bool ok = (sched_getaffinity(Process_getPid(p), sizeof(cpu_set_t), &cpuset) == 0);
- if (!ok)
- return NULL;
- Affinity* affinity = Affinity_new(host);
- for (unsigned int i = 0; i < host->existingCPUs; i++) {
- if (CPU_ISSET(i, &cpuset)) {
- Affinity_add(affinity, i);
- }
- }
- return affinity;
- }
- static bool Affinity_set(Process* p, 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(Process_getPid(p), sizeof(unsigned long), &cpuset) == 0);
- return ok;
- }
- #endif
- #if defined(HAVE_LIBHWLOC) || defined(HAVE_AFFINITY)
- bool Affinity_rowSet(Row* row, Arg arg) {
- Process* p = (Process*) row;
- assert(Object_isA((const Object*) p, (const ObjectClass*) &Process_class));
- return Affinity_set(p, arg);
- }
- Affinity* Affinity_rowGet(const Row* row, Machine* host) {
- const Process* p = (const Process*) row;
- assert(Object_isA((const Object*) p, (const ObjectClass*) &Process_class));
- return Affinity_get(p, host);
- }
- #endif /* HAVE_LIBHWLOC || HAVE_AFFINITY */
|