Base: LCDproc 0.5.2
[lcdproc-de200c.git] / clients / lcdproc / cpu_smp.c
blobe0a41cd58ed8e7ccd1b537fbe65fcfbbc1a0b68e
1 /******************************************************************************
3 * cpu_smp.c - dipslay cpu info for multi-processor machines
4 * Copyright (C) 2000 J Robert Ray
5 * Copyright (C) 2006,7 Peter Marschall
7 * Adapted from cpu.c.
9 * Really boring for the moment, it only shows a current usage percentage graph
10 * for each CPU.
12 * It will handle up to 2xlcd_hgt or 8 CPUs, whichever is less. If there are
13 * more CPUs than lines on the LCD, it puts 2 CPUs per line, splitting the line
14 * in half. Otherwise, it uses one line per CPU.
16 * If the number of lines used to display the bar graphs for the CPUs is smaller
17 * than the LCD's height, a title line is introduced, so that the screen looks
18 * similar to other lcdproc screens.
19 * In all other cases (i.e. #CPUs == LCD height or #CPUs >= 2 * LCD height),
20 * the title is left out to display as many CPUs graphs as possible.
22 * ---
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * as published by the Free Software Foundation; either version 2
27 * of the License, or (at your option) any later version.
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software Foundation,
36 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
38 *******************************************************************************/
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <ctype.h>
47 #include "shared/sockets.h"
48 #include "shared/debug.h"
50 #include "main.h"
51 #include "mode.h"
52 #include "machine.h"
53 #include "cpu_smp.h"
56 //////////////////////////////////////////////////////////////////////////
57 // CPU screen shows info about percentage of the CPU being used
59 int
60 cpu_smp_screen (int rep, int display, int *flags_ptr)
62 #undef CPU_BUF_SIZE
63 #define CPU_BUF_SIZE 4
64 int z;
65 static float cpu[MAX_CPUS][CPU_BUF_SIZE + 1]; // last buffer is scratch
66 load_type load[MAX_CPUS];
67 int num_cpus = MAX_CPUS;
68 int bar_size;
69 int lines_used;
71 // get SMP load - inform about max #CPUs allowed
72 machine_get_smpload(load, &num_cpus);
74 // restrict num_cpus to max. twice the display height
75 if (num_cpus > 2 * lcd_hgt)
76 num_cpus = 2 * lcd_hgt;
78 // 2 CPUs per line if more CPUs than lines
79 bar_size = (num_cpus > lcd_hgt) ? (lcd_wid / 2 - 6) : (lcd_wid - 6);
80 lines_used = (num_cpus > lcd_hgt) ? (num_cpus + 1) / 2 : num_cpus;
82 if ((*flags_ptr & INITIALIZED) == 0) {
83 *flags_ptr |= INITIALIZED;
85 sock_send_string(sock, "screen_add P\n");
87 // print title if he have room for it
88 if (lines_used < lcd_hgt) {
89 sock_send_string(sock, "widget_add P title title\n");
90 sock_printf(sock, "widget_set P title {SMP CPU %s}\n", get_hostname());
92 else {
93 sock_send_string(sock, "screen_set P -heartbeat off\n");
96 sock_printf(sock, "screen_set P -name {CPU Use: %s}\n", get_hostname());
98 for (z = 0; z < num_cpus; z++) {
99 int y_offs = (lines_used < lcd_hgt) ? 2 : 1;
100 int x = (num_cpus > lcd_hgt) ? ((z % 2) * (lcd_wid/2) + 1) : 1;
101 int y = (num_cpus > lcd_hgt) ? (z/2 + y_offs) : (z + y_offs);
103 sock_printf(sock, "widget_add P cpu%d_title string\n", z);
104 sock_printf(sock, "widget_set P cpu%d_title %d %d \"CPU%d[%*s]\"\n",
105 z, x, y, z, bar_size, "");
106 sock_printf(sock, "widget_add P cpu%d_bar hbar\n", z);
109 return 0;
112 for (z = 0; z < num_cpus; z++) {
113 int y_offs = (lines_used < lcd_hgt) ? 2 : 1;
114 int x = (num_cpus > lcd_hgt) ? ((z % 2) * (lcd_wid/2) + 6) : 6;
115 int y = (num_cpus > lcd_hgt) ? (z/2 + y_offs) : (z + y_offs);
116 float value = 0.0;
117 int i, n;
119 // Shift values over by one
120 for (i = 0; i < (CPU_BUF_SIZE - 1); i++)
121 cpu[z][i] = cpu[z][i + 1];
123 // Read new data
124 cpu[z][CPU_BUF_SIZE-1] = (load[z].total > 0L)
125 ? (((float) load[z].user + (float) load[z].system + (float) load[z].nice) / (float) load[z].total) * 100.0
126 : 0.0;
128 // Average values for final result
129 for (i = 0; i < CPU_BUF_SIZE; i++) {
130 value += cpu[z][i];
132 value /= CPU_BUF_SIZE;
134 n = (int) ((value * lcd_cellwid * bar_size) / 100.0 + 0.5);
135 sock_printf(sock, "widget_set P cpu%d_bar %d %d %d\n", z, x, y, n);
138 return 0;
139 } // End cpu_screen()