From 38182e4f4d20ec8094dac97479baf8d3e636c97e Mon Sep 17 00:00:00 2001 From: Ao Li Date: Sun, 19 May 2024 14:54:32 -0400 Subject: [PATCH] disable sleep. --- benchmarks/build.gradle.kts | 4 +- .../cmu/pasta/fray/core/GlobalContext.kt | 18 +++------ .../cmu/pasta/fray/core/RuntimeDelegate.kt | 13 +++++++ .../ApplicationCodeTransformer.kt | 1 + .../visitors/SemaphoreInstrumenter.kt | 17 +++++++-- .../visitors/SleepInstrumenter.kt | 38 +++++++++++++++++++ .../java/cmu/pasta/fray/runtime/Delegate.java | 3 ++ .../java/cmu/pasta/fray/runtime/Runtime.java | 8 ++++ 8 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/visitors/SleepInstrumenter.kt diff --git a/benchmarks/build.gradle.kts b/benchmarks/build.gradle.kts index 4a8abb10..4e63e02a 100644 --- a/benchmarks/build.gradle.kts +++ b/benchmarks/build.gradle.kts @@ -7,7 +7,7 @@ plugins { val buildPath = layout.buildDirectory.get().asFile dependencies { - implementation(fileTree(mapOf("dir" to "${buildPath}/libs/unzipped", "include" to listOf("*.jar")))) + implementation(fileTree(mapOf("dir" to "/Users/aoli/repos/dacapobench/benchmarks", "include" to listOf("*.jar")))) implementation(project(":core")) } @@ -53,7 +53,7 @@ tasks.register("run") { else -> emptyList() } args = listOf("Harness", "main", "-a", - "$appName --size small", "-o", "${layout.buildDirectory.get().asFile}/$appName-report", "--logger", "csv", "--iter", "10000", "-s", "10000000") + extraArgs + "$appName --size small", "-o", "${layout.buildDirectory.get().asFile}/$appName-report", "--logger", "csv", "--iter", "10000", "-s", "90000000") + extraArgs } tasks.register("replay") { diff --git a/core/src/main/kotlin/cmu/pasta/fray/core/GlobalContext.kt b/core/src/main/kotlin/cmu/pasta/fray/core/GlobalContext.kt index 182f5acb..a0307f8c 100644 --- a/core/src/main/kotlin/cmu/pasta/fray/core/GlobalContext.kt +++ b/core/src/main/kotlin/cmu/pasta/fray/core/GlobalContext.kt @@ -393,15 +393,10 @@ object GlobalContext { } fun lockTryLock(lock: Any) { - val t = Thread.currentThread().id - val objId = System.identityHashCode(lock) - registeredThreads[t]?.pendingOperation = LockLockOperation(objId) - registeredThreads[t]?.state = ThreadState.Enabled - scheduleNextOperation(true) - lockManager.lock(lock, t, false, false, false) + lockImpl(lock, false, false, false) } - fun lockImpl(lock: Any, isMonitorLock: Boolean, canInterrupt: Boolean) { + fun lockImpl(lock: Any, isMonitorLock: Boolean, shouldBlock: Boolean, canInterrupt: Boolean) { val t = Thread.currentThread().id val objId = System.identityHashCode(lock) val context = registeredThreads[t]!! @@ -426,7 +421,7 @@ object GlobalContext { // synchronized(lock) { // lock.unlock(); // } - while (!lockManager.lock(lock, t, true, false, canInterrupt)) { + while (!lockManager.lock(lock, t, shouldBlock, false, canInterrupt) && shouldBlock) { context.state = ThreadState.Paused // We want to block current thread because we do @@ -441,11 +436,11 @@ object GlobalContext { } fun monitorEnter(lock: Any) { - lockImpl(lock, true, false) + lockImpl(lock, true, true, false) } fun lockLock(lock: Any, canInterrupt: Boolean) { - lockImpl(lock, false, canInterrupt) + lockImpl(lock, false, true, canInterrupt) } fun reentrantReadWriteLockInit(readLock: ReadLock, writeLock: WriteLock) { @@ -530,7 +525,7 @@ object GlobalContext { context.state = ThreadState.Enabled scheduleNextOperation(true) - while (!semaphoreManager.acquire(sem, permits, true, canInterrupt)) { + while (!semaphoreManager.acquire(sem, permits, shouldBlock, canInterrupt) && shouldBlock) { context.state = ThreadState.Paused scheduleNextOperation(true) @@ -538,7 +533,6 @@ object GlobalContext { context.checkInterrupt() } } - semaphoreManager.acquire(sem, permits, shouldBlock, canInterrupt) } fun semaphoreRelease(sem: Semaphore, permits: Int) { diff --git a/core/src/main/kotlin/cmu/pasta/fray/core/RuntimeDelegate.kt b/core/src/main/kotlin/cmu/pasta/fray/core/RuntimeDelegate.kt index 851e5e51..58ad7746 100644 --- a/core/src/main/kotlin/cmu/pasta/fray/core/RuntimeDelegate.kt +++ b/core/src/main/kotlin/cmu/pasta/fray/core/RuntimeDelegate.kt @@ -366,6 +366,19 @@ class RuntimeDelegate : Delegate() { entered.set(false) } + override fun onSemaphoreTryAcquire(sem: Semaphore, permits: Int) { + if (checkEntered()) { + skipFunctionEntered.set(1 + skipFunctionEntered.get()) + return + } + try { + GlobalContext.semaphoreAcquire(sem, permits, false, true) + } finally { + skipFunctionEntered.set(skipFunctionEntered.get() + 1) + entered.set(false) + } + } + override fun onSemaphoreAcquire(sem: Semaphore, permits: Int) { if (checkEntered()) { skipFunctionEntered.set(1 + skipFunctionEntered.get()) diff --git a/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/ApplicationCodeTransformer.kt b/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/ApplicationCodeTransformer.kt index e906a748..12ee873a 100644 --- a/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/ApplicationCodeTransformer.kt +++ b/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/ApplicationCodeTransformer.kt @@ -52,6 +52,7 @@ class ApplicationCodeTransformer : ClassFileTransformer { cv = ConditionInstrumenter(cv) cv = SynchronizedMethodInstrumenter(cv, false) cv = ClassConstructorInstrumenter(cv) + cv = SleepInstrumenter(cv) val classVersionInstrumenter = ClassVersionInstrumenter(cv) cv = ArrayOperationInstrumenter(classVersionInstrumenter) classReader.accept(cv, ClassReader.EXPAND_FRAMES) diff --git a/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/visitors/SemaphoreInstrumenter.kt b/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/visitors/SemaphoreInstrumenter.kt index 3586850f..f50c217c 100644 --- a/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/visitors/SemaphoreInstrumenter.kt +++ b/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/visitors/SemaphoreInstrumenter.kt @@ -18,12 +18,13 @@ class SemaphoreInstrumenter(cv: ClassVisitor) : ClassVisitorBase(cv, Semaphore:: return MethodExitVisitor( mv, Runtime::onSemaphoreInit, access, name, descriptor, true, false, false) } - if ((name == "acquire" || name == "acquireUninterruptibly") && descriptor == "()V") { + if ((name == "acquire" || name == "acquireUninterruptibly" || name == "tryAcquire") && + descriptor.startsWith("()")) { val eMv = if (name == "acquire") { MethodEnterVisitor( mv, Runtime::onSemaphoreAcquire, access, name, descriptor, true, true) - } else { + } else if (name == "acquireUninterruptibly") { MethodEnterVisitor( mv, Runtime::onSemaphoreAcquireUninterruptibly, @@ -32,16 +33,20 @@ class SemaphoreInstrumenter(cv: ClassVisitor) : ClassVisitorBase(cv, Semaphore:: descriptor, true, true) + } else { + MethodEnterVisitor( + mv, Runtime::onSemaphoreTryAcquire, access, name, descriptor, true, true) } return MethodExitVisitor( eMv, Runtime::onSemaphoreAcquireDone, access, name, descriptor, false, false, true) } - if ((name == "acquire" || name == "acquireUninterruptibly") && descriptor == "(I)V") { + if ((name == "acquire" || name == "acquireUninterruptibly" || name == "tryAcquire") && + descriptor.startsWith("(I)V")) { val eMv = if (name == "acquire") { MethodEnterVisitor( mv, Runtime::onSemaphoreAcquirePermits, access, name, descriptor, true, true) - } else { + } else if (name == "acquireUninterruptibly") { MethodEnterVisitor( mv, Runtime::onSemaphoreAcquirePermitsUninterruptibly, @@ -50,7 +55,11 @@ class SemaphoreInstrumenter(cv: ClassVisitor) : ClassVisitorBase(cv, Semaphore:: descriptor, true, true) + } else { + MethodEnterVisitor( + mv, Runtime::onSemaphoreTryAcquirePermits, access, name, descriptor, true, true) } + return MethodExitVisitor( eMv, Runtime::onSemaphoreAcquireDone, access, name, descriptor, false, false, true) } diff --git a/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/visitors/SleepInstrumenter.kt b/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/visitors/SleepInstrumenter.kt new file mode 100644 index 00000000..d1b8cfbe --- /dev/null +++ b/instrumentation/src/main/kotlin/cmu/pasta/fray/instrumentation/visitors/SleepInstrumenter.kt @@ -0,0 +1,38 @@ +package cmu.pasta.fray.instrumentation.visitors + +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes.ASM9 +import org.objectweb.asm.commons.GeneratorAdapter + +class SleepInstrumenter(cv: ClassVisitor) : ClassVisitor(ASM9, cv) { + override fun visitMethod( + access: Int, + name: String, + descriptor: String, + signature: String?, + exceptions: Array? + ): MethodVisitor { + return object : + GeneratorAdapter( + ASM9, + super.visitMethod(access, name, descriptor, signature, exceptions), + access, + name, + descriptor) { + override fun visitMethodInsn( + opcode: Int, + owner: String, + name: String, + descriptor: String, + isInterface: Boolean + ) { + if (owner == "java/lang/Thread" && name == "sleep") { + pop2() + } else { + super.visitMethodInsn(opcode, owner, name, descriptor, isInterface) + } + } + } + } +} diff --git a/runtime/src/main/java/cmu/pasta/fray/runtime/Delegate.java b/runtime/src/main/java/cmu/pasta/fray/runtime/Delegate.java index 2ecd5073..5e139eed 100644 --- a/runtime/src/main/java/cmu/pasta/fray/runtime/Delegate.java +++ b/runtime/src/main/java/cmu/pasta/fray/runtime/Delegate.java @@ -136,6 +136,9 @@ public void onSemaphoreInit(Semaphore sem) { public void onSemaphoreAcquire(Semaphore sem, int permits) { } + public void onSemaphoreTryAcquire(Semaphore sem, int permits) { + } + public void onSemaphoreAcquireUninterruptibly(Semaphore sem, int permits) { } diff --git a/runtime/src/main/java/cmu/pasta/fray/runtime/Runtime.java b/runtime/src/main/java/cmu/pasta/fray/runtime/Runtime.java index dac43446..565b31b4 100644 --- a/runtime/src/main/java/cmu/pasta/fray/runtime/Runtime.java +++ b/runtime/src/main/java/cmu/pasta/fray/runtime/Runtime.java @@ -196,6 +196,14 @@ public static void onSemaphoreAcquire(Semaphore sem) { DELEGATE.onSemaphoreAcquire(sem, 1); } + public static void onSemaphoreTryAcquire(Semaphore sem) { + DELEGATE.onSemaphoreTryAcquire(sem, 1); + } + + public static void onSemaphoreTryAcquirePermits(Semaphore sem, int permits) { + DELEGATE.onSemaphoreTryAcquire(sem, permits); + } + public static void onSemaphoreAcquireUninterruptibly(Semaphore sem) { DELEGATE.onSemaphoreAcquireUninterruptibly(sem, 1); }