summaryrefslogtreecommitdiffstats
path: root/CPUMeter.c
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2020-09-23 11:58:11 +0200
committercgzones <cgzones@googlemail.com>2020-10-12 13:15:23 +0200
commit9f5b50edd78111a42b5824f3725794f8762326d2 (patch)
treeb207995e874d37832ce5ebca271606c8fe93e633 /CPUMeter.c
parent0b9a0014989b8557eb16697984d9fd02b59bf47a (diff)
CPUMeter: avoid crashes and leaks in case the CPU count changes
E.g. if the HT/SMT mode changes Use separate data for sub-meters Do not reuse drawData for maintainability
Diffstat (limited to 'CPUMeter.c')
-rw-r--r--CPUMeter.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/CPUMeter.c b/CPUMeter.c
index c1ccb12c..446c04d2 100644
--- a/CPUMeter.c
+++ b/CPUMeter.c
@@ -27,6 +27,11 @@ static const int CPUMeter_attributes[] = {
CPU_IOWAIT
};
+typedef struct CPUMeterData_ {
+ int cpus;
+ Meter** meters;
+} CPUMeterData;
+
static void CPUMeter_init(Meter* this) {
int cpu = this->param;
if (this->pl->cpuCount > 1) {
@@ -42,6 +47,9 @@ static void CPUMeter_updateValues(Meter* this, char* buffer, int size) {
int cpu = this->param;
if (cpu > this->pl->cpuCount) {
xSnprintf(buffer, size, "absent");
+ int items = this->curItems;
+ for (int i = 0; i < items; i++)
+ this->values[i] = 0;
return;
}
memset(this->values, 0, sizeof(double) * CPU_METER_ITEMCOUNT);
@@ -119,7 +127,8 @@ static void CPUMeter_display(const Object* cast, RichString* out) {
}
static void AllCPUsMeter_getRange(Meter* this, int* start, int* count) {
- int cpus = this->pl->cpuCount;
+ CPUMeterData* data = this->meterData;
+ int cpus = data->cpus;
switch(Meter_name(this)[0]) {
default:
case 'A': // All
@@ -139,9 +148,13 @@ static void AllCPUsMeter_getRange(Meter* this, int* start, int* count) {
static void CPUMeterCommonInit(Meter *this, int ncol) {
int cpus = this->pl->cpuCount;
- if (!this->drawData)
- this->drawData = xCalloc(cpus, sizeof(Meter*));
- Meter** meters = (Meter**) this->drawData;
+ CPUMeterData* data = this->meterData;
+ if (!data) {
+ data = this->meterData = xMalloc(sizeof(CPUMeterData));
+ data->cpus = cpus;
+ data->meters = xCalloc(cpus, sizeof(Meter*));
+ }
+ Meter** meters = data->meters;
int start, count;
AllCPUsMeter_getRange(this, &start, &count);
for (int i = 0; i < count; i++) {
@@ -156,7 +169,8 @@ static void CPUMeterCommonInit(Meter *this, int ncol) {
}
static void CPUMeterCommonUpdateMode(Meter* this, int mode, int ncol) {
- Meter** meters = (Meter**) this->drawData;
+ CPUMeterData* data = this->meterData;
+ Meter** meters = data->meters;
this->mode = mode;
int h = Meter_modes[mode]->h;
int start, count;
@@ -168,11 +182,14 @@ static void CPUMeterCommonUpdateMode(Meter* this, int mode, int ncol) {
}
static void AllCPUsMeter_done(Meter* this) {
- Meter** meters = (Meter**) this->drawData;
+ CPUMeterData* data = this->meterData;
+ Meter** meters = data->meters;
int start, count;
AllCPUsMeter_getRange(this, &start, &count);
for (int i = 0; i < count; i++)
Meter_delete((Object*)meters[i]);
+ free(data->meters);
+ free(data);
}
static void SingleColCPUsMeter_init(Meter* this) {
@@ -208,18 +225,19 @@ static void OctoColCPUsMeter_updateMode(Meter* this, int mode) {
}
static void CPUMeterCommonDraw(Meter* this, int x, int y, int w, int ncol) {
- Meter** meters = (Meter**) this->drawData;
- int start, count;
- AllCPUsMeter_getRange(this, &start, &count);
- int colwidth = (w-ncol)/ncol + 1;
- int diff = (w - (colwidth * ncol));
- int nrows = (count + ncol - 1) / ncol;
- for (int i = 0; i < count; i++){
- int d = (i/nrows) > diff ? diff : (i / nrows) ; // dynamic spacer
- int xpos = x + ((i / nrows) * colwidth) + d;
- int ypos = y + ((i % nrows) * meters[0]->h);
- meters[i]->draw(meters[i], xpos, ypos, colwidth);
- }
+ CPUMeterData* data = this->meterData;
+ Meter** meters = data->meters;
+ int start, count;
+ AllCPUsMeter_getRange(this, &start, &count);
+ int colwidth = (w-ncol)/ncol + 1;
+ int diff = (w - (colwidth * ncol));
+ int nrows = (count + ncol - 1) / ncol;
+ for (int i = 0; i < count; i++){
+ int d = (i/nrows) > diff ? diff : (i / nrows) ; // dynamic spacer
+ int xpos = x + ((i / nrows) * colwidth) + d;
+ int ypos = y + ((i % nrows) * meters[0]->h);
+ meters[i]->draw(meters[i], xpos, ypos, colwidth);
+ }
}
static void DualColCPUsMeter_draw(Meter* this, int x, int y, int w) {
@@ -236,7 +254,8 @@ static void OctoColCPUsMeter_draw(Meter* this, int x, int y, int w) {
static void SingleColCPUsMeter_draw(Meter* this, int x, int y, int w) {
- Meter** meters = (Meter**) this->drawData;
+ CPUMeterData* data = this->meterData;
+ Meter** meters = data->meters;
int start, count;
AllCPUsMeter_getRange(this, &start, &count);
for (int i = 0; i < count; i++) {

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