dislproj: ex2 done
This commit is contained in:
parent
3eefaaba0a
commit
6274bebf70
4 changed files with 101 additions and 0 deletions
|
@ -1,4 +1,43 @@
|
||||||
package ex2;
|
package ex2;
|
||||||
|
|
||||||
|
import ch.usi.dag.disl.annotation.After;
|
||||||
|
import ch.usi.dag.disl.annotation.Before;
|
||||||
|
import ch.usi.dag.disl.annotation.ThreadLocal;
|
||||||
|
import ch.usi.dag.disl.dynamiccontext.DynamicContext;
|
||||||
|
import ch.usi.dag.disl.marker.BodyMarker;
|
||||||
|
import ch.usi.dag.disl.marker.BytecodeMarker;
|
||||||
|
|
||||||
public class Instrumentation {
|
public class Instrumentation {
|
||||||
|
|
||||||
|
@ThreadLocal
|
||||||
|
static long readCount;
|
||||||
|
|
||||||
|
@ThreadLocal
|
||||||
|
static long writeCount;
|
||||||
|
|
||||||
|
@Before(marker = BytecodeMarker.class, args = "getfield")
|
||||||
|
static void beforeGetField() {
|
||||||
|
readCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before(marker = BytecodeMarker.class, args = "putfield")
|
||||||
|
static void beforePutField() {
|
||||||
|
writeCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@After(marker = BodyMarker.class,
|
||||||
|
scope = "void run()",
|
||||||
|
guard = IsTriviallyThreadGuard.class)
|
||||||
|
static void onThreadExit() {
|
||||||
|
Profiler.increment(readCount, writeCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After(marker = BodyMarker.class,
|
||||||
|
scope = "void run()",
|
||||||
|
guard = IsNotTriviallyThreadGuard.class)
|
||||||
|
static void onThreadExit(final DynamicContext dc) {
|
||||||
|
if (Profiler.isThread(dc.getThis().getClass())) {
|
||||||
|
Profiler.increment(readCount, writeCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package ex2;
|
||||||
|
|
||||||
|
import ch.usi.dag.disl.annotation.GuardMethod;
|
||||||
|
import ch.usi.dag.disl.staticcontext.ClassStaticContext;
|
||||||
|
|
||||||
|
public class IsNotTriviallyThreadGuard {
|
||||||
|
|
||||||
|
@GuardMethod
|
||||||
|
public static boolean isNotTriviallyThread(final ClassStaticContext csc) {
|
||||||
|
return !IsTriviallyThreadGuard.isThread(csc);
|
||||||
|
}
|
||||||
|
}
|
12
DiSLProject2022/src-profiler/ex2/IsTriviallyThreadGuard.java
Normal file
12
DiSLProject2022/src-profiler/ex2/IsTriviallyThreadGuard.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package ex2;
|
||||||
|
|
||||||
|
import ch.usi.dag.disl.annotation.GuardMethod;
|
||||||
|
import ch.usi.dag.disl.staticcontext.ClassStaticContext;
|
||||||
|
|
||||||
|
public class IsTriviallyThreadGuard {
|
||||||
|
@GuardMethod
|
||||||
|
public static boolean isThread(ClassStaticContext csc) {
|
||||||
|
return csc.getInternalName().equals("java/lang/Thread") ||
|
||||||
|
csc.getSuperClassInternalName().equals("java/lang/Thread");
|
||||||
|
}
|
||||||
|
}
|
38
DiSLProject2022/src-profiler/ex2/Profiler.java
Normal file
38
DiSLProject2022/src-profiler/ex2/Profiler.java
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package ex2;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
|
|
||||||
|
public final class Profiler {
|
||||||
|
|
||||||
|
// not concurrent on purpose, since the value of the map is computed with a pure function
|
||||||
|
// on the map key, and thus we don't care if the value is overwritten as a result of a
|
||||||
|
// race condition
|
||||||
|
private static final Map<Class<?>, Boolean> isThread = new HashMap<>();
|
||||||
|
|
||||||
|
private static final LongAdder reads = new LongAdder();
|
||||||
|
|
||||||
|
private static final LongAdder writes = new LongAdder();
|
||||||
|
|
||||||
|
static {
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
|
System.out.printf("Instance field read access: %d\nInstance field write access: %d\n",
|
||||||
|
reads.longValue(),
|
||||||
|
writes.longValue());
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Profiler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isThread(final Class<?> clazz) {
|
||||||
|
return isThread.computeIfAbsent(clazz, Thread.class::isAssignableFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void increment(long readCount, long writeCount) {
|
||||||
|
reads.add(readCount);
|
||||||
|
writes.add(writeCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in a new issue