/*
* Quasar: lightweight threads and actors for the JVM.
* Copyright (c) 2015, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.fibers.instrument;
import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.fibers.Instrumented;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.fibers.Suspendable;
import co.paralleluniverse.strands.SuspendableRunnable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
import static org.junit.Assert.*;
import org.junit.Test;
/**
*
* @author circlespainter
*/
public class InstrumentationOptimizerTest {
private boolean isOptimized(String method) {
for (Method m : getClass().getDeclaredMethods()) {
if (method.equals(m.getName())) {
Instrumented i = m.getAnnotation(Instrumented.class);
return i != null && i.methodOptimized();
}
}
return false;
}
public void sleepFiberVoid() throws InterruptedException, SuspendExecution {
Fiber.sleep(10);
}
private void skipForwardsToSuspendableVoid() throws InterruptedException, SuspendExecution {
sleepFiberVoid();
}
@Test
public void testSkipForwardsToSuspendableVoid() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
skipForwardsToSuspendableVoid();
}
}).start().join();
assertTrue(isOptimized("skipForwardsToSuspendableVoid"));
}
private Object sleepFiberObject() throws InterruptedException, SuspendExecution {
Fiber.sleep(10);
return new Object();
}
private Object skipForwardsToSuspendableObject() throws InterruptedException, SuspendExecution {
return sleepFiberObject();
}
@Test
public void testSkipForwardsToSuspendableObject() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
skipForwardsToSuspendableObject();
}
}).start().join();
assertTrue(isOptimized("skipForwardsToSuspendableObject"));
}
private double sleepFiberDouble() throws InterruptedException, SuspendExecution {
Fiber.sleep(10);
return ThreadLocalRandom.current().nextDouble();
}
private double skipForwardsToSuspendableDouble() throws InterruptedException, SuspendExecution {
return sleepFiberDouble();
}
@Test
public void testSkipForwardsToSuspendableDouble() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
skipForwardsToSuspendableDouble();
}
}).start().join();
assertTrue(isOptimized("skipForwardsToSuspendableDouble"));
}
private float sleepFiberFloat() throws InterruptedException, SuspendExecution {
Fiber.sleep(10);
return ThreadLocalRandom.current().nextFloat();
}
private float skipForwardsToSuspendableFloat() throws InterruptedException, SuspendExecution {
return sleepFiberFloat();
}
@Test
public void testSkipForwardsToSuspendableFloat() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
skipForwardsToSuspendableFloat();
}
}).start().join();
assertTrue(isOptimized("skipForwardsToSuspendableFloat"));
}
private int sleepFiberInt() throws InterruptedException, SuspendExecution {
Fiber.sleep(10);
return ThreadLocalRandom.current().nextInt();
}
private int skipForwardsToSuspendableInt() throws InterruptedException, SuspendExecution {
return sleepFiberInt();
}
@Test
public void testSkipForwardsToSuspendableInt() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
skipForwardsToSuspendableInt();
}
}).start().join();
assertTrue(isOptimized("skipForwardsToSuspendableInt"));
}
private long sleepFiberLong() throws InterruptedException, SuspendExecution {
Fiber.sleep(10);
return ThreadLocalRandom.current().nextLong();
}
private long skipForwardsToSuspendableLong() throws InterruptedException, SuspendExecution {
return sleepFiberLong();
}
@Test
public void testSkipForwardsToSuspendableLong() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
skipForwardsToSuspendableLong();
}
}).start().join();
assertTrue(isOptimized("skipForwardsToSuspendableLong"));
}
@Suspendable
private Object dontSkipForwardsWithTryCatch() throws InterruptedException {
try {
return sleepFiberObject();
} catch (SuspendExecution e) {
return null;
}
}
@Test
public void testDontSkipForwardsWithTryCatch() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
dontSkipForwardsWithTryCatch();
}
}).start().join();
assertFalse(isOptimized("skipForwardsWithTryCatch"));
}
private void dontSkipForwardsWithLoop() throws InterruptedException, SuspendExecution {
for (int i = 0; i < 3; i++)
sleepFiberVoid();
}
@Test
public void testDontSkipForwardsWithLoop() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
dontSkipForwardsWithLoop();
}
}).start().join();
assertFalse(isOptimized("skipForwardsWithLoop"));
}
private void dontSkipForwardsWithLoopBefore() throws InterruptedException, SuspendExecution {
for (int i = 0; i < 5; i++)
i++;
sleepFiberVoid();
}
@Test
public void testDontSkipForwardsWithLoopBefore() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
dontSkipForwardsWithLoopBefore();
}
}).start().join();
assertFalse(isOptimized("skipForwardsWithLoopBefore"));
}
private void skipForwardsWithLoopAfter() throws InterruptedException, SuspendExecution {
sleepFiberVoid();
for (int i = 0; i < 3; i++)
System.nanoTime();
}
@Test
public void testSkipForwardsWithLoopAfter() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
skipForwardsWithLoopAfter();
}
}).start().join();
assertTrue(isOptimized("skipForwardsWithLoopAfter"));
}
private void dontSkipForwardsWithMethodBefore() throws InterruptedException, SuspendExecution {
System.nanoTime();
sleepFiberVoid();
}
@Test
public void testDontSkipForwardsWithMethodBefore() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
dontSkipForwardsWithMethodBefore();
}
}).start().join();
assertFalse(isOptimized("skipForwardsWithMethodBefore"));
}
private void skipForwardsWithMethodAfter() throws InterruptedException, SuspendExecution {
sleepFiberVoid();
System.nanoTime();
}
@Test
public void testSkipForwardsWithMethodAfter() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
skipForwardsWithMethodAfter();
}
}).start().join();
assertTrue(isOptimized("skipForwardsWithMethodAfter"));
}
private void dontSkipForwardsWithReflectiveCalls() throws InterruptedException, SuspendExecution, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
sleepFiberVoid();
getClass().getMethod("sleepFiberVoid", new Class[0]).invoke(this, new Object[0]);
}
@Test
public void testDontSkipForwardsWithReflectiveCalls() throws InterruptedException, SuspendExecution, ExecutionException {
new Fiber(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
try {
dontSkipForwardsWithReflectiveCalls();
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}
}).start().join();
assertFalse(isOptimized("skipForwardsWithReflectiveCalls"));
}
}