Skip to content

Commit aab8617

Browse files
authored
Simplify the MainExit logic. (#152)
1 parent dcebeed commit aab8617

File tree

3 files changed

+12
-11
lines changed

3 files changed

+12
-11
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
### Changed
88

9+
- Simplify the `mainExit` logic and introduce `MainExiting` state.
10+
911
### Deprecated
1012

1113
### Removed

core/src/main/kotlin/org/pastalab/fray/core/RunContext.kt

+9-11
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ class RunContext(val config: Configuration) {
5353
var currentThreadId: Long = -1
5454
var mainThreadId: Long = -1
5555
var bugFound: Throwable? = null
56-
var mainExiting = false
5756
var nanoTime = TimeUnit.SECONDS.toNanos(1577768400)
5857
val hashCodeMapper = ReferencedContextManager<Int>({ config.randomnessProvider.nextInt() })
5958
var forkJoinPool: ForkJoinPool? = null
@@ -187,14 +186,13 @@ class RunContext(val config: Configuration) {
187186
fun mainExit() {
188187
val t = Thread.currentThread()
189188
val context = registeredThreads[t.id]!!
190-
mainExiting = true
191189
while (registeredThreads.any {
192190
it.value.state != ThreadState.Completed &&
193191
it.value.state != ThreadState.Created &&
194192
it.value != context
195193
}) {
196194
try {
197-
context.state = ThreadState.Runnable
195+
context.state = ThreadState.MainExiting
198196
scheduleNextOperation(true)
199197
} catch (e: org.pastalab.fray.runtime.TargetTerminateException) {
200198
// If deadlock detected let's try to unblock one thread and continue.
@@ -219,7 +217,6 @@ class RunContext(val config: Configuration) {
219217
val t = Thread.currentThread()
220218
step = 0
221219
bugFound = null
222-
mainExiting = false
223220
currentThreadId = t.id
224221
mainThreadId = t.id
225222
registeredThreads[t.id] = ThreadContext(t, registeredThreads.size, this)
@@ -1014,9 +1011,6 @@ class RunContext(val config: Configuration) {
10141011
.toList()
10151012
.filter { it.state == ThreadState.Runnable }
10161013
.sortedBy { it.thread.id }
1017-
if (mainExiting && (currentThreadId == mainThreadId || enabledOperations.size > 1)) {
1018-
enabledOperations = enabledOperations.filter { it.thread.id != mainThreadId }
1019-
}
10201014

10211015
// The first empty check will enable timed operations
10221016
if (enabledOperations.isEmpty()) {
@@ -1026,13 +1020,17 @@ class RunContext(val config: Configuration) {
10261020
.toList()
10271021
.filter { it.state == ThreadState.Runnable }
10281022
.sortedBy { it.thread.id }
1029-
if (mainExiting && (currentThreadId == mainThreadId || enabledOperations.size > 1)) {
1030-
enabledOperations = enabledOperations.filter { it.thread.id != mainThreadId }
1031-
}
10321023
}
10331024

10341025
// The second empty check throws deadlock exceptions.
10351026
if (enabledOperations.isEmpty()) {
1027+
// If no thread is blocked. We are done. Return to main thread and exit.
1028+
if (registeredThreads.values.none { it.state == ThreadState.Blocked }) {
1029+
if (currentThreadId != mainThreadId) {
1030+
registeredThreads[mainThreadId]?.unblock()
1031+
}
1032+
return
1033+
}
10361034
val e = DeadlockException()
10371035
reportError(e)
10381036
throw e
@@ -1042,7 +1040,7 @@ class RunContext(val config: Configuration) {
10421040
if (config.executionInfo.maxScheduledStep in 1 ..< step &&
10431041
!currentThread.isExiting &&
10441042
Thread.currentThread() !is HelperThread &&
1045-
!(mainExiting && currentThreadId == mainThreadId)) {
1043+
currentThread.state != ThreadState.MainExiting) {
10461044
currentThread.state = ThreadState.Running
10471045
val e = LivenessException()
10481046
reportError(e)

rmi/src/main/kotlin/org/pastalab/fray/rmi/RemoteScheduler.kt

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ enum class ThreadState {
1010
Running,
1111
Blocked,
1212
Completed,
13+
MainExiting,
1314
Created,
1415
}
1516

0 commit comments

Comments
 (0)