Skip to content

Commit

Permalink
Improved getCpuUsage() precision.
Browse files Browse the repository at this point in the history
Added unit tests.
  • Loading branch information
dyorgio committed Mar 1, 2020
1 parent 906f2f4 commit 70e3524
Show file tree
Hide file tree
Showing 4 changed files with 325 additions and 38 deletions.
2 changes: 1 addition & 1 deletion _config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
theme: jekyll-theme-cayman
title: Cpu Watcher

lib-version: 1.2.1
lib-version: 1.2.2
36 changes: 36 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<version.sigar.base>1.6.5</version.sigar.base>
<version.sigar>${version.sigar.base}.132</version.sigar>
<version.junit>4.12</version.junit>
<version.out-process>1.2.6</version.out-process>
</properties>

<repositories>
Expand Down Expand Up @@ -98,6 +99,18 @@
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.dyorgio.runtime</groupId>
<artifactId>out-process</artifactId>
<version>${version.out-process}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -510,6 +523,8 @@
<version>${version.maven.release.plugin}</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<localCheckout>true</localCheckout>
<pushChanges>false</pushChanges>
<useReleaseProfile>false</useReleaseProfile>
<releaseProfiles>release</releaseProfiles>
<goals>deploy</goals>
Expand Down Expand Up @@ -570,6 +585,27 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>de.jutzig</groupId>
<artifactId>github-release-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<description>
Improved getCpuUsage() precision.
Added unit tests.
</description>
<releaseName>${project.version}</releaseName>
<tag>${project.version}</tag>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<includes>
<include>${project.artifactId}*.jar</include>
</includes>
</fileSet>
</fileSets>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Expand Down
81 changes: 44 additions & 37 deletions src/main/java/dyorgio/runtime/cpu/watcher/CpuWatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public final class CpuWatcher extends Thread {
private final AbstractProcessWatcher processWatcher;

private volatile Float usageLimit;
private float cpuUsage;
private CpuTimeSnapshot prev;

public CpuWatcher(long pid, Float usageLimit) {
this(null, pid, usageLimit);
Expand Down Expand Up @@ -76,7 +76,17 @@ public Float getUsageLimit() {
}

public float getCpuUsage() {
return cpuUsage;
if (prev != null) {
CpuTimeSnapshot current = processWatcher.getCpuTimes();
try {
return current.getCpuUsage(prev) / cpuCount;
} finally {
prev = current;
}
} else {
prev = processWatcher.getCpuTimes();
return 0;
}
}

public AbstractProcessWatcher getProcessWatcher() {
Expand All @@ -91,62 +101,59 @@ public void run() {
CpuTimeSnapshot prev = processWatcher.getCpuTimes();

Float localUsageLimit;
float cpuUsage;

while (!isInterrupted()) {
try {
localUsageLimit = this.usageLimit;
if (localUsageLimit == null) {
while (this.usageLimit == null) {
Thread.sleep(500);
current = processWatcher.getCpuTimes();
cpuUsage = current.getCpuUsage(prev) / cpuCount;
prev = current;
prev = processWatcher.getCpuTimes();
}
} else {
processWatcher.suspend();
long wakeupAmount = 0;
float error;
try {
while ((localUsageLimit = this.usageLimit) != null) {
if (wakeupAmount > 0) {
processWatcher.resume();
sleepNanoseconds(wakeupAmount);
current = processWatcher.getCpuTimes();
processWatcher.suspend();
cpuUsage = current.getCpuUsage(prev) / cpuCount;
error = ((cpuUsage - localUsageLimit) / 100f) * ONE_SECOND_IN_NANOS;
wakeupAmount -= (long) error;
if (error > 0) {
if (wakeupAmount > 0) {
wakeupAmount -= ONE_MILLIS_IN_NANOS;
}
} else {
if (wakeupAmount < 0) {
wakeupAmount += ONE_MILLIS_IN_NANOS;
}
}
if (wakeupAmount > WAKEUP_LIMITER_UP) {
wakeupAmount = WAKEUP_LIMITER_UP;
} else if (wakeupAmount < WAKEUP_LIMITER_DOWN) {
wakeupAmount = WAKEUP_LIMITER_DOWN;
while ((localUsageLimit = this.usageLimit) != null) {
if (wakeupAmount > 0) {
processWatcher.resume();
sleepNanoseconds(wakeupAmount);
current = processWatcher.getCpuTimes();
processWatcher.suspend();
cpuUsage = current.getCpuUsage(prev) / cpuCount;
error = ((cpuUsage - localUsageLimit) / 100f) * ONE_SECOND_IN_NANOS;
wakeupAmount -= (long) error;
if (error > 0) {
if (wakeupAmount > 0) {
wakeupAmount -= ONE_MILLIS_IN_NANOS;
}
prev = current;
} else {
} else if (wakeupAmount < 0) {
wakeupAmount += ONE_MILLIS_IN_NANOS;
Thread.sleep(1);
}
}
} finally {
try {
processWatcher.resume();
} catch (Exception ex) {
//ignore
if (wakeupAmount > WAKEUP_LIMITER_UP) {
wakeupAmount = WAKEUP_LIMITER_UP;
} else if (wakeupAmount < WAKEUP_LIMITER_DOWN) {
wakeupAmount = WAKEUP_LIMITER_DOWN;
}
prev = current;
} else {
wakeupAmount += ONE_MILLIS_IN_NANOS;
Thread.sleep(1);
}
}

}
} catch (InterruptedException ex) {
// ignore interruptions errors
interrupt();
break;
} finally {
try {
processWatcher.resume();
} catch (Exception ex) {
//ignore
}
}
}
}
Expand Down
Loading

0 comments on commit 70e3524

Please sign in to comment.