123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /*
- htop - Instance.c
- (C) 2022-2023 Sohaib Mohammed
- (C) 2022-2023 htop dev team
- Released under the GNU GPLv2+, see the COPYING file
- in the source distribution for its full text.
- */
- #include "config.h" // IWYU pragma: keep
- #include "pcp/Instance.h"
- #include <stdbool.h>
- #include <stdlib.h>
- #include "CRT.h"
- #include "DynamicColumn.h"
- #include "DynamicScreen.h"
- #include "Hashtable.h"
- #include "Machine.h"
- #include "Macros.h"
- #include "Metric.h"
- #include "Platform.h"
- #include "PCPDynamicColumn.h"
- #include "PCPDynamicScreen.h"
- #include "Row.h"
- #include "RichString.h"
- #include "XUtils.h"
- #include "pcp/InDomTable.h"
- #include "pcp/Metric.h"
- Instance* Instance_new(const Machine* host, const InDomTable* indom) {
- Instance* this = xCalloc(1, sizeof(Instance));
- Object_setClass(this, Class(Instance));
- Row* super = &this->super;
- Row_init(super, host);
- this->indom = indom;
- return this;
- }
- void Instance_done(Instance* this) {
- if (this->name)
- free(this->name);
- Row_done(&this->super);
- }
- static void Instance_delete(Object* cast) {
- Instance* this = (Instance*) cast;
- Instance_done(this);
- free(this);
- }
- static void Instance_writeField(const Row* super, RichString* str, RowField field) {
- const Instance* this = (const Instance*) super;
- int instid = Instance_getId(this);
- const Settings* settings = super->host->settings;
- DynamicColumn* column = Hashtable_get(settings->dynamicColumns, field);
- PCPDynamicColumn* cp = (PCPDynamicColumn*) column;
- if (!cp)
- return;
- pmAtomValue atom;
- pmAtomValue* ap = &atom;
- const pmDesc* descp = Metric_desc(cp->id);
- if (!Metric_instance(cp->id, instid, this->offset, ap, descp->type))
- ap = NULL;
- PCPDynamicColumn_writeAtomValue(cp, str, settings, cp->id, instid, descp, ap);
- if (ap && descp->type == PM_TYPE_STRING)
- free(ap->cp);
- }
- static const char* Instance_externalName(Row* super) {
- Instance* this = (Instance*) super;
- if (!this->name)
- /* ignore any failure here - its safe and we try again next time */
- (void)pmNameInDom(InDom_getId(this), Instance_getId(this), &this->name);
- return this->name;
- }
- static int Instance_compareByKey(const Row* v1, const Row* v2, int key) {
- const Instance* i1 = (const Instance*)v1;
- const Instance* i2 = (const Instance*)v2;
- if (key < 0)
- return 0;
- Hashtable* dc = Platform_dynamicColumns();
- const PCPDynamicColumn* column = Hashtable_get(dc, key);
- if (!column)
- return -1;
- size_t metric = column->id;
- unsigned int type = Metric_type(metric);
- pmAtomValue atom1 = {0}, atom2 = {0};
- if (!Metric_instance(metric, i1->offset, i1->offset, &atom1, type) ||
- !Metric_instance(metric, i2->offset, i2->offset, &atom2, type)) {
- if (type == PM_TYPE_STRING) {
- free(atom1.cp);
- free(atom2.cp);
- }
- return -1;
- }
- switch (type) {
- case PM_TYPE_STRING: {
- int cmp = SPACESHIP_NULLSTR(atom2.cp, atom1.cp);
- free(atom2.cp);
- free(atom1.cp);
- return cmp;
- }
- case PM_TYPE_32:
- return SPACESHIP_NUMBER(atom2.l, atom1.l);
- case PM_TYPE_U32:
- return SPACESHIP_NUMBER(atom2.ul, atom1.ul);
- case PM_TYPE_64:
- return SPACESHIP_NUMBER(atom2.ll, atom1.ll);
- case PM_TYPE_U64:
- return SPACESHIP_NUMBER(atom2.ull, atom1.ull);
- case PM_TYPE_FLOAT:
- return SPACESHIP_NUMBER(atom2.f, atom1.f);
- case PM_TYPE_DOUBLE:
- return SPACESHIP_NUMBER(atom2.d, atom1.d);
- default:
- break;
- }
- return 0;
- }
- static int Instance_compare(const void* v1, const void* v2) {
- const Instance* i1 = (const Instance*)v1;
- const Instance* i2 = (const Instance*)v2;
- const ScreenSettings* ss = i1->super.host->settings->ss;
- RowField key = ScreenSettings_getActiveSortKey(ss);
- int result = Instance_compareByKey(v1, v2, key);
- // Implement tie-breaker (needed to make tree mode more stable)
- if (!result)
- return SPACESHIP_NUMBER(Instance_getId(i1), Instance_getId(i2));
- return (ScreenSettings_getActiveDirection(ss) == 1) ? result : -result;
- }
- const RowClass Instance_class = {
- .super = {
- .extends = Class(Row),
- .display = Row_display,
- .delete = Instance_delete,
- .compare = Instance_compare,
- },
- .sortKeyString = Instance_externalName,
- .writeField = Instance_writeField,
- };
|