diff --git a/core/src/main/kotlin/org/pastalab/fray/core/RunContext.kt b/core/src/main/kotlin/org/pastalab/fray/core/RunContext.kt index f7c1004..072d170 100644 --- a/core/src/main/kotlin/org/pastalab/fray/core/RunContext.kt +++ b/core/src/main/kotlin/org/pastalab/fray/core/RunContext.kt @@ -858,6 +858,15 @@ class RunContext(val config: Configuration) { syncManager.wait(latch) } + fun threadSleepOperation() { + val t = Thread.currentThread().threadId() + val context = registeredThreads[t]!! + context.checkInterrupt() + context.pendingOperation = ThreadSleepBlocking(context) + context.state = ThreadState.Paused + scheduleNextOperation(true) + } + fun scheduleNextOperationAndCheckDeadlock(shouldBlockCurrentThread: Boolean) { try { scheduleNextOperation(shouldBlockCurrentThread) diff --git a/core/src/main/kotlin/org/pastalab/fray/core/RuntimeDelegate.kt b/core/src/main/kotlin/org/pastalab/fray/core/RuntimeDelegate.kt index 1311c34..4138614 100644 --- a/core/src/main/kotlin/org/pastalab/fray/core/RuntimeDelegate.kt +++ b/core/src/main/kotlin/org/pastalab/fray/core/RuntimeDelegate.kt @@ -846,16 +846,40 @@ class RuntimeDelegate(val context: RunContext) : org.pastalab.fray.runtime.Deleg return probe } - override fun onThreadSleepDuration(duration: Duration?) { - Thread.yield() + override fun onThreadSleepDuration(duration: Duration) { + if (checkEntered()) { + Thread.sleep(duration) + return + } + try { + context.threadSleepOperation() + } finally { + entered.set(false) + } } override fun onThreadSleepMillis(millis: Long) { - Thread.yield() + if (checkEntered()) { + Thread.sleep(millis) + return + } + try { + context.threadSleepOperation() + } finally { + entered.set(false) + } } override fun onThreadSleepMillisNanos(millis: Long, nanos: Int) { - Thread.yield() + if (checkEntered()) { + Thread.sleep(millis, nanos) + return + } + try { + context.threadSleepOperation() + } finally { + entered.set(false) + } } override fun onStampedLockReadLock(lock: StampedLock) { diff --git a/core/src/main/kotlin/org/pastalab/fray/core/concurrency/operations/ThreadSleepBlocking.kt b/core/src/main/kotlin/org/pastalab/fray/core/concurrency/operations/ThreadSleepBlocking.kt new file mode 100644 index 0000000..437a058 --- /dev/null +++ b/core/src/main/kotlin/org/pastalab/fray/core/concurrency/operations/ThreadSleepBlocking.kt @@ -0,0 +1,13 @@ +package org.pastalab.fray.core.concurrency.operations + +import org.pastalab.fray.core.ThreadContext +import org.pastalab.fray.core.concurrency.primitives.InterruptionType +import org.pastalab.fray.rmi.ThreadState + +class ThreadSleepBlocking(val context: ThreadContext) : TimedBlockingOperation(true) { + override fun unblockThread(tid: Long, type: InterruptionType): Any? { + context.pendingOperation = ThreadResumeOperation(type != InterruptionType.TIMEOUT) + context.state = ThreadState.Enabled + return null + } +}