eu.stratosphere.nephele.profiling.impl.EnvironmentThreadSet Maven / Gradle / Ivy
/***********************************************************************************************************************
* Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
**********************************************************************************************************************/
package eu.stratosphere.nephele.profiling.impl;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import eu.stratosphere.nephele.executiongraph.ExecutionVertexID;
import eu.stratosphere.nephele.jobgraph.JobID;
import eu.stratosphere.nephele.profiling.impl.types.InternalExecutionVertexThreadProfilingData;
public class EnvironmentThreadSet {
private static final long NANO_TO_MILLISECONDS = 1000 * 1000;
private static final long PERCENT = 100;
private class CPUUtilizationSnapshot {
private final long timestamp;
private final long totalCPUTime;
private final long totalCPUUserTime;
private final long totalCPUWaitTime;
private final long totalCPUBlockTime;
public CPUUtilizationSnapshot(long timestamp, long totalCPUTime, long totalCPUUserTime, long totalCPUWaitTime,
long totalCPUBlockTime) {
this.timestamp = timestamp;
this.totalCPUTime = totalCPUTime;
this.totalCPUUserTime = totalCPUUserTime;
this.totalCPUWaitTime = totalCPUWaitTime;
this.totalCPUBlockTime = totalCPUBlockTime;
}
public long getTimestamp() {
return this.timestamp;
}
public long getTotalCPUTime() {
return this.totalCPUTime;
}
public long getTotalCPUUserTime() {
return this.totalCPUUserTime;
}
public long getTotalCPUWaitTime() {
return this.totalCPUWaitTime;
}
public long getTotalCPUBlockTime() {
return this.totalCPUBlockTime;
}
}
private final Thread mainThread;
private final ExecutionVertexID executionVertexID;
private final Map userThreads = new HashMap();
private CPUUtilizationSnapshot mainThreadSnapshot = null;
public EnvironmentThreadSet(ThreadMXBean tmx, Thread mainThread, ExecutionVertexID executionVertexID) {
this.mainThread = mainThread;
this.executionVertexID = executionVertexID;
this.mainThreadSnapshot = createCPUUtilizationSnapshot(tmx, mainThread, System.currentTimeMillis());
}
public Thread getMainThread() {
return this.mainThread;
}
public void addUserThread(ThreadMXBean tmx, Thread thread) {
synchronized (this.userThreads) {
this.userThreads.put(thread, createCPUUtilizationSnapshot(tmx, thread, System.currentTimeMillis()));
}
}
public void removeUserThread(Thread thread) {
synchronized (this.userThreads) {
this.userThreads.remove(thread);
}
}
public int getNumberOfUserThreads() {
synchronized (this.userThreads) {
return this.userThreads.size();
}
}
private CPUUtilizationSnapshot createCPUUtilizationSnapshot(ThreadMXBean tmx, Thread thread, long timestamp) {
final long threadId = thread.getId();
final ThreadInfo threadInfo = tmx.getThreadInfo(threadId);
if(threadInfo == null) {
return null;
}
return new CPUUtilizationSnapshot(timestamp, tmx.getThreadCpuTime(threadId) / NANO_TO_MILLISECONDS, tmx
.getThreadUserTime(threadId) / NANO_TO_MILLISECONDS, threadInfo.getWaitedTime(),
threadInfo.getBlockedTime());
}
public InternalExecutionVertexThreadProfilingData captureCPUUtilization(JobID jobID, ThreadMXBean tmx,
long timestamp) {
synchronized (this.userThreads) {
// Calculate utilization for main thread first
final CPUUtilizationSnapshot newMainThreadSnapshot = createCPUUtilizationSnapshot(tmx, this.mainThread, timestamp);
if(newMainThreadSnapshot == null) {
return null;
}
final long mainInterval = newMainThreadSnapshot.getTimestamp() - this.mainThreadSnapshot.getTimestamp();
if (mainInterval == 0) {
return null;
}
long cputime = newMainThreadSnapshot.getTotalCPUTime() - this.mainThreadSnapshot.getTotalCPUTime();
long usrtime = newMainThreadSnapshot.getTotalCPUUserTime() - this.mainThreadSnapshot.getTotalCPUUserTime();
long systime = cputime - usrtime;
long waitime = newMainThreadSnapshot.getTotalCPUWaitTime() - this.mainThreadSnapshot.getTotalCPUWaitTime();
long blktime = newMainThreadSnapshot.getTotalCPUBlockTime()
- this.mainThreadSnapshot.getTotalCPUBlockTime();
int sumUsrTime = (int) ((usrtime * PERCENT) / mainInterval);
int sumSysTime = (int) ((systime * PERCENT) / mainInterval);
int sumBlkTime = (int) ((blktime * PERCENT) / mainInterval);
int sumWaiTime = (int) ((waitime * PERCENT) / mainInterval);
// Update snapshot
this.mainThreadSnapshot = newMainThreadSnapshot;
if (!this.userThreads.isEmpty()) {
final Iterator it = this.userThreads.keySet().iterator();
int divisor = this.userThreads.size();
while (it.hasNext()) {
final Thread userThread = it.next();
final CPUUtilizationSnapshot newUtilizationSnaphot = createCPUUtilizationSnapshot(tmx, userThread,
timestamp);
final CPUUtilizationSnapshot oldUtilizationSnapshot = this.userThreads.get(userThread);
long interval = newUtilizationSnaphot.getTimestamp() - oldUtilizationSnapshot.getTimestamp();
if (interval == 0) {
--divisor;
continue;
}
cputime = newUtilizationSnaphot.getTotalCPUTime() - oldUtilizationSnapshot.getTotalCPUTime();
usrtime = newUtilizationSnaphot.getTotalCPUUserTime()
- oldUtilizationSnapshot.getTotalCPUUserTime();
systime = cputime - usrtime;
waitime = newUtilizationSnaphot.getTotalCPUWaitTime()
- oldUtilizationSnapshot.getTotalCPUWaitTime();
blktime = newUtilizationSnaphot.getTotalCPUBlockTime()
- oldUtilizationSnapshot.getTotalCPUBlockTime();
sumUsrTime += (int) ((usrtime * PERCENT) / interval);
sumSysTime += (int) ((systime * PERCENT) / interval);
sumBlkTime += (int) ((blktime * PERCENT) / interval);
sumWaiTime += (int) ((waitime * PERCENT) / interval);
// Update snapshot
this.userThreads.put(userThread, newUtilizationSnaphot);
}
sumUsrTime /= (divisor + 1);
sumSysTime /= (divisor + 1);
sumBlkTime /= (divisor + 1);
sumWaiTime /= (divisor + 1);
}
return new InternalExecutionVertexThreadProfilingData(jobID, this.executionVertexID, (int) mainInterval,
sumUsrTime, sumSysTime, sumBlkTime, sumWaiTime);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy