htop/Meter.h

154 lines
5.1 KiB
C
Raw Normal View History

2006-03-04 18:16:49 +00:00
#ifndef HEADER_Meter
#define HEADER_Meter
/*
2006-06-06 20:28:42 +00:00
htop - Meter.h
2011-05-26 16:35:07 +00:00
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPLv2, see the COPYING file
2006-03-04 18:16:49 +00:00
in the source distribution for its full text.
*/
#include "config.h" // IWYU pragma: keep
#include <stdbool.h>
2021-04-29 15:12:43 +00:00
#include <stddef.h>
2020-11-18 13:26:30 +00:00
#include <stdint.h>
#include <sys/time.h>
2006-03-04 18:16:49 +00:00
2020-09-18 17:23:04 +00:00
#include "ListItem.h"
#include "Object.h"
#include "ProcessList.h"
2020-09-18 17:23:04 +00:00
2020-10-06 11:13:16 +00:00
#define METER_TXTBUFFER_LEN 256
#define METER_GRAPHDATA_SIZE 256
#define METER_BUFFER_CHECK(buffer, size, written) \
do { \
if ((written) < 0 || (size_t)(written) >= (size)) { \
return; \
} \
(buffer) += (written); \
(size) -= (size_t)(written); \
} while (0)
#define METER_BUFFER_APPEND_CHR(buffer, size, c) \
do { \
if ((size) < 2) { \
return; \
} \
*(buffer)++ = c; \
*(buffer) = '\0'; \
(size)--; \
if ((size) == 0) { \
return; \
} \
} while (0)
struct Meter_;
2006-03-04 18:16:49 +00:00
typedef struct Meter_ Meter;
typedef void(*Meter_Init)(Meter*);
typedef void(*Meter_Done)(Meter*);
typedef void(*Meter_UpdateMode)(Meter*, int);
2020-10-06 11:13:16 +00:00
typedef void(*Meter_UpdateValues)(Meter*);
2006-03-04 18:16:49 +00:00
typedef void(*Meter_Draw)(Meter*, int, int, int);
2021-07-14 17:24:18 +00:00
typedef const char* (*Meter_GetCaption)(const Meter*);
Add a new DynamicMeter class for runtime Meter extension This commit is based on exploratory work by Sohaib Mohamed. The end goal is two-fold - to support addition of Meters we build via configuration files for both the PCP platform and for scripts ( https://github.com/htop-dev/htop/issues/526 ) Here, we focus on generic code and the PCP support. A new class DynamicMeter is introduced - it uses the special case 'param' field handling that previously was used only by the CPUMeter, such that every runtime-configured Meter is given a unique identifier. Unlike with the CPUMeter this is used internally only. When reading/writing to htoprc instead of CPU(N) - where N is an integer param (CPU number) - we use the string name for each meter. For example, if we have a configuration for a DynamicMeter for some Redis metrics, we might read and write "Dynamic(redis)". This identifier is subsequently matched (back) up to the configuration file so we're able to re-create arbitrary user configurations. The PCP platform configuration file format is fairly simple. We expand configs from several directories, including the users homedir alongside htoprc (below htop/meters/) and also /etc/pcp/htop/meters. The format will be described via a new pcp-htop(5) man page, but its basically ini-style and each Meter has one or more metric expressions associated, as well as specifications for labels, color and so on via a dot separated notation for individual metrics within the Meter. A few initial sample configuration files are provided below ./pcp/meters that give the general idea. The PCP "derived" metric specification - see pmRegisterDerived(3) - is used as the syntax for specifying metrics in PCP DynamicMeters.
2021-06-23 07:44:56 +00:00
typedef void(*Meter_GetUiName)(const Meter*, char*, size_t);
2006-03-04 18:16:49 +00:00
typedef struct MeterClass_ {
const ObjectClass super;
const Meter_Init init;
const Meter_Done done;
const Meter_UpdateMode updateMode;
const Meter_UpdateValues updateValues;
Add a new DynamicMeter class for runtime Meter extension This commit is based on exploratory work by Sohaib Mohamed. The end goal is two-fold - to support addition of Meters we build via configuration files for both the PCP platform and for scripts ( https://github.com/htop-dev/htop/issues/526 ) Here, we focus on generic code and the PCP support. A new class DynamicMeter is introduced - it uses the special case 'param' field handling that previously was used only by the CPUMeter, such that every runtime-configured Meter is given a unique identifier. Unlike with the CPUMeter this is used internally only. When reading/writing to htoprc instead of CPU(N) - where N is an integer param (CPU number) - we use the string name for each meter. For example, if we have a configuration for a DynamicMeter for some Redis metrics, we might read and write "Dynamic(redis)". This identifier is subsequently matched (back) up to the configuration file so we're able to re-create arbitrary user configurations. The PCP platform configuration file format is fairly simple. We expand configs from several directories, including the users homedir alongside htoprc (below htop/meters/) and also /etc/pcp/htop/meters. The format will be described via a new pcp-htop(5) man page, but its basically ini-style and each Meter has one or more metric expressions associated, as well as specifications for labels, color and so on via a dot separated notation for individual metrics within the Meter. A few initial sample configuration files are provided below ./pcp/meters that give the general idea. The PCP "derived" metric specification - see pmRegisterDerived(3) - is used as the syntax for specifying metrics in PCP DynamicMeters.
2021-06-23 07:44:56 +00:00
const Meter_Draw draw;
const Meter_GetCaption getCaption;
Add a new DynamicMeter class for runtime Meter extension This commit is based on exploratory work by Sohaib Mohamed. The end goal is two-fold - to support addition of Meters we build via configuration files for both the PCP platform and for scripts ( https://github.com/htop-dev/htop/issues/526 ) Here, we focus on generic code and the PCP support. A new class DynamicMeter is introduced - it uses the special case 'param' field handling that previously was used only by the CPUMeter, such that every runtime-configured Meter is given a unique identifier. Unlike with the CPUMeter this is used internally only. When reading/writing to htoprc instead of CPU(N) - where N is an integer param (CPU number) - we use the string name for each meter. For example, if we have a configuration for a DynamicMeter for some Redis metrics, we might read and write "Dynamic(redis)". This identifier is subsequently matched (back) up to the configuration file so we're able to re-create arbitrary user configurations. The PCP platform configuration file format is fairly simple. We expand configs from several directories, including the users homedir alongside htoprc (below htop/meters/) and also /etc/pcp/htop/meters. The format will be described via a new pcp-htop(5) man page, but its basically ini-style and each Meter has one or more metric expressions associated, as well as specifications for labels, color and so on via a dot separated notation for individual metrics within the Meter. A few initial sample configuration files are provided below ./pcp/meters that give the general idea. The PCP "derived" metric specification - see pmRegisterDerived(3) - is used as the syntax for specifying metrics in PCP DynamicMeters.
2021-06-23 07:44:56 +00:00
const Meter_GetUiName getUiName;
const int defaultMode;
const double total;
const int* const attributes;
const char* const name; /* internal name of the meter, must not contain any space */
const char* const uiName; /* display name in header setup menu */
const char* const caption; /* prefix in the actual header */
const char* const description; /* optional meter description in header setup menu */
const uint8_t maxItems;
} MeterClass;
#define As_Meter(this_) ((const MeterClass*)((this_)->super.klass))
#define Meter_initFn(this_) As_Meter(this_)->init
#define Meter_init(this_) As_Meter(this_)->init((Meter*)(this_))
#define Meter_done(this_) As_Meter(this_)->done((Meter*)(this_))
#define Meter_updateModeFn(this_) As_Meter(this_)->updateMode
#define Meter_updateMode(this_, m_) As_Meter(this_)->updateMode((Meter*)(this_), m_)
#define Meter_drawFn(this_) As_Meter(this_)->draw
#define Meter_doneFn(this_) As_Meter(this_)->done
2020-10-06 11:13:16 +00:00
#define Meter_updateValues(this_) As_Meter(this_)->updateValues((Meter*)(this_))
Add a new DynamicMeter class for runtime Meter extension This commit is based on exploratory work by Sohaib Mohamed. The end goal is two-fold - to support addition of Meters we build via configuration files for both the PCP platform and for scripts ( https://github.com/htop-dev/htop/issues/526 ) Here, we focus on generic code and the PCP support. A new class DynamicMeter is introduced - it uses the special case 'param' field handling that previously was used only by the CPUMeter, such that every runtime-configured Meter is given a unique identifier. Unlike with the CPUMeter this is used internally only. When reading/writing to htoprc instead of CPU(N) - where N is an integer param (CPU number) - we use the string name for each meter. For example, if we have a configuration for a DynamicMeter for some Redis metrics, we might read and write "Dynamic(redis)". This identifier is subsequently matched (back) up to the configuration file so we're able to re-create arbitrary user configurations. The PCP platform configuration file format is fairly simple. We expand configs from several directories, including the users homedir alongside htoprc (below htop/meters/) and also /etc/pcp/htop/meters. The format will be described via a new pcp-htop(5) man page, but its basically ini-style and each Meter has one or more metric expressions associated, as well as specifications for labels, color and so on via a dot separated notation for individual metrics within the Meter. A few initial sample configuration files are provided below ./pcp/meters that give the general idea. The PCP "derived" metric specification - see pmRegisterDerived(3) - is used as the syntax for specifying metrics in PCP DynamicMeters.
2021-06-23 07:44:56 +00:00
#define Meter_getUiNameFn(this_) As_Meter(this_)->getUiName
#define Meter_getUiName(this_,n_,l_) As_Meter(this_)->getUiName((const Meter*)(this_),n_,l_)
#define Meter_getCaptionFn(this_) As_Meter(this_)->getCaption
#define Meter_getCaption(this_) (Meter_getCaptionFn(this_) ? As_Meter(this_)->getCaption((const Meter*)(this_)) : (this_)->caption)
#define Meter_defaultMode(this_) As_Meter(this_)->defaultMode
#define Meter_attributes(this_) As_Meter(this_)->attributes
#define Meter_name(this_) As_Meter(this_)->name
#define Meter_uiName(this_) As_Meter(this_)->uiName
2020-10-02 14:27:57 +00:00
typedef struct GraphData_ {
struct timeval time;
2020-10-06 11:13:16 +00:00
double values[METER_GRAPHDATA_SIZE];
2020-10-02 14:27:57 +00:00
} GraphData;
struct Meter_ {
Object super;
Meter_Draw draw;
2019-10-31 16:39:12 +00:00
char* caption;
int mode;
unsigned int param;
2020-10-02 14:27:57 +00:00
GraphData* drawData;
int h;
int columnWidthCount; /*<< only used internally by the Header */
const ProcessList* pl;
uint8_t curItems;
const int* curAttributes;
2020-10-06 11:13:16 +00:00
char txtBuffer[METER_TXTBUFFER_LEN];
2006-03-04 18:16:49 +00:00
double* values;
double total;
void* meterData;
2006-03-04 18:16:49 +00:00
};
typedef struct MeterMode_ {
Meter_Draw draw;
const char* uiName;
int h;
} MeterMode;
typedef enum {
CUSTOM_METERMODE = 0,
BAR_METERMODE,
TEXT_METERMODE,
GRAPH_METERMODE,
LED_METERMODE,
LAST_METERMODE
} MeterModeId;
2006-03-04 18:16:49 +00:00
2020-10-05 11:19:50 +00:00
extern const MeterClass Meter_class;
2006-03-04 18:16:49 +00:00
Meter* Meter_new(const ProcessList* pl, unsigned int param, const MeterClass* type);
2006-03-04 18:16:49 +00:00
int Meter_humanUnit(char* buffer, unsigned long int value, size_t size);
void Meter_delete(Object* cast);
2006-03-04 18:16:49 +00:00
void Meter_setCaption(Meter* this, const char* caption);
2006-03-04 18:16:49 +00:00
void Meter_setMode(Meter* this, int modeIndex);
2006-03-04 18:16:49 +00:00
ListItem* Meter_toListItem(const Meter* this, bool moving);
2006-03-04 18:16:49 +00:00
2020-10-05 11:19:50 +00:00
extern const MeterMode* const Meter_modes[];
2020-10-05 11:19:50 +00:00
extern const MeterClass BlankMeter_class;
2014-02-27 19:35:22 +00:00
2006-03-04 18:16:49 +00:00
#endif