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>
|
||||
|
||||
* Plug various handle+mem leaks on win32
|
||||
|
|
|
@ -319,6 +319,18 @@ my %classes = (
|
|||
plat => '*'
|
||||
},
|
||||
],
|
||||
ProcCpu => [
|
||||
{
|
||||
name => 'percent', type => 'Double',
|
||||
desc => 'Process cpu usage',
|
||||
plat => '*'
|
||||
},
|
||||
{
|
||||
name => 'last_time', type => 'Long',
|
||||
desc => '',
|
||||
plat => '*'
|
||||
},
|
||||
],
|
||||
ProcState => [
|
||||
{
|
||||
name => 'state', type => 'Char',
|
||||
|
@ -976,6 +988,14 @@ my %classes = (
|
|||
|
||||
$classes{DirUsage} = $classes{DirStat};
|
||||
|
||||
my(%extends) = (
|
||||
ProcCpu => 'ProcTime',
|
||||
);
|
||||
|
||||
while (my($subclass, $superclass) = each %extends) {
|
||||
push @{ $classes{$subclass} }, @{ $classes{$superclass} };
|
||||
}
|
||||
|
||||
my %cmds = (
|
||||
Mem => {
|
||||
AIX => 'top',
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.hyperic.sigar.ptql.ProcessFinder;
|
|||
*/
|
||||
public class MultiProcCpu extends ProcCpu {
|
||||
|
||||
private long pid;
|
||||
private int nproc = 0;
|
||||
private static Map ptable = new HashMap();
|
||||
|
||||
|
@ -99,4 +100,19 @@ public class MultiProcCpu extends ProcCpu {
|
|||
public int getProcesses() {
|
||||
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.
|
||||
*/
|
||||
public ProcCpu getProcCpu(long pid) throws SigarException {
|
||||
return ProcCpu.get(this, pid);
|
||||
return ProcCpu.fetch(this, pid);
|
||||
}
|
||||
|
||||
public ProcCpu getProcCpu(String pid) throws SigarException {
|
||||
|
|
|
@ -58,7 +58,7 @@ public class MultiPs extends SigarCommandBase {
|
|||
MultiProcCpu cpu = this.proxy.getMultiProcCpu(query);
|
||||
println("Number of processes: " + cpu.getProcesses());
|
||||
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);
|
||||
println("Size: " + Sigar.formatSize(mem.getSize()));
|
||||
|
|
|
@ -148,11 +148,15 @@ public class Ps extends SigarCommandBase {
|
|||
println(join(getInfo(this.proxy, pid)));
|
||||
}
|
||||
|
||||
public static String getCpuTime(ProcTime time) {
|
||||
long t = time.getTotal() / 1000;
|
||||
public static String getCpuTime(long total) {
|
||||
long t = total / 1000;
|
||||
return t/60 + ":" + t%60;
|
||||
}
|
||||
|
||||
public static String getCpuTime(ProcTime time) {
|
||||
return getCpuTime(time.getTotal());
|
||||
}
|
||||
|
||||
private static String getStartTime(long time) {
|
||||
if (time == 0) {
|
||||
return "00:00";
|
||||
|
|
|
@ -33,18 +33,30 @@ typedef unsigned __int32 sigar_uint32_t;
|
|||
|
||||
typedef unsigned __int64 sigar_uint64_t;
|
||||
|
||||
typedef __int32 sigar_int32_t;
|
||||
|
||||
typedef __int64 sigar_int64_t;
|
||||
|
||||
#elif ULONG_MAX > 4294967295UL
|
||||
|
||||
typedef unsigned int sigar_uint32_t;
|
||||
|
||||
typedef unsigned long sigar_uint64_t;
|
||||
|
||||
typedef int sigar_int32_t;
|
||||
|
||||
typedef long sigar_int64_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef unsigned int sigar_uint32_t;
|
||||
|
||||
typedef unsigned long long sigar_uint64_t;
|
||||
|
||||
typedef int sigar_int32_t;
|
||||
|
||||
typedef long long sigar_int64_t;
|
||||
|
||||
#endif
|
||||
|
||||
#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_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
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -65,7 +65,8 @@
|
|||
char errbuf[256]; \
|
||||
char *ifconf_buf; \
|
||||
int ifconf_len; \
|
||||
char *self_path
|
||||
char *self_path; \
|
||||
sigar_cache_t *proc_cpu
|
||||
|
||||
#if defined(WIN32)
|
||||
# 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_impl = NULL;
|
||||
(*sigar)->log_data = NULL;
|
||||
(*sigar)->ptql_re_impl = NULL;
|
||||
(*sigar)->ptql_re_data = NULL;
|
||||
(*sigar)->self_path = NULL;
|
||||
(*sigar)->proc_cpu = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -48,6 +51,10 @@ SIGAR_DECLARE(int) sigar_close(sigar_t *sigar)
|
|||
if (sigar->self_path) {
|
||||
free(sigar->self_path);
|
||||
}
|
||||
if (sigar->proc_cpu) {
|
||||
sigar_cache_destroy(sigar->proc_cpu);
|
||||
}
|
||||
|
||||
return sigar_os_close(sigar);
|
||||
}
|
||||
|
||||
|
@ -62,6 +69,62 @@ SIGAR_DECLARE(sigar_pid_t) sigar_pid_get(sigar_t *sigar)
|
|||
}
|
||||
#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)
|
||||
{
|
||||
switch (err) {
|
||||
|
|
Loading…
Reference in New Issue