Implement native sigar_proc_cpu_get function
This commit is contained in:
parent
171f2e021e
commit
93ef97aaa8
|
@ -1,3 +1,7 @@
|
||||||
|
2007-03-11 Doug MacEachern <dougm@hyperic.com>
|
||||||
|
|
||||||
|
* Implement native sigar_proc_cpu_get function
|
||||||
|
|
||||||
2007-03-07 Doug MacEachern <dougm@hyperic.com>
|
2007-03-07 Doug MacEachern <dougm@hyperic.com>
|
||||||
|
|
||||||
* Plug various handle+mem leaks on win32
|
* Plug various handle+mem leaks on win32
|
||||||
|
|
|
@ -319,6 +319,18 @@ my %classes = (
|
||||||
plat => '*'
|
plat => '*'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
ProcCpu => [
|
||||||
|
{
|
||||||
|
name => 'percent', type => 'Double',
|
||||||
|
desc => 'Process cpu usage',
|
||||||
|
plat => '*'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name => 'last_time', type => 'Long',
|
||||||
|
desc => '',
|
||||||
|
plat => '*'
|
||||||
|
},
|
||||||
|
],
|
||||||
ProcState => [
|
ProcState => [
|
||||||
{
|
{
|
||||||
name => 'state', type => 'Char',
|
name => 'state', type => 'Char',
|
||||||
|
@ -976,6 +988,14 @@ my %classes = (
|
||||||
|
|
||||||
$classes{DirUsage} = $classes{DirStat};
|
$classes{DirUsage} = $classes{DirStat};
|
||||||
|
|
||||||
|
my(%extends) = (
|
||||||
|
ProcCpu => 'ProcTime',
|
||||||
|
);
|
||||||
|
|
||||||
|
while (my($subclass, $superclass) = each %extends) {
|
||||||
|
push @{ $classes{$subclass} }, @{ $classes{$superclass} };
|
||||||
|
}
|
||||||
|
|
||||||
my %cmds = (
|
my %cmds = (
|
||||||
Mem => {
|
Mem => {
|
||||||
AIX => 'top',
|
AIX => 'top',
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.hyperic.sigar.ptql.ProcessFinder;
|
||||||
*/
|
*/
|
||||||
public class MultiProcCpu extends ProcCpu {
|
public class MultiProcCpu extends ProcCpu {
|
||||||
|
|
||||||
|
private long pid;
|
||||||
private int nproc = 0;
|
private int nproc = 0;
|
||||||
private static Map ptable = new HashMap();
|
private static Map ptable = new HashMap();
|
||||||
|
|
||||||
|
@ -99,4 +100,19 @@ public class MultiProcCpu extends ProcCpu {
|
||||||
public int getProcesses() {
|
public int getProcesses() {
|
||||||
return this.nproc;
|
return this.nproc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Pid of the process.
|
||||||
|
*/
|
||||||
|
public int hashCode() {
|
||||||
|
return (int)this.pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object cpu) {
|
||||||
|
if (!(cpu instanceof MultiProcCpu)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((MultiProcCpu)cpu).pid == this.pid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
|
||||||
* This file is part of SIGAR.
|
|
||||||
*
|
|
||||||
* SIGAR is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms version 2 of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.hyperic.sigar;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend ProcTime to provide process cpu percentage metric.
|
|
||||||
*/
|
|
||||||
public class ProcCpu extends ProcTime {
|
|
||||||
|
|
||||||
private static ProcCpu key = new ProcCpu();
|
|
||||||
private static Map ptable = new HashMap();
|
|
||||||
|
|
||||||
protected long lastTime = 0;
|
|
||||||
protected double percent = 0.0;
|
|
||||||
protected long pid;
|
|
||||||
|
|
||||||
private void getValues(Sigar sigar, long pid)
|
|
||||||
throws SigarException {
|
|
||||||
this.gather(sigar, pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
static synchronized ProcCpu get(Sigar sigar, long pid)
|
|
||||||
throws SigarException {
|
|
||||||
|
|
||||||
ProcCpu cpu;
|
|
||||||
|
|
||||||
key.pid = pid;
|
|
||||||
cpu = (ProcCpu)ptable.get(key);
|
|
||||||
|
|
||||||
if (cpu == null) {
|
|
||||||
cpu = new ProcCpu();
|
|
||||||
cpu.pid = pid;
|
|
||||||
ptable.put(cpu, cpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
long timeNow = System.currentTimeMillis();
|
|
||||||
double diff = timeNow - cpu.lastTime;
|
|
||||||
if (diff == 0) {
|
|
||||||
return cpu; //we were just called within < 1 second ago.
|
|
||||||
}
|
|
||||||
|
|
||||||
cpu.lastTime = timeNow;
|
|
||||||
|
|
||||||
long otime = cpu.total;
|
|
||||||
|
|
||||||
cpu.getValues(sigar, pid);
|
|
||||||
|
|
||||||
if (otime == 0) {
|
|
||||||
//XXX could/should pause first time called.
|
|
||||||
return cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpu.percent = ((cpu.total - otime) / diff);
|
|
||||||
if (cpu.percent >= 1.0) {
|
|
||||||
cpu.percent = 0.99;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Process CPU usage percentage.
|
|
||||||
*/
|
|
||||||
public double getPercent() {
|
|
||||||
return this.percent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Pid of the process.
|
|
||||||
*/
|
|
||||||
public int hashCode() {
|
|
||||||
return (int)this.pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object cpu) {
|
|
||||||
if (!(cpu instanceof ProcCpu)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((ProcCpu)cpu).pid == this.pid;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -472,7 +472,7 @@ public class Sigar implements SigarProxy {
|
||||||
* @exception SigarException on failure.
|
* @exception SigarException on failure.
|
||||||
*/
|
*/
|
||||||
public ProcCpu getProcCpu(long pid) throws SigarException {
|
public ProcCpu getProcCpu(long pid) throws SigarException {
|
||||||
return ProcCpu.get(this, pid);
|
return ProcCpu.fetch(this, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProcCpu getProcCpu(String pid) throws SigarException {
|
public ProcCpu getProcCpu(String pid) throws SigarException {
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class MultiPs extends SigarCommandBase {
|
||||||
MultiProcCpu cpu = this.proxy.getMultiProcCpu(query);
|
MultiProcCpu cpu = this.proxy.getMultiProcCpu(query);
|
||||||
println("Number of processes: " + cpu.getProcesses());
|
println("Number of processes: " + cpu.getProcesses());
|
||||||
println("Cpu usage: " + CpuPerc.format(cpu.getPercent()));
|
println("Cpu usage: " + CpuPerc.format(cpu.getPercent()));
|
||||||
println("Cpu time: " + Ps.getCpuTime(cpu));
|
println("Cpu time: " + Ps.getCpuTime(cpu.getTotal()));
|
||||||
|
|
||||||
ProcMem mem = this.proxy.getMultiProcMem(query);
|
ProcMem mem = this.proxy.getMultiProcMem(query);
|
||||||
println("Size: " + Sigar.formatSize(mem.getSize()));
|
println("Size: " + Sigar.formatSize(mem.getSize()));
|
||||||
|
|
|
@ -148,11 +148,15 @@ public class Ps extends SigarCommandBase {
|
||||||
println(join(getInfo(this.proxy, pid)));
|
println(join(getInfo(this.proxy, pid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getCpuTime(ProcTime time) {
|
public static String getCpuTime(long total) {
|
||||||
long t = time.getTotal() / 1000;
|
long t = total / 1000;
|
||||||
return t/60 + ":" + t%60;
|
return t/60 + ":" + t%60;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getCpuTime(ProcTime time) {
|
||||||
|
return getCpuTime(time.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
private static String getStartTime(long time) {
|
private static String getStartTime(long time) {
|
||||||
if (time == 0) {
|
if (time == 0) {
|
||||||
return "00:00";
|
return "00:00";
|
||||||
|
|
|
@ -33,18 +33,30 @@ typedef unsigned __int32 sigar_uint32_t;
|
||||||
|
|
||||||
typedef unsigned __int64 sigar_uint64_t;
|
typedef unsigned __int64 sigar_uint64_t;
|
||||||
|
|
||||||
|
typedef __int32 sigar_int32_t;
|
||||||
|
|
||||||
|
typedef __int64 sigar_int64_t;
|
||||||
|
|
||||||
#elif ULONG_MAX > 4294967295UL
|
#elif ULONG_MAX > 4294967295UL
|
||||||
|
|
||||||
typedef unsigned int sigar_uint32_t;
|
typedef unsigned int sigar_uint32_t;
|
||||||
|
|
||||||
typedef unsigned long sigar_uint64_t;
|
typedef unsigned long sigar_uint64_t;
|
||||||
|
|
||||||
|
typedef int sigar_int32_t;
|
||||||
|
|
||||||
|
typedef long sigar_int64_t;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
typedef unsigned int sigar_uint32_t;
|
typedef unsigned int sigar_uint32_t;
|
||||||
|
|
||||||
typedef unsigned long long sigar_uint64_t;
|
typedef unsigned long long sigar_uint64_t;
|
||||||
|
|
||||||
|
typedef int sigar_int32_t;
|
||||||
|
|
||||||
|
typedef long long sigar_int64_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SIGAR_FIELD_NOTIMPL -1
|
#define SIGAR_FIELD_NOTIMPL -1
|
||||||
|
@ -272,6 +284,20 @@ typedef struct {
|
||||||
SIGAR_DECLARE(int) sigar_proc_time_get(sigar_t *sigar, sigar_pid_t pid,
|
SIGAR_DECLARE(int) sigar_proc_time_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
sigar_proc_time_t *proctime);
|
sigar_proc_time_t *proctime);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* must match sigar_proc_time_t fields */
|
||||||
|
sigar_uint64_t
|
||||||
|
start_time,
|
||||||
|
user,
|
||||||
|
sys,
|
||||||
|
total;
|
||||||
|
sigar_uint64_t last_time;
|
||||||
|
double percent;
|
||||||
|
} sigar_proc_cpu_t;
|
||||||
|
|
||||||
|
SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
|
sigar_proc_cpu_t *proccpu);
|
||||||
|
|
||||||
#define SIGAR_PROC_NAME_LEN 128
|
#define SIGAR_PROC_NAME_LEN 128
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -65,7 +65,8 @@
|
||||||
char errbuf[256]; \
|
char errbuf[256]; \
|
||||||
char *ifconf_buf; \
|
char *ifconf_buf; \
|
||||||
int ifconf_len; \
|
int ifconf_len; \
|
||||||
char *self_path
|
char *self_path; \
|
||||||
|
sigar_cache_t *proc_cpu
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
# define SIGAR_INLINE __inline
|
# define SIGAR_INLINE __inline
|
||||||
|
|
63
src/sigar.c
63
src/sigar.c
|
@ -34,7 +34,10 @@ SIGAR_DECLARE(int) sigar_open(sigar_t **sigar)
|
||||||
(*sigar)->log_level = -1; /* log nothing by default */
|
(*sigar)->log_level = -1; /* log nothing by default */
|
||||||
(*sigar)->log_impl = NULL;
|
(*sigar)->log_impl = NULL;
|
||||||
(*sigar)->log_data = NULL;
|
(*sigar)->log_data = NULL;
|
||||||
|
(*sigar)->ptql_re_impl = NULL;
|
||||||
|
(*sigar)->ptql_re_data = NULL;
|
||||||
(*sigar)->self_path = NULL;
|
(*sigar)->self_path = NULL;
|
||||||
|
(*sigar)->proc_cpu = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -48,6 +51,10 @@ SIGAR_DECLARE(int) sigar_close(sigar_t *sigar)
|
||||||
if (sigar->self_path) {
|
if (sigar->self_path) {
|
||||||
free(sigar->self_path);
|
free(sigar->self_path);
|
||||||
}
|
}
|
||||||
|
if (sigar->proc_cpu) {
|
||||||
|
sigar_cache_destroy(sigar->proc_cpu);
|
||||||
|
}
|
||||||
|
|
||||||
return sigar_os_close(sigar);
|
return sigar_os_close(sigar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +69,62 @@ SIGAR_DECLARE(sigar_pid_t) sigar_pid_get(sigar_t *sigar)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* XXX: add clear() function */
|
||||||
|
/* XXX: check for stale-ness using start_time */
|
||||||
|
SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
|
sigar_proc_cpu_t *proccpu)
|
||||||
|
{
|
||||||
|
sigar_cache_entry_t *entry;
|
||||||
|
sigar_proc_cpu_t *prev;
|
||||||
|
sigar_uint64_t otime, time_now = time(NULL) * 1000;
|
||||||
|
sigar_int64_t time_diff, total_diff;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (!sigar->proc_cpu) {
|
||||||
|
sigar->proc_cpu = sigar_cache_new(128);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = sigar_cache_get(sigar->proc_cpu, pid);
|
||||||
|
if (entry->value) {
|
||||||
|
prev = (sigar_proc_cpu_t *)entry->value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prev = entry->value = malloc(sizeof(*prev));
|
||||||
|
SIGAR_ZERO(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
time_diff = time_now - prev->last_time;
|
||||||
|
proccpu->last_time = prev->last_time = time_now;
|
||||||
|
|
||||||
|
if (time_diff == 0) {
|
||||||
|
/* we were just called within < 1 second ago. */
|
||||||
|
memcpy(proccpu, prev, sizeof(*proccpu));
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
otime = prev->total;
|
||||||
|
|
||||||
|
status =
|
||||||
|
sigar_proc_time_get(sigar, pid,
|
||||||
|
(sigar_proc_time_t *)proccpu);
|
||||||
|
|
||||||
|
if (status != SIGAR_OK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(prev, proccpu, sizeof(*prev));
|
||||||
|
|
||||||
|
if (otime == 0) {
|
||||||
|
/* first time called */
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_diff = proccpu->total - otime;
|
||||||
|
proccpu->percent = total_diff / (double)time_diff;
|
||||||
|
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static char *sigar_error_string(int err)
|
static char *sigar_error_string(int err)
|
||||||
{
|
{
|
||||||
switch (err) {
|
switch (err) {
|
||||||
|
|
Loading…
Reference in New Issue