/*
* mpstat: per-processor statistics
- * (C) 2000-2020 by Sebastien GODARD (sysstat <at> orange.fr)
+ * (C) 2000-2021 by Sebastien GODARD (sysstat <at> orange.fr)
*
***************************************************************************
* This program is free software; you can redistribute it and/or modify it *
progname);
fprintf(stderr, _("Options are:\n"
- "[ -A ] [ -n ] [-T] [ -u ] [ -V ]\n"
+ "[ -A ] [ -n ] [ -T ] [ -u ] [ -V ]\n"
"[ -I { SUM | CPU | SCPU | ALL } ] [ -N { <node_list> | ALL } ]\n"
"[ --dec={ 0 | 1 | 2 } ] [ -o JSON ] [ -P { <cpu_list> | ALL } ]\n"));
exit(1);
scp->cpu_steal + scp->cpu_softirq;
/*
- * If the CPU is offline then it is omited from /proc/stat:
+ * If the CPU is offline then it is omitted from /proc/stat:
* All the fields couldn't have been read and the sum of them is zero.
*/
if (tot_jiffies_c == 0) {
* @curr_string String displayed at the beginning of current sample stats.
* This is the timestamp of the current sample, or "Average"
* when displaying average stats.
+ * @offline_cpu_bitmap
+ * CPU bitmap for offline CPU.
***************************************************************************
*/
void write_plain_isumcpu_stats(int dis, unsigned long long itv, int prev, int curr,
- char *prev_string, char *curr_string)
+ char *prev_string, char *curr_string, unsigned char offline_cpu_bitmap[])
{
struct stats_cpu *scc, *scp;
struct stats_irq *sic, *sip;
scp = st_cpu[prev] + cpu;
/* Check if we want stats about this CPU */
- if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))))
+ if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))) ||
+ offline_cpu_bitmap[cpu >> 3] & (1 << (cpu & 0x07)))
continue;
- if ((scc->cpu_user + scc->cpu_nice + scc->cpu_sys +
- scc->cpu_iowait + scc->cpu_idle + scc->cpu_steal +
- scc->cpu_hardirq + scc->cpu_softirq) == 0) {
-
- /* This is an offline CPU */
- continue;
- }
-
printf("%-11s", curr_string);
cprintf_in(IS_INT, " %4d", "", cpu - 1);
* Stats used as reference may be the previous ones read, or
* the very first ones when calculating the average.
* @curr Position in array where current statistics will be saved.
+ * @offline_cpu_bitmap
+ * CPU bitmap for offline CPU.
***************************************************************************
*/
-void write_json_isumcpu_stats(int tab, unsigned long long itv, int prev, int curr)
+void write_json_isumcpu_stats(int tab, unsigned long long itv, int prev, int curr,
+ unsigned char offline_cpu_bitmap[])
{
struct stats_cpu *scc, *scp;
struct stats_irq *sic, *sip;
scp = st_cpu[prev] + cpu;
/* Check if we want stats about this CPU */
- if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))))
+ if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))) ||
+ offline_cpu_bitmap[cpu >> 3] & (1 << (cpu & 0x07)))
continue;
if (next) {
}
next = TRUE;
- if ((scc->cpu_user + scc->cpu_nice + scc->cpu_sys +
- scc->cpu_iowait + scc->cpu_idle + scc->cpu_steal +
- scc->cpu_hardirq + scc->cpu_softirq) == 0) {
-
- /* This is an offline CPU */
- continue;
- }
-
/* Recalculate itv for current proc */
pc_itv = get_per_cpu_interval(scc, scp);
* @tab Number of tabs to print (JSON format only).
* @next TRUE is a previous activity has been displayed (JSON format
* only).
+ * @offline_cpu_bitmap
+ * CPU bitmap for offline CPU.
***************************************************************************
*/
void write_isumcpu_stats(int dis, unsigned long long itv, int prev, int curr,
- char *prev_string, char *curr_string, int tab, int *next)
+ char *prev_string, char *curr_string, int tab, int *next,
+ unsigned char offline_cpu_bitmap[])
{
if (DISPLAY_JSON_OUTPUT(flags)) {
if (*next) {
printf(",\n");
}
*next = TRUE;
- write_json_isumcpu_stats(tab, itv, prev, curr);
+ write_json_isumcpu_stats(tab, itv, prev, curr, offline_cpu_bitmap);
}
else {
- write_plain_isumcpu_stats(dis, itv, prev, curr, prev_string, curr_string);
+ write_plain_isumcpu_stats(dis, itv, prev, curr, prev_string, curr_string,
+ offline_cpu_bitmap);
}
}
* @curr_string String displayed at the beginning of current sample stats.
* This is the timestamp of the current sample, or "Average"
* when displaying average stats.
+ * @offline_cpu_bitmap
+ * CPU bitmap for offline CPU.
***************************************************************************
*/
void write_plain_irqcpu_stats(struct stats_irqcpu *st_ic[], int ic_nr, int dis,
unsigned long long itv, int prev, int curr,
- char *prev_string, char *curr_string)
+ char *prev_string, char *curr_string, unsigned char offline_cpu_bitmap[])
{
- struct stats_cpu *scc;
int j = ic_nr, offset, cpu, colwidth[NR_IRQS];
struct stats_irqcpu *p, *q, *p0, *q0;
for (cpu = 1; cpu <= cpu_nr; cpu++) {
- scc = st_cpu[curr] + cpu;
-
/*
* Check if we want stats about this CPU.
* CPU must have been explicitly selected using option -P,
- * else we display every CPU.
+ * else we display every CPU (unless it's offline).
*/
- if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))) && USE_OPTION_P(flags))
- continue;
-
- if ((scc->cpu_user + scc->cpu_nice + scc->cpu_sys +
- scc->cpu_iowait + scc->cpu_idle + scc->cpu_steal +
- scc->cpu_hardirq + scc->cpu_softirq) == 0)
- /* Offline CPU found */
+ if ((!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))) && USE_OPTION_P(flags)) ||
+ offline_cpu_bitmap[cpu >> 3] & (1 << (cpu & 0x07)))
continue;
printf("%-11s", curr_string);
* the very first ones when calculating the average.
* @curr Position in array where current statistics will be saved.
* @type Activity (M_D_IRQ_CPU or M_D_SOFTIRQS).
+ * @offline_cpu_bitmap
+ * CPU bitmap for offline CPU.
***************************************************************************
*/
void write_json_irqcpu_stats(int tab, struct stats_irqcpu *st_ic[], int ic_nr,
- unsigned long long itv, int prev, int curr, int type)
+ unsigned long long itv, int prev, int curr, int type,
+ unsigned char offline_cpu_bitmap[])
{
- struct stats_cpu *scc;
int j = ic_nr, offset, cpu;
struct stats_irqcpu *p, *q, *p0, *q0;
int nextcpu = FALSE, nextirq;
for (cpu = 1; cpu <= cpu_nr; cpu++) {
- scc = st_cpu[curr] + cpu;
-
/*
* Check if we want stats about this CPU.
* CPU must have been explicitly selected using option -P,
- * else we display every CPU.
+ * else we display every CPU (unless it's offline).
*/
- if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))) && USE_OPTION_P(flags))
- continue;
-
- if ((scc->cpu_user + scc->cpu_nice + scc->cpu_sys +
- scc->cpu_iowait + scc->cpu_idle + scc->cpu_steal +
- scc->cpu_hardirq + scc->cpu_softirq) == 0)
- /* Offline CPU found */
+ if ((!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))) && USE_OPTION_P(flags)) ||
+ offline_cpu_bitmap[cpu >> 3] & (1 << (cpu & 0x07)))
continue;
if (nextcpu) {
* @next TRUE is a previous activity has been displayed (JSON format
* only).
* @type Activity (M_D_IRQ_CPU or M_D_SOFTIRQS).
+ * @offline_cpu_bitmap
+ * CPU bitmap for offline CPU.
***************************************************************************
*/
void write_irqcpu_stats(struct stats_irqcpu *st_ic[], int ic_nr, int dis,
unsigned long long itv, int prev, int curr,
char *prev_string, char *curr_string, int tab,
- int *next, int type)
+ int *next, int type, unsigned char offline_cpu_bitmap[])
{
if (DISPLAY_JSON_OUTPUT(flags)) {
if (*next) {
printf(",\n");
}
*next = TRUE;
- write_json_irqcpu_stats(tab, st_ic, ic_nr, itv, prev, curr, type);
+ write_json_irqcpu_stats(tab, st_ic, ic_nr, itv, prev, curr, type,
+ offline_cpu_bitmap);
}
else {
write_plain_irqcpu_stats(st_ic, ic_nr, dis, itv, prev, curr,
- prev_string, curr_string);
+ prev_string, curr_string, offline_cpu_bitmap);
}
}
/* Print total number of interrupts per processor */
if (DISPLAY_IRQ_SUM(actflags)) {
write_isumcpu_stats(dis, itv, prev, curr, prev_string, curr_string,
- tab, &next);
+ tab, &next, offline_cpu_bitmap);
}
/* Display each interrupt value for each CPU */
if (DISPLAY_IRQ_CPU(actflags)) {
write_irqcpu_stats(st_irqcpu, irqcpu_nr, dis, itv, prev, curr,
- prev_string, curr_string, tab, &next, M_D_IRQ_CPU);
+ prev_string, curr_string, tab, &next, M_D_IRQ_CPU,
+ offline_cpu_bitmap);
}
if (DISPLAY_SOFTIRQS(actflags)) {
write_irqcpu_stats(st_softirqcpu, softirqcpu_nr, dis, itv, prev, curr,
- prev_string, curr_string, tab, &next, M_D_SOFTIRQS);
+ prev_string, curr_string, tab, &next, M_D_SOFTIRQS,
+ offline_cpu_bitmap);
}
if (DISPLAY_JSON_OUTPUT(flags)) {
int curr = 1, dis = 1;
unsigned long lines = rows;
- /* Dont buffer data if redirected to a pipe */
- setbuf(stdout, NULL);
-
/* Read system uptime and CPU stats */
read_uptime(&(uptime_cs[0]));
read_stat_cpu(st_cpu[0], cpu_nr + 1);
/* Get time */
get_localtime(&(mp_tstamp[0]), 0);
+ /*
+ * Don't buffer data if redirected to a pipe.
+ * Note: With musl-c, the behavior of this function is undefined except
+ * when it is the first operation on the stream.
+ */
+ setbuf(stdout, NULL);
+
/* Get system name, release number and hostname */
__uname(&header);
print_gal_header(&(mp_tstamp[0]), header.sysname, header.release,