summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Scott <nathans@redhat.com>2020-08-26 10:15:00 +1000
committerNathan Scott <nathans@redhat.com>2020-08-26 10:39:43 +1000
commit728b04bbb5667291f1e56058240fcd7e03cbfe74 (patch)
treead199ce3a3303e723eb9332aa6cb847b9530084a
parentd0f31ede5624ed2f35ca25043f6a28adfe3bc171 (diff)
Merge branch 'ci-hwloc-job' of https://github.com/bertwesarg/htop into bertwesarg-ci-hwloc-job
-rw-r--r--Action.c5
-rw-r--r--AffinityPanel.c399
-rw-r--r--AffinityPanel.h23
-rw-r--r--CRT.c68
-rw-r--r--CRT.h28
-rw-r--r--CheckItem.c7
-rw-r--r--DisplayOptionsPanel.c3
-rw-r--r--Panel.c8
-rw-r--r--Panel.h2
-rw-r--r--ProcessList.c19
-rw-r--r--Settings.c13
-rw-r--r--Settings.h3
-rw-r--r--Vector.c12
-rw-r--r--Vector.h2
14 files changed, 529 insertions, 63 deletions
diff --git a/Action.c b/Action.c
index a7747f52..363c2b98 100644
--- a/Action.c
+++ b/Action.c
@@ -318,10 +318,11 @@ static Htop_Reaction actionSetAffinity(State* st) {
if (!p) return HTOP_OK;
Affinity* affinity1 = Affinity_get(p, st->pl);
if (!affinity1) return HTOP_OK;
- Panel* affinityPanel = AffinityPanel_new(st->pl, affinity1);
+ int width;
+ Panel* affinityPanel = AffinityPanel_new(st->pl, affinity1, &width);
Affinity_delete(affinity1);
- void* set = Action_pickFromVector(st, affinityPanel, 15, true);
+ void* set = Action_pickFromVector(st, affinityPanel, width, true);
if (set) {
Affinity* affinity2 = AffinityPanel_getAffinity(affinityPanel, st->pl);
bool ok = MainPanel_foreachProcess((MainPanel*)panel, (MainPanel_ForeachProcessFn) Affinity_set, (Arg){ .v = affinity2 }, NULL);
diff --git a/AffinityPanel.c b/AffinityPanel.c
index d9f1612b..7accb2ab 100644
--- a/AffinityPanel.c
+++ b/AffinityPanel.c
@@ -8,69 +8,416 @@ in the source distribution for its full text.
#include "AffinityPanel.h"
#include "CRT.h"
-#include "CheckItem.h"
+#include "Vector.h"
#include <assert.h>
#include <string.h>
+#ifdef HAVE_LIBHWLOC
+#include <hwloc.h>
+#endif
+
/*{
#include "Panel.h"
#include "Affinity.h"
#include "ProcessList.h"
-#include "ListItem.h"
+
}*/
-static HandlerResult AffinityPanel_eventHandler(Panel* this, int ch) {
- CheckItem* selected = (CheckItem*) Panel_getSelected(this);
+typedef struct MaskItem_ {
+ Object super;
+ const char* text;
+ const char* indent;
+ int value; /* tri-state: 0 - off, 1 - some set, 2 - all set */
+ int sub_tree; /* tri-state: 0 - no sub-tree, 1 - open sub-tree, 2 - closed sub-tree */
+ Vector *children;
+ #ifdef HAVE_LIBHWLOC
+ bool ownCpuset;
+ hwloc_bitmap_t cpuset;
+ #else
+ int cpu;
+ #endif
+} MaskItem;
+
+static void MaskItem_delete(Object* cast) {
+ MaskItem* this = (MaskItem*) cast;
+ free((void*)this->text);
+ if (this->indent)
+ free((void*)this->indent);
+ Vector_delete(this->children);
+ #ifdef HAVE_LIBHWLOC
+ if (this->ownCpuset)
+ hwloc_bitmap_free(this->cpuset);
+ #endif
+ free(this);
+}
+
+static void MaskItem_display(Object* cast, RichString* out) {
+ MaskItem* this = (MaskItem*)cast;
+ assert (this != NULL);
+ if (this->value == 2)
+ RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_FULL]);
+ else if (this->value == 1)
+ RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_PARTIAL]);
+ else
+ RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_NONE]);
+ RichString_append(out, CRT_colors[CHECK_TEXT], " ");
+ if (this->indent)
+ RichString_append(out, CRT_colors[PROCESS_TREE], this->indent);
+ if (this->sub_tree) {
+ RichString_append(out, CRT_colors[PROCESS_TREE],
+ this->sub_tree == 1
+ ? CRT_collapStr[COLLAP_STR_OPEN]
+ : CRT_collapStr[COLLAP_STR_CLOSED]);
+ RichString_append(out, CRT_colors[CHECK_TEXT], " ");
+ }
+ RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
+}
+
+static ObjectClass MaskItem_class = {
+ .display = MaskItem_display,
+ .delete = MaskItem_delete
+};
+
+#ifdef HAVE_LIBHWLOC
+
+static MaskItem* MaskItem_newMask(const char* text, const char* indent, hwloc_bitmap_t cpuset, bool owner) {
+ MaskItem* this = AllocThis(MaskItem);
+ this->text = xStrdup(text);
+ this->indent = xStrdup(indent);
+ this->value = 0;
+ this->ownCpuset = owner;
+ this->cpuset = cpuset;
+ this->sub_tree = hwloc_bitmap_weight(cpuset) > 1 ? 1 : 0;
+ this->children = Vector_new(Class(MaskItem), true, DEFAULT_SIZE);
+ return this;
+}
+
+#endif
+
+static MaskItem* MaskItem_newSingleton(const char* text, int cpu, bool isSet) {
+ MaskItem* this = AllocThis(MaskItem);
+ this->text = xStrdup(text);
+ this->indent = NULL;
+ this->sub_tree = 0;
+ this->children = Vector_new(Class(MaskItem), true, DEFAULT_SIZE);
+
+ #ifdef HAVE_LIBHWLOC
+ this->ownCpuset = true;
+ this->cpuset = hwloc_bitmap_alloc();
+ hwloc_bitmap_set(this->cpuset, cpu);
+ (void)isSet;
+ #else
+ this->cpu = cpu;
+ #endif
+ this->value = 2 * isSet;
+
+ return this;
+}
+
+typedef struct AffinityPanel_ {
+ Panel super;
+ ProcessList* pl;
+ bool topoView;
+ Vector *cpuids;
+ unsigned width;
+
+ #ifdef HAVE_LIBHWLOC
+ MaskItem *topoRoot;
+ hwloc_const_cpuset_t allCpuset;
+ hwloc_bitmap_t workCpuset;
+ #endif
+} AffinityPanel;
+
+static void AffinityPanel_delete(Object* cast) {
+ AffinityPanel* this = (AffinityPanel*) cast;
+ Panel* super = (Panel*) this;
+ Panel_done(super);
+ Vector_delete(this->cpuids);
+ #ifdef HAVE_LIBHWLOC
+ hwloc_bitmap_free(this->workCpuset);
+ MaskItem_delete((Object*) this->topoRoot);
+ #endif
+ free(this);
+}
+
+#ifdef HAVE_LIBHWLOC
+
+static void AffinityPanel_updateItem(AffinityPanel* this, MaskItem* item) {
+ Panel* super = (Panel*) this;
+
+ item->value = hwloc_bitmap_isincluded(item->cpuset, this->workCpuset) ? 2 :
+ hwloc_bitmap_intersects(item->cpuset, this->workCpuset) ? 1 : 0;
+
+ Panel_add(super, (Object*) item);
+}
+
+static void AffinityPanel_updateTopo(AffinityPanel* this, MaskItem* item) {
+ AffinityPanel_updateItem(this, item);
+
+ if (item->sub_tree == 2)
+ return;
+
+ for (int i = 0; i < Vector_size(item->children); i++)
+ AffinityPanel_updateTopo(this, (MaskItem*) Vector_get(item->children, i));
+}
+
+#endif
+
+static void AffinityPanel_update(AffinityPanel* this, bool keepSelected) {
+ Panel* super = (Panel*) this;
+
+ FunctionBar_setLabel(super->currentBar, KEY_F(3), this->topoView ? "Collapse/Expand" : "");
+ FunctionBar_draw(super->currentBar, NULL);
+
+ int oldSelected = Panel_getSelectedIndex(super);
+ Panel_prune(super);
+
+ #ifdef HAVE_LIBHWLOC
+ if (this->topoView)
+ AffinityPanel_updateTopo(this, this->topoRoot);
+ else {
+ for (int i = 0; i < Vector_size(this->cpuids); i++)
+ AffinityPanel_updateItem(this, (MaskItem*) Vector_get(this->cpuids, i));
+ }
+ #else
+ Panel_splice(super, this->cpuids);
+ #endif
+
+ if (keepSelected)
+ Panel_setSelected(super, oldSelected);
+
+ super->needsRedraw = true;
+}
+
+static HandlerResult AffinityPanel_eventHandler(Panel* super, int ch) {
+ AffinityPanel* this = (AffinityPanel*) super;
+ HandlerResult result = IGNORED;
+ MaskItem* selected = (MaskItem*) Panel_getSelected(super);
+ bool keepSelected = true;
+
switch(ch) {
case KEY_MOUSE:
case KEY_RECLICK:
case ' ':
- CheckItem_set(selected, ! (CheckItem_get(selected)) );
- return HANDLED;
+ #ifdef HAVE_LIBHWLOC
+ if (selected->value == 2) {
+ /* Item was selected, so remove this mask from the top cpuset. */
+ hwloc_bitmap_andnot(this->workCpuset, this->workCpuset, selected->cpuset);
+ selected->value = 0;
+ } else {
+ /* Item was not or only partial selected, so set all bits from this object
+ in the top cpuset. */
+ hwloc_bitmap_or(this->workCpuset, this->workCpuset, selected->cpuset);
+ selected->value = 2;
+ }
+ #else
+ selected->value = 2 * !selected->value; /* toggle between 0 and 2 */
+ #endif
+
+ result = HANDLED;
+ break;
+
+ #ifdef HAVE_LIBHWLOC
+
+ case KEY_F(1):
+ hwloc_bitmap_copy(this->workCpuset, this->allCpuset);
+ result = HANDLED;
+ break;
+
+ case KEY_F(2):
+ this->topoView = !this->topoView;
+ keepSelected = false;
+
+ result = HANDLED;
+ break;
+
+ case KEY_F(3):
+ case '-':
+ case '+':
+ if (selected->sub_tree)
+ selected->sub_tree = 1 + !(selected->sub_tree - 1); /* toggle between 1 and 2 */
+
+ result = HANDLED;
+ break;
+
+ #endif
+
case 0x0a:
case 0x0d:
case KEY_ENTER:
- return BREAK_LOOP;
+ result = BREAK_LOOP;
+ break;
+ }
+
+ if (HANDLED == result)
+ AffinityPanel_update(this, keepSelected);
+
+ return result;
+}
+
+#ifdef HAVE_LIBHWLOC
+
+static MaskItem *AffinityPanel_addObject(AffinityPanel* this, hwloc_obj_t obj, unsigned indent, MaskItem *parent) {
+ const char* type_name = hwloc_obj_type_string(obj->type);
+ const char* index_prefix = " #";
+ unsigned depth = obj->depth;
+ unsigned index = obj->logical_index;
+ size_t off = 0, left = 10 * depth;
+ char buf[64], indent_buf[left + 1];
+
+ if (obj->type == HWLOC_OBJ_PU) {
+ index = Settings_cpuId(this->pl->settings, obj->os_index);
+ type_name = "CPU";
+ index_prefix = "";
+ }
+
+ indent_buf[0] = '\0';
+ if (depth > 0) {
+ for (unsigned i = 1; i < depth; i++) {
+ xSnprintf(&indent_buf[off], left, "%s ", (indent & (1u << i)) ? CRT_treeStr[TREE_STR_VERT] : " ");
+ size_t len = strlen(&indent_buf[off]);
+ off += len, left -= len;
+ }
+ xSnprintf(&indent_buf[off], left, "%s%s ",
+ obj->next_sibling ? CRT_treeStr[TREE_STR_RTEE] : CRT_treeStr[TREE_STR_BEND],
+ CRT_treeStr[TREE_STR_HORZ]);
+ size_t len = strlen(&indent_buf[off]);
+ off += len, left -= len;
+ }
+
+ xSnprintf(buf, 64, "%s%s%u", type_name, index_prefix, index);
+
+ MaskItem *item = MaskItem_newMask(buf, indent_buf, obj->complete_cpuset, false);
+ if (parent)
+ Vector_add(parent->children, item);
+
+ if (item->sub_tree && parent && parent->sub_tree == 1) {
+ /* if obj is fully included or fully excluded, collapse the item */
+ hwloc_bitmap_t result = hwloc_bitmap_alloc();
+ hwloc_bitmap_and(result, obj->complete_cpuset, this->workCpuset);
+ int weight = hwloc_bitmap_weight(result);
+ hwloc_bitmap_free(result);
+ if (weight == 0 || weight == (hwloc_bitmap_weight(this->workCpuset) + hwloc_bitmap_weight(obj->complete_cpuset)))
+ item->sub_tree = 2;
+ }
+
+ /* "[x] " + "|- " * depth + ("[+] ")? + name */
+ unsigned width = (CRT_utf8 ? 2 : 4) + 3 * depth + (item->sub_tree ? (CRT_utf8 ? 2 : 4) : 0) + strlen(buf);
+ if (width > this->width)
+ this->width = width;
+
+ return item;
+}
+
+static MaskItem *AffinityPanel_buildTopology(AffinityPanel* this, hwloc_obj_t obj, unsigned indent, MaskItem *parent) {
+ MaskItem *item = AffinityPanel_addObject(this, obj, indent, parent);
+ if (obj->next_sibling) {
+ indent |= (1u << obj->depth);
+ } else {
+ indent &= ~(1u << obj->depth);
}
- return IGNORED;
+ for (unsigned i = 0; i < obj->arity; i++)
+ AffinityPanel_buildTopology(this, obj->children[i], indent, item);
+
+ return parent == NULL ? item : NULL;
}
+#endif
+
PanelClass AffinityPanel_class = {
.super = {
.extends = Class(Panel),
- .delete = Panel_delete
+ .delete = AffinityPanel_delete
},
.eventHandler = AffinityPanel_eventHandler
};
-Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) {
- Panel* this = Panel_new(1, 1, 1, 1, true, Class(CheckItem), FunctionBar_newEnterEsc("Set ", "Cancel "));
- Object_setClass(this, Class(AffinityPanel));
+static const char* const AffinityPanelFunctions[] = {
+ "Set ",
+ "Cancel ",
+ #ifdef HAVE_LIBHWLOC
+ "All",
+ "Topology",
+ " ",
+ #endif
+ NULL
+};
+static const char* const AffinityPanelKeys[] = {"Enter", "Esc", "F1", "F2", "F3"};
+static const int AffinityPanelEvents[] = {13, 27, KEY_F(1), KEY_F(2), KEY_F(3)};
+
+Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity, int* width) {
+ AffinityPanel* this = AllocThis(AffinityPanel);
+ Panel* super = (Panel*) this;
+ Panel_init(super, 1, 1, 1, 1, Class(MaskItem), false, FunctionBar_new(AffinityPanelFunctions, AffinityPanelKeys, AffinityPanelEvents));
+
+ this->pl = pl;
+ this->width = 15;
+
+ this->cpuids = Vector_new(Class(MaskItem), true, DEFAULT_SIZE);
+
+ #ifdef HAVE_LIBHWLOC
+ this->topoView = pl->settings->topologyAffinity;
+ #else
+ this->topoView = false;
+ #endif
+
+ #ifdef HAVE_LIBHWLOC
+ this->allCpuset = hwloc_topology_get_complete_cpuset(pl->topology);
+ this->workCpuset = hwloc_bitmap_alloc();
+ #endif
+
+ Panel_setHeader(super, "Use CPUs:");
- Panel_setHeader(this, "Use CPUs:");
int curCpu = 0;
for (int i = 0; i < pl->cpuCount; i++) {
- char number[10];
- xSnprintf(number, 9, "%d", Settings_cpuId(pl->settings, i));
- bool mode;
+ char number[16];
+ xSnprintf(number, 9, "CPU %d", Settings_cpuId(pl->settings, i));
+ unsigned width = 4 + strlen(number);
+ if (width > this->width)
+ this->width = width;
+
+ bool isSet = false;
if (curCpu < affinity->used && affinity->cpus[curCpu] == i) {
- mode = true;
+ #ifdef HAVE_LIBHWLOC
+ hwloc_bitmap_set(this->workCpuset, i);
+ #endif
+ isSet = true;
curCpu++;
- } else {
- mode = false;
}
- Panel_add(this, (Object*) CheckItem_newByVal(xStrdup(number), mode));
+
+ MaskItem* cpuItem = MaskItem_newSingleton(number, i, isSet);
+ Vector_add(this->cpuids, (Object*) cpuItem);
}
- return this;
+
+ #ifdef HAVE_LIBHWLOC
+ this->topoRoot = AffinityPanel_buildTopology(this, hwloc_get_root_obj(pl->topology), 0, NULL);
+ #endif
+
+ if (width)
+ *width = this->width;
+
+ AffinityPanel_update(this, false);
+
+ return super;
}
-Affinity* AffinityPanel_getAffinity(Panel* this, ProcessList* pl) {
+Affinity* AffinityPanel_getAffinity(Panel* super, ProcessList* pl) {
+ AffinityPanel* this = (AffinityPanel*) super;
Affinity* affinity = Affinity_new(pl);
- int size = Panel_size(this);
- for (int i = 0; i < size; i++) {
- if (CheckItem_get((CheckItem*)Panel_get(this, i)))
- Affinity_add(affinity, i);
+
+ #ifdef HAVE_LIBHWLOC
+ int i;
+ hwloc_bitmap_foreach_begin(i, this->workCpuset)
+ Affinity_add(affinity, i);
+ hwloc_bitmap_foreach_end();
+ #else
+ for (int i = 0; i < this->pl->cpuCount; i++) {
+ MaskItem* item = (MaskItem*)Vector_get(this->cpuids, i);
+ if (item->value)
+ Affinity_add(affinity, item->cpu);
}
+ #endif
+
return affinity;
}
diff --git a/AffinityPanel.h b/AffinityPanel.h
index 3a9c7807..54d4f24c 100644
--- a/AffinityPanel.h
+++ b/AffinityPanel.h
@@ -9,15 +9,32 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
+#ifdef HAVE_LIBHWLOC
+#endif
+
#include "Panel.h"
#include "Affinity.h"
#include "ProcessList.h"
-#include "ListItem.h"
+
+
+
+#ifdef HAVE_LIBHWLOC
+
+#endif
+
+
+#ifdef HAVE_LIBHWLOC
+
+#endif
+
+#ifdef HAVE_LIBHWLOC
+
+#endif
extern PanelClass AffinityPanel_class;
-extern Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity);
+extern Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity, int* width);
-extern Affinity* AffinityPanel_getAffinity(Panel* this, ProcessList* pl);
+extern Affinity* AffinityPanel_getAffinity(Panel* super, ProcessList* pl);
#endif
diff --git a/CRT.c b/CRT.c
index 35b285f7..869573e5 100644
--- a/CRT.c
+++ b/CRT.c
@@ -59,6 +59,19 @@ typedef enum TreeStr_ {
TREE_STR_COUNT
} TreeStr;
+typedef enum CheckStr_ {
+ CHECK_STR_NONE,
+ CHECK_STR_PARTIAL,
+ CHECK_STR_FULL,
+ CHECK_STR_COUNT
+} CheckStr;
+
+typedef enum CollapStr_ {
+ COLLAP_STR_OPEN,
+ COLLAP_STR_CLOSED,
+ COLLAP_STR_COUNT
+} CollapStr;
+
typedef enum ColorSchemes_ {
COLORSCHEME_DEFAULT = 0,
COLORSCHEME_MONOCHROME = 1,
@@ -113,7 +126,6 @@ typedef enum ColorElements_ {
LOAD_AVERAGE_FIFTEEN,
LOAD_AVERAGE_FIVE,
LOAD_AVERAGE_ONE,
- CHECK_BOX,
CHECK_MARK,
CHECK_TEXT,
CLOCK,
@@ -159,6 +171,17 @@ const char *CRT_treeStrAscii[TREE_STR_COUNT] = {
"-", // TREE_STR_SHUT
};
+const char *CRT_checkStrAscii[CHECK_STR_COUNT] = {
+ "[ ]", // CHECK_STR_NONE
+ "[o]", // CHECK_STR_PARTIAL
+ "[x]", // CHECK_STR_FULL
+};
+
+const char *CRT_collapStrAscii[COLLAP_STR_COUNT] = {
+ "[-]", // COLLAP_STR_OPEN
+ "[+]", // COLLAP_STR_CLOSED
+};
+
#ifdef HAVE_LIBNCURSESW
const char *CRT_treeStrUtf8[TREE_STR_COUNT] = {
@@ -171,12 +194,27 @@ const char *CRT_treeStrUtf8[TREE_STR_COUNT] = {
"\xe2\x94\x80", // TREE_STR_SHUT ─
};
-bool CRT_utf8 = false;
+const char *CRT_checkStrUtf8[CHECK_STR_COUNT] = {
+ "\xe2\x98\x90", // CHECK_STR_NONE ☐
+ "\xe2\x98\x92", // CHECK_STR_PARTIAL ☒
+ "\xe2\x98\x91", // CHECK_STR_FULL ☑
+};
+
+const char *CRT_collapStrUtf8[COLLAP_STR_COUNT] = {
+ "\xe2\x8a\x9f", // COLLAP_STR_OPEN ⊟
+ "\xe2\x8a\x9e", // COLLAP_STR_CLOSED ⊞
+};
#endif
+bool CRT_utf8 = false;
+
const char **CRT_treeStr = CRT_treeStrAscii;
+const char **CRT_checkStr = CRT_checkStrAscii;
+
+const char **CRT_collapStr = CRT_collapStrAscii;
+
static bool CRT_hasColors;
int CRT_delay = 0;
@@ -229,8 +267,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black),
[CLOCK] = A_BOLD,
- [CHECK_BOX] = ColorPair(Cyan,Black),
- [CHECK_MARK] = A_BOLD,
+ [CHECK_MARK] = A_BOLD | ColorPair(Cyan,Black),
[CHECK_TEXT] = A_NORMAL,
[HOSTNAME] = A_BOLD,
[CPU_NICE] = ColorPair(Blue,Black),
@@ -298,8 +335,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD,
[CLOCK] = A_BOLD,
- [CHECK_BOX] = A_BOLD,
- [CHECK_MARK] = A_NORMAL,
+ [CHECK_MARK] = A_BOLD,
[CHECK_TEXT] = A_NORMAL,
[HOSTNAME] = A_BOLD,
[CPU_NICE] = A_NORMAL,
@@ -367,7 +403,6 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = ColorPair(Black,White),
[HELP_BOLD] = ColorPair(Blue,White),
[CLOCK] = ColorPair(Black,White),
- [CHECK_BOX] = ColorPair(Blue,White),
[CHECK_MARK] = ColorPair(Black,White),
[CHECK_TEXT] = ColorPair(Black,White),
[HOSTNAME] = ColorPair(Black,White),
@@ -436,7 +471,6 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = ColorPair(White,Black),
[HELP_BOLD] = ColorPair(Blue,Black),
[CLOCK] = ColorPair(White,Black),
- [CHECK_BOX] = ColorPair(Blue,Black),
[CHECK_MARK] = ColorPair(Black,Black),
[CHECK_TEXT] = ColorPair(Black,Black),
[HOSTNAME] = ColorPair(White,Black),
@@ -505,8 +539,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD | ColorPair(White,Blue),
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Blue),
[CLOCK] = ColorPair(White,Blue),
- [CHECK_BOX] = ColorPair(Cyan,Blue),
- [CHECK_MARK] = A_BOLD | ColorPair(White,Blue),
+ [CHECK_MARK] = A_BOLD | ColorPair(Cyan,Blue),
[CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue),
[HOSTNAME] = ColorPair(White,Blue),
[CPU_NICE] = A_BOLD | ColorPair(Cyan,Blue),
@@ -574,7 +607,6 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black),
[CLOCK] = ColorPair(Green,Black),
- [CHECK_BOX] = ColorPair(Green,Black),
[CHECK_MARK] = A_BOLD | ColorPair(Green,Black),
[CHECK_TEXT] = ColorPair(Cyan,Black),
[HOSTNAME] = ColorPair(Green,Black),
@@ -731,17 +763,13 @@ void CRT_init(int delay, int colorScheme) {
setlocale(LC_CTYPE, "");
#ifdef HAVE_LIBNCURSESW
- if(strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
+ if(strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
CRT_utf8 = true;
- else
- CRT_utf8 = false;
-#endif
-
- CRT_treeStr =
-#ifdef HAVE_LIBNCURSESW
- CRT_utf8 ? CRT_treeStrUtf8 :
+ CRT_treeStr = CRT_treeStrUtf8;
+ CRT_checkStr = CRT_checkStrUtf8;
+ CRT_collapStr = CRT_collapStrUtf8;
+ }
#endif
- CRT_treeStrAscii;
#if NCURSES_MOUSE_VERSION > 1
mousemask(BUTTON1_RELEASED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL);
diff --git a/CRT.h b/CRT.h
index 80022f70..5fb2f09c 100644
--- a/CRT.h
+++ b/CRT.h
@@ -47,6 +47,19 @@ typedef enum TreeStr_ {
TREE_STR_COUNT
} TreeStr;
+typedef enum CheckStr_ {
+ CHECK_STR_NONE,
+ CHECK_STR_PARTIAL,
+ CHECK_STR_FULL,
+ CHECK_STR_COUNT
+} CheckStr;
+
+typedef enum CollapStr_ {
+ COLLAP_STR_OPEN,
+ COLLAP_STR_CLOSED,
+ COLLAP_STR_COUNT
+} CollapStr;
+
typedef enum ColorSchemes_ {
COLORSCHEME_DEFAULT = 0,
COLORSCHEME_MONOCHROME = 1,
@@ -101,7 +114,6 @@ typedef enum ColorElements_ {
LOAD_AVERAGE_FIFTEEN,
LOAD_AVERAGE_FIVE,
LOAD_AVERAGE_ONE,
- CHECK_BOX,
CHECK_MARK,
CHECK_TEXT,
CLOCK,
@@ -138,16 +150,28 @@ extern void CRT_handleSIGSEGV(int sgn);
extern const char *CRT_treeStrAscii[TREE_STR_COUNT];
+extern const char *CRT_checkStrAscii[CHECK_STR_COUNT];
+
+extern const char *CRT_collapStrAscii[COLLAP_STR_COUNT];
+
#ifdef HAVE_LIBNCURSESW
extern const char *CRT_treeStrUtf8[TREE_STR_COUNT];
-extern bool CRT_utf8;
+extern const char *CRT_checkStrUtf8[CHECK_STR_COUNT];
+
+extern const char *CRT_collapStrUtf8[COLLAP_STR_COUNT];
#endif
+extern bool CRT_utf8;
+
extern const char **CRT_treeStr;
+extern const char **CRT_checkStr;
+
+extern const char **CRT_collapStr;
+
extern int CRT_delay;
extern int* CRT_colors;
diff --git a/CheckItem.c b/CheckItem.c
index 910981e8..a045d2ff 100644
--- a/CheckItem.c
+++ b/CheckItem.c
@@ -35,12 +35,11 @@ static void CheckItem_delete(Object* cast) {
static void CheckItem_display(Object* cast, RichString* out) {
CheckItem* this = (CheckItem*)cast;
assert (this != NULL);
- RichString_write(out, CRT_colors[CHECK_BOX], "[");
if (CheckItem_get(this))
- RichString_append(out, CRT_colors[CHECK_MARK], "x");
+ RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_FULL]);
else
- RichString_append(out, CRT_colors[CHECK_MARK], " ");
- RichString_append(out, CRT_colors[CHECK_BOX], "] ");
+ RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_NONE]);
+ RichString_append(out, CRT_colors[CHECK_TEXT], " ");
RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
}
diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c
index 0f44acc2..1222d823 100644
--- a/DisplayOptionsPanel.c
+++ b/DisplayOptionsPanel.c
@@ -100,5 +100,8 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU percentage numerically"), &(settings->showCPUUsage)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU frequency"), &(settings->showCPUFrequency)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Enable the mouse"), &(settings->enableMouse)));
+ #ifdef HAVE_LIBHWLOC
+ Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Show topology when selecting affinity by default"), &(settings->topologyAffinity)));
+ #endif
return this;
}
diff --git a/Panel.c b/Panel.c
index fc4fa3c2..348fd238 100644
--- a/Panel.c
+++ b/Panel.c
@@ -264,6 +264,14 @@ void Panel_setSelected(Panel* this, int selected) {
}
}
+void Panel_splice(Panel *this, Vector* from) {
+ assert (this != NULL);
+ assert (from != NULL);
+
+ Vector_splice(this->items, from);
+ this->needsRedraw = true;
+}
+
void Panel_draw(Panel* this, bool focus) {
assert (this != NULL);
diff --git a/Panel.h b/Panel.h
index b7480c6b..4b517f31 100644
--- a/Panel.h
+++ b/Panel.h
@@ -119,6 +119,8 @@ extern void Panel_setSelected(Panel* this, int selected);
extern void Panel_draw(Panel* this, bool focus);
+extern void Panel_splice(Panel *this, Vector* from);
+
extern bool Panel_onKey(Panel* this, int key);
extern HandlerResult Panel_selectByTyping(Panel* this, int ch);
diff --git a/ProcessList.c b/ProcessList.c
index edbc114c..36b494e2 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -93,12 +93,19 @@ ProcessList* ProcessList_init(ProcessList* this, ObjectClass* klass, UsersTable*
#ifdef HAVE_LIBHWLOC
this->topologyOk = false;
- int topoErr = hwloc_topology_init(&this->topology);
- if (topoErr == 0) {
- topoErr = hwloc_topology_load(this->topology);
- }
- if (topoErr == 0) {
- this->topologyOk = true;
+ if (hwloc_topology_init(&this->topology) == 0) {
+ this->topologyOk =
+ #if HWLOC_API_VERSION < 0x00020000
+ /* try to ignore the top-level machine object type */
+ 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_MACHINE) &&
+ /* ignore caches, which don't add structure */
+ 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CORE) &&
+ 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CACHE) &&
+ 0 == hwloc_topology_set_flags(this->topology, HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) &&
+ #else
+ 0 == hwloc_topology_set_all_types_filter(this->topology, HWLOC_TYPE_FILTER_KEEP_STRUCTURE) &&
+ #endif
+ 0 == hwloc_topology_load(this->topology);
}
#endif
diff --git a/Settings.c b/Settings.c
index 6197241f..81d547be 100644
--- a/Settings.c
+++ b/Settings.c
@@ -62,6 +62,9 @@ typedef struct Settings_ {
bool headerMargin;
bool enableMouse;
bool vimMode;
+ #ifdef HAVE_LIBHWLOC
+ bool topologyAffinity;
+ #endif
bool changed;
} Settings;
@@ -256,6 +259,10 @@ static bool Settings_read(Settings* this, const char* fileName) {
didReadMeters = true;
} else if (String_eq(option[0], "vim_mode")) {
this->vimMode = atoi(option[1]);
+ #ifdef HAVE_LIBHWLOC
+ } else if (String_eq(option[0], "topology_affinity")) {
+ this->topologyAffinity = !!atoi(option[1]);
+ #endif
}
String_freeArray(option);
}
@@ -336,6 +343,9 @@ bool Settings_write(Settings* this) {
fprintf(fd, "right_meters="); writeMeters(this, fd, 1);
fprintf(fd, "right_meter_modes="); writeMeterModes(this, fd, 1);
fprintf(fd, "vim_mode=%d\n", (int) this->vimMode);
+ #ifdef HAVE_LIBHWLOC
+ fprintf(fd, "topology_affinity=%d\n", (int) this->topologyAffinity);
+ #endif
fclose(fd);
return true;
}
@@ -362,6 +372,9 @@ Settings* Settings_new(int cpuCount) {
this->cpuCount = cpuCount;
this->showProgramPath = true;
this->highlightThreads = true;
+ #ifdef HAVE_LIBHWLOC
+ this->topologyAffinity = false;
+ #endif
this->fields = xCalloc(Platform_numberOfFields+1, sizeof(ProcessField));
// TODO: turn 'fields' into a Vector,
diff --git a/Settings.h b/Settings.h
index 89300951..f38b8ecd 100644
--- a/Settings.h
+++ b/Settings.h
@@ -53,6 +53,9 @@ typedef struct Settings_ {
bool headerMargin;
bool enableMouse;
bool vimMode;
+ #ifdef HAVE_LIBHWLOC
+ bool topologyAffinity;
+ #endif
bool changed;
} Settings;
diff --git a/Vector.c b/Vector.c
index 819d9863..b5e77446 100644
--- a/Vector.c
+++ b/Vector.c
@@ -335,3 +335,15 @@ inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
}
return -1;
}
+
+void Vector_splice(Vector* this, Vector* from) {
+ assert(Vector_isConsistent(this));
+ assert(Vector_isConsistent(from));
+ assert(!(this->owner && from->owner));
+
+ int olditmes = this->items;
+ this->items += from->items;
+ Vector_checkArraySize(this);
+ for (int j = 0; j < from->items; j++)
+ this->array[olditmes + j] = from->array[j];
+}
diff --git a/Vector.h b/Vector.h
index b48c8363..0d9f1c2c 100644
--- a/Vector.h
+++ b/Vector.h
@@ -88,4 +88,6 @@ extern void Vector_add(Vector* this, void* data_);
extern int Vector_indexOf(Vector* this, void* search_, Object_Compare compare);
+void Vector_splice(Vector* this, Vector* from);
+
#endif

© 2014-2024 Faster IT GmbH | imprint | privacy policy