Skip to content

Commit

Permalink
Further revise thread interrupt tests (#405) (#407)
Browse files Browse the repository at this point in the history
* Add an assert to hopefully avoid JIT elision which was causing a background thread to complete before being interrupted.
  • Loading branch information
dlurton authored May 10, 2021
1 parent f007af0 commit 44d412b
Showing 1 changed file with 26 additions and 36 deletions.
62 changes: 26 additions & 36 deletions lang/test/org/partiql/lang/thread/ThreadInterruptedTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ class ThreadInterruptedTests {
private val reallyBigNAry = makeBigExprNode(20000000)
private val bigNAry = makeBigExprNode(10000000)

private val bigSexpAst by lazy {
val nary = makeBigExprNode(1000000)
@Suppress("DEPRECATION")

private fun makeBigSexpAst() =
makeBigExprNode(1000000).let { nary ->
@Suppress("DEPRECATION")
val sexp = AstSerializer.serialize(nary, ion)
// format of sexp is:
// (ast
Expand All @@ -72,13 +73,12 @@ class ThreadInterruptedTests {
val t = thread {
try {
block()
} catch(_: InterruptedException) {
} catch (_: InterruptedException) {
wasInterrupted.set(true)
}
}

Thread.sleep(INTERRUPT_AFTER_MS)

t.interrupt()
t.join(WAIT_FOR_THREAD_TERMINATION_MS)
assertTrue(wasInterrupted.get(), "Thread should have been interrupted.")
Expand All @@ -97,8 +97,6 @@ class ThreadInterruptedTests {

@Test
fun astChildIterator() {
// force lazy load
reallyBigNAry
testThreadInterrupt {
@Suppress("DEPRECATION")
reallyBigNAry.iterator()
Expand All @@ -107,18 +105,14 @@ class ThreadInterruptedTests {

@Test
fun astWalker() {
// force lazy load
reallyBigNAry
val walker = AstWalker(object : AstVisitor { })
val walker = AstWalker(object : AstVisitor {})
testThreadInterrupt {
walker.walk(reallyBigNAry)
}
}

@Test
fun serialize() {
// force lazy load
bigNAry
testThreadInterrupt {
@Suppress("DEPRECATION")
AstSerializer.serialize(bigNAry, ion)
Expand All @@ -127,8 +121,7 @@ class ThreadInterruptedTests {

@Test
fun deserialize_validate() {
// force lazy load
bigSexpAst
val bigSexpAst = makeBigSexpAst()

val deserializer = AstDeserializerImpl(ion, emptyMap())
deserializer.astVersion = AstVersion.V1
Expand All @@ -139,9 +132,7 @@ class ThreadInterruptedTests {

@Test
fun deserialize_deserializeExprNode() {
// force lazy load
bigSexpAst

val bigSexpAst = makeBigSexpAst()
val deserializer = AstDeserializerImpl(ion, emptyMap())
deserializer.astVersion = AstVersion.V1

Expand All @@ -152,8 +143,6 @@ class ThreadInterruptedTests {

@Test
fun astRewriterBase() {
// force lazy load
reallyBigNAry

@Suppress("DEPRECATION")
val identityRewriter = AstRewriterBase()
Expand All @@ -165,11 +154,14 @@ class ThreadInterruptedTests {
@Test
fun compilerPipeline() {
val numSteps = 10000000
var accumulator= 0L

val pipeline = CompilerPipeline.build(ion) {
repeat(numSteps) {
addPreprocessingStep { expr, _ ->
// burns about 200ms on first run
assert(factorial(Int.MAX_VALUE / 8) >= 0)
// Burn some CPU so we don't get thru all the pipeline steps before the interrupt.
// Adding the return value to accumulator guarantees this won't be elided by the JIT.
accumulator += fibonacci(131071)
expr
}
}
Expand All @@ -181,22 +173,20 @@ class ThreadInterruptedTests {
testThreadInterrupt {
pipeline.executePreProcessingSteps(expr, context)
}
}
}

private fun factorial(num: Int): Long {
var result = 1L
for (i in 2..num) result *= i
return result
}

fun <T> time(message: String = "", block: () -> T): T {
val startTime = System.currentTimeMillis()
// At this point, there's a remote possibility that accumulator has overflowed to zero and the assertion
// below might fail. This guarantees that it will always pass.
if(accumulator == 0L) {
accumulator = 1L
}

return block().also {
val endTime = System.currentTimeMillis()
val duration = endTime - startTime
val of = when(message.length) { 0 -> "" else -> " of $message"}
println("duration$of: $duration")
assertTrue(accumulator != 0L)
}
}

private tailrec fun fibonacci(n: Long, a: Long = 0, b: Long = 1): Long =
when (n) {
0L -> a
1L -> b
else -> fibonacci(n - 1L, b, a + b)
}

0 comments on commit 44d412b

Please sign in to comment.