CPUMeter.c 4.99 KB
Newer Older
Hisham Muhammad's avatar
Hisham Muhammad committed
1
2
/*
htop - CPUMeter.c
Hisham Muhammad's avatar
Hisham Muhammad committed
3
(C) 2004-2006 Hisham H. Muhammad
Hisham Muhammad's avatar
Hisham Muhammad committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/

#include "CPUMeter.h"
#include "Meter.h"

#include "ProcessList.h"

#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <math.h>

#include "debug.h"
#include <assert.h>

21
int CPUMeter_attributes[] = {
22
   CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IRQ, CPU_SOFTIRQ, CPU_IOWAIT
23
};
Hisham Muhammad's avatar
Hisham Muhammad committed
24

25
26
27
28
MeterType CPUMeter = {
   .setValues = CPUMeter_setValues, 
   .display = CPUMeter_display,
   .mode = BAR_METERMODE,
29
   .items = 6,
30
31
32
33
34
35
   .total = 100.0,
   .attributes = CPUMeter_attributes, 
   .name = "CPU",
   .uiName = "CPU",
   .caption = "CPU",
   .init = CPUMeter_init
Hisham Muhammad's avatar
Hisham Muhammad committed
36
37
};

38
39
40
41
42
43
44
45
46
47
MeterType AllCPUsMeter = {
   .mode = 0,
   .items = 1,
   .total = 100.0,
   .attributes = CPUMeter_attributes, 
   .name = "AllCPUs",
   .uiName = "All CPUs",
   .caption = "CPU",
   .draw = AllCPUsMeter_draw,
   .init = AllCPUsMeter_init,
48
   .setMode = AllCPUsMeter_setMode,
49
50
   .done = AllCPUsMeter_done
};
Hisham Muhammad's avatar
Hisham Muhammad committed
51
52
53
54
55
56
57
58

#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif

59
60
61
62
void CPUMeter_init(Meter* this) {
   int processor = this->param;
   if (this->pl->processorCount > 1) {
      char caption[10];
Hisham Muhammad's avatar
Hisham Muhammad committed
63
      sprintf(caption, "%-3d", processor);
64
      Meter_setCaption(this, caption);
Hisham Muhammad's avatar
Hisham Muhammad committed
65
   }
66
67
   if (this->param == 0)
      Meter_setCaption(this, "Avg");
Hisham Muhammad's avatar
Hisham Muhammad committed
68
69
}

70
71
72
73
void CPUMeter_setValues(Meter* this, char* buffer, int size) {
   ProcessList* pl = this->pl;
   int processor = this->param;
   double total = (double) pl->totalPeriod[processor];
74
   double cpu;
75
76
   this->values[0] = pl->nicePeriod[processor] / total * 100.0;
   this->values[1] = pl->userPeriod[processor] / total * 100.0;
77
   if (pl->detailedCPUTime) {
78
      this->values[2] = pl->systemPeriod[processor] / total * 100.0;
79
80
81
      this->values[3] = pl->irqPeriod[processor] / total * 100.0;
      this->values[4] = pl->softIrqPeriod[processor] / total * 100.0;
      this->values[5] = pl->ioWaitPeriod[processor] / total * 100.0;
82
83
      this->type->items = 6;
      cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+
84
                       this->values[3]+this->values[4])));
85
86
87
88
89
   } else {
      this->values[2] = pl->systemAllPeriod[processor] / total * 100.0;
      this->type->items = 3;
      cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2])));
   }
90
   snprintf(buffer, size, "%5.1f%%", cpu );
Hisham Muhammad's avatar
Hisham Muhammad committed
91
92
93
94
95
}

void CPUMeter_display(Object* cast, RichString* out) {
   char buffer[50];
   Meter* this = (Meter*)cast;
96
   RichString_init(out);
97
   sprintf(buffer, "%5.1f%% ", this->values[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
98
99
   RichString_append(out, CRT_colors[METER_TEXT], ":");
   RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
100
   if (this->pl->detailedCPUTime) {
101
102
103
104
105
106
107
108
109
110
111
112
      sprintf(buffer, "%5.1f%% ", this->values[2]);
      RichString_append(out, CRT_colors[METER_TEXT], "sy:");
      RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
      sprintf(buffer, "%5.1f%% ", this->values[0]);
      RichString_append(out, CRT_colors[METER_TEXT], "ni:");
      RichString_append(out, CRT_colors[CPU_NICE], buffer);
      sprintf(buffer, "%5.1f%% ", this->values[3]);
      RichString_append(out, CRT_colors[METER_TEXT], "hi:");
      RichString_append(out, CRT_colors[CPU_IRQ], buffer);
      sprintf(buffer, "%5.1f%% ", this->values[4]);
      RichString_append(out, CRT_colors[METER_TEXT], "si:");
      RichString_append(out, CRT_colors[CPU_SOFTIRQ], buffer);
113
114
115
      sprintf(buffer, "%5.1f%% ", this->values[5]);
      RichString_append(out, CRT_colors[METER_TEXT], "wa:");
      RichString_append(out, CRT_colors[CPU_IOWAIT], buffer);
116
117
118
119
120
121
122
123
   } else {
      sprintf(buffer, "%5.1f%% ", this->values[2]);
      RichString_append(out, CRT_colors[METER_TEXT], "sys:");
      RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
      sprintf(buffer, "%5.1f%% ", this->values[0]);
      RichString_append(out, CRT_colors[METER_TEXT], "low:");
      RichString_append(out, CRT_colors[CPU_NICE], buffer);
   }
Hisham Muhammad's avatar
Hisham Muhammad committed
124
}
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

void AllCPUsMeter_init(Meter* this) {
   int processors = this->pl->processorCount;
   this->drawBuffer = malloc(sizeof(Meter*) * processors);
   Meter** meters = (Meter**) this->drawBuffer;
   for (int i = 0; i < processors; i++)
      meters[i] = Meter_new(this->pl, i+1, &CPUMeter);
   this->h = processors;
   this->mode = BAR_METERMODE;
}

void AllCPUsMeter_done(Meter* this) {
   int processors = this->pl->processorCount;
   Meter** meters = (Meter**) this->drawBuffer;
   for (int i = 0; i < processors; i++)
      Meter_delete((Object*)meters[i]);
}

143
144
145
146
147
148
149
void AllCPUsMeter_setMode(Meter* this, int mode) {
   this->mode = mode;
   int processors = this->pl->processorCount;
   int h = Meter_modes[this->mode]->h;
   this->h = h * processors;
}

150
151
152
153
154
void AllCPUsMeter_draw(Meter* this, int x, int y, int w) {
   int processors = this->pl->processorCount;
   Meter** meters = (Meter**) this->drawBuffer;
   for (int i = 0; i < processors; i++) {
      Meter_setMode(meters[i], this->mode);
155
156
      meters[i]->draw(meters[i], x, y, w);
      y += meters[i]->h;
157
158
   }
}