File: cpu_smp.c

package info (click to toggle)
lcdproc 0.5.9-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 5,064 kB
  • sloc: ansic: 59,645; sh: 1,740; perl: 681; makefile: 417
file content (133 lines) | stat: -rw-r--r-- 3,963 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/** \file clients/lcdproc/cpu_smp.c
 * Display cpu info for multi-processor machines.
 *
 * Adapted from cpu.c.
 *
 * Really boring for the moment, it only shows a current usage percentage graph
 * for each CPU.
 *
 * It will handle up to 2xlcd_hgt or 8 CPUs, whichever is less.  If there are
 * more CPUs than lines on the LCD, it puts 2 CPUs per line, splitting the line
 * in half.  Otherwise, it uses one line per CPU.
 *
 * If the number of lines used to display the bar graphs for the CPUs is smaller
 * than the LCD's height, a title line is introduced, so that the screen looks
 * similar to other lcdproc screens.
 * In all other cases (i.e. \#CPUs == LCD height or \#CPUs >= 2 * LCD height),
 * the title is left out to display as many CPUs graphs as possible.
 */

/*-
 * Copyright (C) 2000       J Robert Ray
 * Copyright (C) 2006,2007  Peter Marschall
 *
 * This file is part of lcdproc, the lcdproc client.
 *
 * This file is released under the GNU General Public License.
 * Refer to the COPYING file distributed with this package.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>

#include "shared/sockets.h"

#include "main.h"
#include "mode.h"
#include "machine.h"
#include "cpu_smp.h"


/**
 * CPU screen shows info about percentage of the CPU being used
 *
 * \param rep        Time since last screen update
 * \param display    1 if screen is visible or data should be updated
 * \param flags_ptr  Mode flags
 * \return  Always 0
 */
int
cpu_smp_screen (int rep, int display, int *flags_ptr)
{
#undef CPU_BUF_SIZE
#define CPU_BUF_SIZE 4
	int z;
	static float cpu[MAX_CPUS][CPU_BUF_SIZE + 1];	/* last buffer is scratch */
	load_type load[MAX_CPUS];
	int num_cpus = MAX_CPUS;
	int bar_size;
	int lines_used;

	/* get SMP load - inform about max #CPUs allowed */
	machine_get_smpload(load, &num_cpus);

	/* restrict num_cpus to max. twice the display height */
	if (num_cpus > 2 * lcd_hgt)
		num_cpus = 2 * lcd_hgt;

	/* 2 CPUs per line if more CPUs than lines */
	bar_size = (num_cpus > lcd_hgt) ? (lcd_wid / 2 - 6) : (lcd_wid - 6);
	lines_used = (num_cpus > lcd_hgt) ? (num_cpus + 1) / 2 : num_cpus;

	if ((*flags_ptr & INITIALIZED) == 0) {
		*flags_ptr |= INITIALIZED;

		sock_send_string(sock, "screen_add P\n");

		/* print title if he have room for it */
		if (lines_used < lcd_hgt) {
			sock_send_string(sock, "widget_add P title title\n");
			sock_printf(sock, "widget_set P title {SMP CPU %s}\n", get_hostname());
		}
		else {
			sock_send_string(sock, "screen_set P -heartbeat off\n");
		}

		sock_printf(sock, "screen_set P -name {CPU Use: %s}\n", get_hostname());

		for (z = 0; z < num_cpus; z++) {
			int y_offs = (lines_used < lcd_hgt) ? 2 : 1;
			int x = (num_cpus > lcd_hgt) ? ((z % 2) * (lcd_wid/2) + 1) : 1;
			int y = (num_cpus > lcd_hgt) ? (z/2 + y_offs) : (z + y_offs);

			sock_printf(sock, "widget_add P cpu%d_title string\n", z);
			sock_printf(sock, "widget_set P cpu%d_title %d %d \"CPU%d[%*s]\"\n",
					z, x, y, z, bar_size, "");
			sock_printf(sock, "widget_add P cpu%d_bar hbar\n", z);
		}

		return 0;
	}

	for (z = 0; z < num_cpus; z++) {
		int y_offs = (lines_used < lcd_hgt) ? 2 : 1;
		int x = (num_cpus > lcd_hgt) ? ((z % 2) * (lcd_wid/2) + 6) : 6;
		int y = (num_cpus > lcd_hgt) ? (z/2 + y_offs) : (z + y_offs);
		float value = 0.0;
		int i, n;

		/* Shift values over by one */
		for (i = 0; i < (CPU_BUF_SIZE - 1); i++)
			cpu[z][i] = cpu[z][i + 1];

		/* Read new data */
		cpu[z][CPU_BUF_SIZE-1] = (load[z].total > 0L)
				    ? (((float) load[z].user + (float) load[z].system + (float) load[z].nice) / (float) load[z].total) * 100.0
				    : 0.0;

		/* Average values for final result */
		for (i = 0; i < CPU_BUF_SIZE; i++) {
			value += cpu[z][i];
		}
		value /= CPU_BUF_SIZE;

		n = (int) ((value * lcd_cellwid * bar_size) / 100.0 + 0.5);
		sock_printf(sock, "widget_set P cpu%d_bar %d %d %d\n", z, x, y, n);
	}

	return 0;
}