blob: 3305122e626d1c0ff1b59f1af3c9e2416ac9e021 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2014 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Simon Delisle - Initial API and implementation
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ctf.core.tests.temp.request;
import java.io.PrintWriter;
import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils;
import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
/**
* Benchmark for the request scheduler
*
* The benchmark has three tests. The first one is the latency (time between the
* creation of the request and the beginning of its execution). The second one
* is the average waiting time for a request. The last one is the total
* completion time.
*/
public class TmfSchedulerBenchmark {
// ------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------
private static final int NUM_LOOPS = 10;
private static final int NANOSECONDS_IN_MILLISECONDS = 1000000;
private static final int NANOSECONDS_IN_SECONDS = 1000000000;
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
private static CtfTmfTrace trace = CtfTmfTestTraceUtils.getTrace(CtfTestTrace.KERNEL);
private static ForegroundRequest lastForegroundRequest = null;
private static BackgroundRequest lastBackgroundRequest = null;
private static PrintWriter pw = new PrintWriter(System.out, true);
/**
* Start the benchmark
*
* @param args
* The command-line arguments
*/
public static void main(final String[] args) {
trace.indexTrace(true);
pw.println("---------- Benchmark started ----------");
latencyBenchmark();
averageWaitingTime();
completedTime();
benchmarkResults();
trace.dispose();
}
private static void latencyBenchmark() {
long averageLatency = 0;
pw.println("----- Latency -----");
for (int i = 0; i < NUM_LOOPS; i++) {
try {
ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY);
trace.sendRequest(foreground1);
foreground1.waitForCompletion();
averageLatency += foreground1.getLatency();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
pw.println((averageLatency / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms");
}
private static void averageWaitingTime() {
long averageWaitingBackground = 0;
long averageWaitingForeground1 = 0;
long averageWaitingForeground2 = 0;
pw.println("----- Average waiting time with 3 requests -----");
for (int i = 0; i < NUM_LOOPS; i++) {
ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY);
ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY);
BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY);
trace.sendRequest(background1);
trace.sendRequest(foreground1);
trace.sendRequest(foreground2);
try {
foreground1.waitForCompletion();
foreground2.waitForCompletion();
background1.waitForCompletion();
} catch (InterruptedException e) {
e.printStackTrace();
}
averageWaitingBackground += background1.getAverageWaitingTime();
averageWaitingForeground1 += foreground1.getAverageWaitingTime();
averageWaitingForeground2 += foreground2.getAverageWaitingTime();
}
pw.print("-- Background : ");
pw.println((averageWaitingBackground / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms");
pw.print("-- First foreground : ");
pw.println((averageWaitingForeground1 / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms");
pw.print("-- Second foreground : ");
pw.println((averageWaitingForeground2 / NUM_LOOPS) / NANOSECONDS_IN_MILLISECONDS + " ms");
}
private static void completedTime() {
long averageCompletedTime1 = 0;
long averageCompletedTime2 = 0;
long averageCompletedTime3 = 0;
long averageCompletedTime4 = 0;
long averageCompletedTime5 = 0;
long averageCompletedTime6 = 0;
pw.println("----- Time to complete request -----");
for (int i = 0; i < NUM_LOOPS; i++) {
try {
ForegroundRequest foreground1 = new ForegroundRequest(TmfTimeRange.ETERNITY);
trace.sendRequest(foreground1);
foreground1.waitForCompletion();
averageCompletedTime1 += foreground1.getCompletedTime();
ForegroundRequest foreground2 = new ForegroundRequest(TmfTimeRange.ETERNITY);
ForegroundRequest foreground3 = new ForegroundRequest(TmfTimeRange.ETERNITY);
trace.sendRequest(foreground2);
trace.sendRequest(foreground3);
foreground2.waitForCompletion();
foreground3.waitForCompletion();
averageCompletedTime2 += (foreground2.getCompletedTime() + foreground3.getCompletedTime());
ForegroundRequest foreground4 = new ForegroundRequest(TmfTimeRange.ETERNITY);
BackgroundRequest background1 = new BackgroundRequest(TmfTimeRange.ETERNITY);
trace.sendRequest(foreground4);
trace.sendRequest(background1);
foreground4.waitForCompletion();
background1.waitForCompletion();
averageCompletedTime3 += (foreground4.getCompletedTime() + background1.getCompletedTime());
ForegroundRequest foreground5 = new ForegroundRequest(TmfTimeRange.ETERNITY);
ForegroundRequest foreground6 = new ForegroundRequest(TmfTimeRange.ETERNITY);
BackgroundRequest background2 = new BackgroundRequest(TmfTimeRange.ETERNITY);
trace.sendRequest(foreground5);
trace.sendRequest(foreground6);
trace.sendRequest(background2);
foreground5.waitForCompletion();
foreground6.waitForCompletion();
background2.waitForCompletion();
averageCompletedTime4 += (foreground5.getCompletedTime() + foreground6.getCompletedTime() + background2.getCompletedTime());
ForegroundRequest foreground7 = new ForegroundRequest(TmfTimeRange.ETERNITY);
ForegroundRequest foreground8 = new ForegroundRequest(TmfTimeRange.ETERNITY);
ForegroundRequest foreground9 = new ForegroundRequest(TmfTimeRange.ETERNITY);
BackgroundRequest background3 = new BackgroundRequest(TmfTimeRange.ETERNITY);
trace.sendRequest(foreground7);
trace.sendRequest(foreground8);
trace.sendRequest(foreground9);
trace.sendRequest(background3);
foreground7.waitForCompletion();
foreground8.waitForCompletion();
foreground9.waitForCompletion();
background3.waitForCompletion();
averageCompletedTime5 += (foreground7.getCompletedTime() + foreground8.getCompletedTime() + foreground9.getCompletedTime() + background3.getCompletedTime());
ForegroundRequest foreground10 = new ForegroundRequest(TmfTimeRange.ETERNITY);
ForegroundRequest foreground11 = new ForegroundRequest(TmfTimeRange.ETERNITY);
ForegroundRequest foreground12 = new ForegroundRequest(TmfTimeRange.ETERNITY);
ForegroundRequest foreground13 = new ForegroundRequest(TmfTimeRange.ETERNITY);
BackgroundRequest background4 = new BackgroundRequest(TmfTimeRange.ETERNITY);
trace.sendRequest(foreground10);
trace.sendRequest(foreground11);
trace.sendRequest(foreground12);
trace.sendRequest(foreground13);
trace.sendRequest(background4);
foreground10.waitForCompletion();
foreground11.waitForCompletion();
foreground12.waitForCompletion();
foreground13.waitForCompletion();
background4.waitForCompletion();
averageCompletedTime6 += (foreground10.getCompletedTime() + foreground11.getCompletedTime() + foreground12.getCompletedTime() + foreground13.getCompletedTime() + background4.getCompletedTime());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
pw.print("-- Time to complete one request : ");
pw.println((averageCompletedTime1 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s");
pw.print("-- Time to complete 2 requests (2 foreground) : ");
pw.println((averageCompletedTime2 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s");
pw.print("-- Time to complete 2 requests (1 foreground, 1 background) : ");
pw.println((averageCompletedTime3 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s");
pw.print("-- Time to complete 3 requests (2 foreground, 1 background) : ");
pw.println((averageCompletedTime4 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s");
pw.print("-- Time to complete 4 requests (3 foreground, 1 background) : ");
pw.println((averageCompletedTime5 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s");
pw.print("-- Time to complete 5 requests (4 foreground, 1 background) : ");
pw.println((averageCompletedTime6 / NUM_LOOPS) / NANOSECONDS_IN_SECONDS + " s");
}
/**
* The benchmark results
*/
public static void benchmarkResults() {
pw.println("---------- Benchmark completed ----------");
}
// ------------------------------------------------------------------------
// Helper methods
// ------------------------------------------------------------------------
private static class BackgroundRequest extends TmfEventRequest {
private long startTime;
private long endTimeLatency = -1;
private long completedTime = 0;
private long waitingTimeStart = 0;
private long waitingTimeEnd = 0;
private long waitingTime = 0;
private int waitingCounter = 0;
private boolean isWaiting = false;
BackgroundRequest(TmfTimeRange timeRange) {
super(trace.getEventType(),
timeRange,
0,
ITmfEventRequest.ALL_DATA,
ExecutionType.BACKGROUND);
startTime = System.nanoTime();
}
@Override
public void handleData(final ITmfEvent event) {
if (endTimeLatency == -1) {
endTimeLatency = System.nanoTime();
}
super.handleData(event);
if (lastForegroundRequest == null && lastBackgroundRequest == null) {
lastBackgroundRequest = this;
}
if (isWaiting) {
waitingTimeEnd = System.nanoTime();
waitingTime += waitingTimeEnd - waitingTimeStart;
++waitingCounter;
isWaiting = false;
}
if (lastForegroundRequest != null) {
lastForegroundRequest.waitingTimeStart = System.nanoTime();
lastForegroundRequest.isWaiting = true;
lastForegroundRequest = null;
lastBackgroundRequest = this;
}
if (lastBackgroundRequest != this) {
lastBackgroundRequest.waitingTimeStart = System.nanoTime();
lastBackgroundRequest.isWaiting = true;
lastBackgroundRequest = this;
}
}
@Override
public void handleCompleted() {
completedTime = System.nanoTime();
super.handleCompleted();
}
public long getCompletedTime() {
return completedTime - startTime;
}
public long getAverageWaitingTime() {
if (waitingCounter == 0) {
return 0;
}
return waitingTime / waitingCounter;
}
}
private static class ForegroundRequest extends TmfEventRequest {
private long startTime = 0;
private long endTimeLatency = -1;
private long completedTime = 0;
private long waitingTimeStart = 0;
private long waitingTimeEnd = 0;
private long waitingTime = 0;
private int waitingCounter = 0;
private boolean isWaiting = false;
ForegroundRequest(TmfTimeRange timeRange) {
super(trace.getEventType(),
timeRange,
0,
ITmfEventRequest.ALL_DATA,
ExecutionType.FOREGROUND);
startTime = System.nanoTime();
}
@Override
public void handleData(final ITmfEvent event) {
if (endTimeLatency == -1) {
endTimeLatency = System.nanoTime();
}
super.handleData(event);
if (lastBackgroundRequest == null && lastForegroundRequest == null) {
lastForegroundRequest = this;
}
if (isWaiting) {
waitingTimeEnd = System.nanoTime();
waitingTime += waitingTimeEnd - waitingTimeStart;
++waitingCounter;
isWaiting = false;
}
if (lastBackgroundRequest != null) {
lastBackgroundRequest.waitingTimeStart = System.nanoTime();
lastBackgroundRequest.isWaiting = true;
lastBackgroundRequest = null;
lastForegroundRequest = this;
}
if (lastForegroundRequest != this) {
lastForegroundRequest.waitingTimeStart = System.nanoTime();
lastForegroundRequest.isWaiting = true;
lastForegroundRequest = this;
}
}
@Override
public void handleCompleted() {
completedTime = System.nanoTime();
super.handleCompleted();
}
public long getLatency() {
return endTimeLatency - startTime;
}
public long getCompletedTime() {
return completedTime - startTime;
}
public long getAverageWaitingTime() {
if (waitingCounter == 0) {
return 0;
}
return waitingTime / waitingCounter;
}
}
}