1 /**************************************************************************
3 * Copyright 2013 Marek Olšák <maraeo@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 /* This file contains code for reading CPU load for displaying on the HUD.
31 #include "hud/hud_private.h"
32 #include "os/os_time.h"
33 #include "util/u_memory.h"
38 get_cpu_stats(unsigned cpu_index
, uint64_t *busy_time
, uint64_t *total_time
)
44 if (cpu_index
== ALL_CPUS
)
45 strcpy(cpuname
, "cpu");
47 sprintf(cpuname
, "cpu%u", cpu_index
);
49 f
= fopen("/proc/stat", "r");
53 while (!feof(f
) && fgets(line
, sizeof(line
), f
)) {
54 if (strstr(line
, cpuname
) == line
) {
59 "%s %"PRIu64
" %"PRIu64
" %"PRIu64
" %"PRIu64
" %"PRIu64
60 " %"PRIu64
" %"PRIu64
" %"PRIu64
" %"PRIu64
" %"PRIu64
61 " %"PRIu64
" %"PRIu64
"",
62 cpuname
, &v
[0], &v
[1], &v
[2], &v
[3], &v
[4], &v
[5],
63 &v
[6], &v
[7], &v
[8], &v
[9], &v
[10], &v
[11]);
69 /* user + nice + system */
70 *busy_time
= v
[0] + v
[1] + v
[2];
71 *total_time
= *busy_time
;
73 /* ... + idle + iowait + irq + softirq + ... */
74 for (i
= 3; i
< num
-1; i
++) {
87 uint64_t last_cpu_busy
, last_cpu_total
, last_time
;
91 query_cpu_load(struct hud_graph
*gr
)
93 struct cpu_info
*info
= gr
->query_data
;
94 uint64_t now
= os_time_get();
96 if (info
->last_time
) {
97 if (info
->last_time
+ gr
->pane
->period
<= now
) {
98 uint64_t cpu_busy
, cpu_total
, cpu_load
;
100 get_cpu_stats(info
->cpu_index
, &cpu_busy
, &cpu_total
);
102 cpu_load
= (cpu_busy
- info
->last_cpu_busy
) * 100 /
103 (double)(cpu_total
- info
->last_cpu_total
);
104 hud_graph_add_value(gr
, cpu_load
);
106 info
->last_cpu_busy
= cpu_busy
;
107 info
->last_cpu_total
= cpu_total
;
108 info
->last_time
= now
;
113 info
->last_time
= now
;
114 get_cpu_stats(info
->cpu_index
, &info
->last_cpu_busy
,
115 &info
->last_cpu_total
);
120 free_query_data(void *p
)
126 hud_cpu_graph_install(struct hud_pane
*pane
, unsigned cpu_index
)
128 struct hud_graph
*gr
;
129 struct cpu_info
*info
;
130 uint64_t busy
, total
;
132 /* see if the cpu exists */
133 if (cpu_index
!= ALL_CPUS
&& !get_cpu_stats(cpu_index
, &busy
, &total
)) {
137 gr
= CALLOC_STRUCT(hud_graph
);
141 if (cpu_index
== ALL_CPUS
)
142 strcpy(gr
->name
, "cpu");
144 sprintf(gr
->name
, "cpu%u", cpu_index
);
146 gr
->query_data
= CALLOC_STRUCT(cpu_info
);
147 if (!gr
->query_data
) {
152 gr
->query_new_value
= query_cpu_load
;
154 /* Don't use free() as our callback as that messes up Gallium's
155 * memory debugger. Use simple free_query_data() wrapper.
157 gr
->free_query_data
= free_query_data
;
159 info
= gr
->query_data
;
160 info
->cpu_index
= cpu_index
;
162 hud_pane_add_graph(pane
, gr
);
163 hud_pane_set_max_value(pane
, 100);
167 hud_get_num_cpus(void)
169 uint64_t busy
, total
;
172 while (get_cpu_stats(i
, &busy
, &total
))