mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
77460a9075
(This used to be commit 59c00924b6
)
191 lines
5.7 KiB
C
191 lines
5.7 KiB
C
/*
|
|
* Unix SMB/CIFS implementation.
|
|
* Performance Counter Daemon
|
|
*
|
|
* Copyright (C) Marcin Krzysztof Porwit 2005
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "perf.h"
|
|
|
|
void init_cpudata_desc(PERF_DATA_BLOCK *data)
|
|
{
|
|
init_perf_counter(&(data->cpuInfo.cpuObjDesc),
|
|
&(data->cpuInfo.cpuObjDesc),
|
|
get_counter_id(data),
|
|
"Processor",
|
|
"The Processor object consists of counters that describe the behavior of the CPU.",
|
|
0,
|
|
PERF_OBJECT);
|
|
init_perf_counter(&(data->cpuInfo.userCPU),
|
|
&(data->cpuInfo.cpuObjDesc),
|
|
get_counter_id(data),
|
|
"\% User CPU Utilization",
|
|
"\% User CPU Utilization is the percentage of the CPU used by processes executing user code.",
|
|
PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
|
|
PERF_COUNTER);
|
|
init_perf_counter(&(data->cpuInfo.systemCPU),
|
|
&(data->cpuInfo.cpuObjDesc),
|
|
get_counter_id(data),
|
|
"\% System CPU Utilization",
|
|
"\% System CPU Utilization is the percentage of the CPU used by processes doing system calls.",
|
|
PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
|
|
PERF_COUNTER);
|
|
init_perf_counter(&(data->cpuInfo.niceCPU),
|
|
&(data->cpuInfo.cpuObjDesc),
|
|
get_counter_id(data),
|
|
"\% Nice CPU Utilization",
|
|
"\% Nice CPU Utilization is the percentage of the CPU used by processes running in nice mode.",
|
|
PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NOSHOW,
|
|
PERF_COUNTER);
|
|
init_perf_counter(&(data->cpuInfo.idleCPU),
|
|
&(data->cpuInfo.cpuObjDesc),
|
|
get_counter_id(data),
|
|
"\% Idle CPU",
|
|
"\% Idle CPU is the percentage of the CPU not doing any work.",
|
|
PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NOSHOW,
|
|
PERF_COUNTER);
|
|
|
|
return;
|
|
}
|
|
|
|
void get_cpuinfo(PERF_DATA_BLOCK *data)
|
|
{
|
|
int num, i;
|
|
unsigned int cpuid;
|
|
char buf[PROC_BUF];
|
|
static FILE *fp = NULL;
|
|
|
|
if(!fp)
|
|
{
|
|
if(!(fp = fopen("/proc/stat", "r")))
|
|
{
|
|
perror("get_cpuinfo: fopen");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
rewind(fp);
|
|
fflush(fp);
|
|
|
|
/* Read in the first line and discard it -- that has the CPU summary */
|
|
if(!fgets(buf, sizeof(buf), fp))
|
|
{
|
|
perror("get_cpuinfo: fgets");
|
|
exit(1);
|
|
}
|
|
for(i = 0; i < data->cpuInfo.numCPUs; i++)
|
|
{
|
|
if(!fgets(buf, sizeof(buf), fp))
|
|
{
|
|
perror("get_cpuinfo: fgets");
|
|
exit(1);
|
|
}
|
|
num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu",
|
|
&cpuid,
|
|
&data->cpuInfo.data[i].user,
|
|
&data->cpuInfo.data[i].nice,
|
|
&data->cpuInfo.data[i].system,
|
|
&data->cpuInfo.data[i].idle);
|
|
if(i != cpuid)
|
|
{
|
|
perror("get_cpuinfo: /proc/stat inconsistent?");
|
|
exit(1);
|
|
}
|
|
/*
|
|
Alternate way of doing things:
|
|
struct tms buffer;
|
|
data->PerfTime100nSec = times(&buffer);
|
|
*/
|
|
data->PerfTime100nSec += data->cpuInfo.data[i].user +
|
|
data->cpuInfo.data[i].nice +
|
|
data->cpuInfo.data[i].system +
|
|
data->cpuInfo.data[i].idle;
|
|
}
|
|
data->PerfTime100nSec /= data->cpuInfo.numCPUs;
|
|
return;
|
|
}
|
|
|
|
void init_cpu_data(PERF_DATA_BLOCK *data)
|
|
{
|
|
data->cpuInfo.data = calloc(data->cpuInfo.numCPUs, sizeof(*data->cpuInfo.data));
|
|
if(!data->cpuInfo.data)
|
|
{
|
|
perror("init_cpu_data: out of memory");
|
|
exit(1);
|
|
}
|
|
|
|
init_cpudata_desc(data);
|
|
|
|
get_cpuinfo(data);
|
|
|
|
return;
|
|
}
|
|
|
|
void output_cpu_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt)
|
|
{
|
|
output_perf_desc(data->cpuInfo.cpuObjDesc, rt);
|
|
output_perf_desc(data->cpuInfo.userCPU, rt);
|
|
output_perf_desc(data->cpuInfo.niceCPU, rt);
|
|
output_perf_desc(data->cpuInfo.systemCPU, rt);
|
|
output_perf_desc(data->cpuInfo.idleCPU, rt);
|
|
if(data->cpuInfo.numCPUs > 1)
|
|
output_num_instances(data->cpuInfo.cpuObjDesc, data->cpuInfo.numCPUs + 1, rt);
|
|
|
|
return;
|
|
}
|
|
|
|
void output_cpuinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
|
|
{
|
|
int i;
|
|
char buf[NAME_LEN];
|
|
|
|
output_perf_counter(data->cpuInfo.userCPU,
|
|
data->cpuInfo.data[0].user,
|
|
rt, tdb_flags);
|
|
output_perf_counter(data->cpuInfo.systemCPU,
|
|
data->cpuInfo.data[0].system,
|
|
rt, tdb_flags);
|
|
output_perf_counter(data->cpuInfo.niceCPU,
|
|
data->cpuInfo.data[0].nice,
|
|
rt, tdb_flags);
|
|
output_perf_counter(data->cpuInfo.idleCPU,
|
|
data->cpuInfo.data[0].idle,
|
|
rt, tdb_flags);
|
|
if(data->cpuInfo.numCPUs > 1)
|
|
{
|
|
for(i = 0; i < data->cpuInfo.numCPUs; i++)
|
|
{
|
|
memset(buf, 0, NAME_LEN);
|
|
sprintf(buf, "cpu%d", i);
|
|
output_perf_instance(data->cpuInfo.cpuObjDesc.index,
|
|
i,
|
|
(void *)&(data->cpuInfo.data[i]),
|
|
sizeof(data->cpuInfo.data[i]),
|
|
buf, rt, tdb_flags);
|
|
}
|
|
|
|
memset(buf, 0, NAME_LEN);
|
|
sprintf(buf, "_Total");
|
|
output_perf_instance(data->cpuInfo.cpuObjDesc.index,
|
|
i,
|
|
(void *)&(data->cpuInfo.data[i]),
|
|
sizeof(data->cpuInfo.data[i]),
|
|
buf, rt, tdb_flags);
|
|
}
|
|
return;
|
|
}
|