2011-12-26 21:35:57 +00:00
|
|
|
/*
|
|
|
|
htop - Affinity.c
|
|
|
|
(C) 2004-2011 Hisham H. Muhammad
|
2020-08-19 23:35:24 +00:00
|
|
|
(C) 2020 Red Hat, Inc. All Rights Reserved.
|
2020-10-05 07:51:32 +00:00
|
|
|
Released under the GNU GPLv2, see the COPYING file
|
2011-12-26 21:35:57 +00:00
|
|
|
in the source distribution for its full text.
|
|
|
|
*/
|
2011-09-24 00:30:47 +00:00
|
|
|
|
2020-11-18 14:12:18 +00:00
|
|
|
#include "config.h" // IWYU pragma: keep
|
2020-09-18 17:23:04 +00:00
|
|
|
|
2011-09-24 00:30:47 +00:00
|
|
|
#include "Affinity.h"
|
2011-12-26 21:35:57 +00:00
|
|
|
|
2011-09-24 00:30:47 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2020-09-19 11:55:23 +00:00
|
|
|
#include "XUtils.h"
|
|
|
|
|
2015-01-22 01:27:31 +00:00
|
|
|
#ifdef HAVE_LIBHWLOC
|
2016-02-14 21:57:29 +00:00
|
|
|
#include <hwloc.h>
|
2020-09-19 11:55:23 +00:00
|
|
|
#include <hwloc/bitmap.h>
|
2020-09-08 11:59:30 +00:00
|
|
|
#ifdef __linux__
|
2016-02-14 21:57:29 +00:00
|
|
|
#define HTOP_HWLOC_CPUBIND_FLAG HWLOC_CPUBIND_THREAD
|
|
|
|
#else
|
|
|
|
#define HTOP_HWLOC_CPUBIND_FLAG HWLOC_CPUBIND_PROCESS
|
|
|
|
#endif
|
2020-09-08 11:59:30 +00:00
|
|
|
#elif defined(HAVE_LINUX_AFFINITY)
|
2015-01-22 01:27:31 +00:00
|
|
|
#include <sched.h>
|
|
|
|
#endif
|
|
|
|
|
2011-09-24 00:30:47 +00:00
|
|
|
|
2015-01-22 01:27:31 +00:00
|
|
|
Affinity* Affinity_new(ProcessList* pl) {
|
2016-02-02 14:53:02 +00:00
|
|
|
Affinity* this = xCalloc(1, sizeof(Affinity));
|
2011-09-24 00:30:47 +00:00
|
|
|
this->size = 8;
|
2016-02-02 14:53:02 +00:00
|
|
|
this->cpus = xCalloc(this->size, sizeof(int));
|
2015-01-22 01:27:31 +00:00
|
|
|
this->pl = pl;
|
2011-09-24 00:30:47 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Affinity_delete(Affinity* this) {
|
|
|
|
free(this->cpus);
|
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Affinity_add(Affinity* this, int id) {
|
|
|
|
if (this->used == this->size) {
|
|
|
|
this->size *= 2;
|
2016-02-02 14:53:02 +00:00
|
|
|
this->cpus = xRealloc(this->cpus, sizeof(int) * this->size);
|
2011-09-24 00:30:47 +00:00
|
|
|
}
|
|
|
|
this->cpus[this->used] = id;
|
|
|
|
this->used++;
|
|
|
|
}
|
|
|
|
|
2015-01-22 01:27:31 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBHWLOC
|
|
|
|
|
|
|
|
Affinity* Affinity_get(Process* proc, ProcessList* pl) {
|
|
|
|
hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
|
2016-02-14 21:57:29 +00:00
|
|
|
bool ok = (hwloc_get_proc_cpubind(pl->topology, proc->pid, cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0);
|
2015-01-22 01:27:31 +00:00
|
|
|
Affinity* affinity = NULL;
|
|
|
|
if (ok) {
|
|
|
|
affinity = Affinity_new(pl);
|
|
|
|
if (hwloc_bitmap_last(cpuset) == -1) {
|
|
|
|
for (int i = 0; i < pl->cpuCount; i++) {
|
|
|
|
Affinity_add(affinity, i);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
unsigned int id;
|
|
|
|
hwloc_bitmap_foreach_begin(id, cpuset);
|
2020-10-31 21:14:27 +00:00
|
|
|
Affinity_add(affinity, id);
|
2015-01-22 01:27:31 +00:00
|
|
|
hwloc_bitmap_foreach_end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hwloc_bitmap_free(cpuset);
|
|
|
|
return affinity;
|
|
|
|
}
|
|
|
|
|
2020-08-19 23:35:24 +00:00
|
|
|
bool Affinity_set(Process* proc, Arg arg) {
|
2020-10-31 22:28:02 +00:00
|
|
|
Affinity* this = arg.v;
|
2015-01-22 01:27:31 +00:00
|
|
|
hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
|
2016-02-14 21:57:29 +00:00
|
|
|
for (int i = 0; i < this->used; i++) {
|
|
|
|
hwloc_bitmap_set(cpuset, this->cpus[i]);
|
2015-01-22 01:27:31 +00:00
|
|
|
}
|
2016-02-14 21:57:29 +00:00
|
|
|
bool ok = (hwloc_set_proc_cpubind(this->pl->topology, proc->pid, cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0);
|
2015-01-22 01:27:31 +00:00
|
|
|
hwloc_bitmap_free(cpuset);
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2020-09-08 11:59:30 +00:00
|
|
|
#elif defined(HAVE_LINUX_AFFINITY)
|
2015-01-22 01:27:31 +00:00
|
|
|
|
|
|
|
Affinity* Affinity_get(Process* proc, ProcessList* pl) {
|
|
|
|
cpu_set_t cpuset;
|
|
|
|
bool ok = (sched_getaffinity(proc->pid, sizeof(cpu_set_t), &cpuset) == 0);
|
2020-11-01 00:09:51 +00:00
|
|
|
if (!ok)
|
|
|
|
return NULL;
|
|
|
|
|
2015-01-22 01:27:31 +00:00
|
|
|
Affinity* affinity = Affinity_new(pl);
|
|
|
|
for (int i = 0; i < pl->cpuCount; i++) {
|
2020-11-01 00:09:51 +00:00
|
|
|
if (CPU_ISSET(i, &cpuset)) {
|
2015-01-22 01:27:31 +00:00
|
|
|
Affinity_add(affinity, i);
|
2020-11-01 00:09:51 +00:00
|
|
|
}
|
2015-01-22 01:27:31 +00:00
|
|
|
}
|
|
|
|
return affinity;
|
|
|
|
}
|
|
|
|
|
2020-08-19 23:35:24 +00:00
|
|
|
bool Affinity_set(Process* proc, Arg arg) {
|
2020-10-31 22:28:02 +00:00
|
|
|
Affinity* this = arg.v;
|
2015-01-22 01:27:31 +00:00
|
|
|
cpu_set_t cpuset;
|
|
|
|
CPU_ZERO(&cpuset);
|
|
|
|
for (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
|