@@ -7,16 +7,29 @@ package kotlinx.coroutines.experimental.scheduling
77import kotlinx.atomicfu.*
88import kotlinx.coroutines.experimental.*
99import org.junit.Test
10+ import org.junit.runner.*
11+ import org.junit.runners.*
1012import java.util.*
13+ import java.util.concurrent.*
1114import kotlin.test.*
1215
13- class CoroutineSchedulerCloseStressTest : TestBase () {
16+ @RunWith(Parameterized ::class )
17+ class CoroutineSchedulerCloseStressTest (private val mode : Mode ) : TestBase() {
18+ enum class Mode { CPU , BLOCKING , CPU_LIMITED }
19+
20+ companion object {
21+ @Parameterized.Parameters (name = " mode={0}" )
22+ @JvmStatic
23+ fun params (): Collection <Array <Any >> = Mode .values().map { arrayOf<Any >(it) }
24+ }
25+
1426 private val N_REPEAT = 2 * stressTestMultiplier
1527 private val MAX_LEVEL = 5
1628 private val N_COROS = (1 shl (MAX_LEVEL + 1 )) - 1
1729 private val N_THREADS = 4
1830 private val rnd = Random ()
1931
32+ private lateinit var closeableDispatcher: ExperimentalCoroutineDispatcher
2033 private lateinit var dispatcher: ExecutorCoroutineDispatcher
2134 private var closeIndex = - 1
2235
@@ -28,7 +41,7 @@ class CoroutineSchedulerCloseStressTest : TestBase() {
2841 try {
2942 launchCoroutines()
3043 } finally {
31- dispatcher .close()
44+ closeableDispatcher .close()
3245 }
3346 }
3447
@@ -41,7 +54,12 @@ class CoroutineSchedulerCloseStressTest : TestBase() {
4154 }
4255
4356 private fun launchCoroutines () = runBlocking {
44- dispatcher = ExperimentalCoroutineDispatcher (N_THREADS )
57+ closeableDispatcher = ExperimentalCoroutineDispatcher (N_THREADS )
58+ dispatcher = when (mode) {
59+ Mode .CPU -> closeableDispatcher
60+ Mode .CPU_LIMITED -> closeableDispatcher.limited(N_THREADS ) as ExecutorCoroutineDispatcher
61+ Mode .BLOCKING -> closeableDispatcher.blocking(N_THREADS ) as ExecutorCoroutineDispatcher
62+ }
4563 started.value = 0
4664 finished.value = 0
4765 withContext(dispatcher) {
@@ -54,15 +72,19 @@ class CoroutineSchedulerCloseStressTest : TestBase() {
5472 private fun CoroutineScope.launchChild (index : Int , level : Int ): Job = launch(start = CoroutineStart .ATOMIC ) {
5573 started.incrementAndGet()
5674 try {
57- if (index == closeIndex) dispatcher .close()
75+ if (index == closeIndex) closeableDispatcher .close()
5876 if (level < MAX_LEVEL ) {
5977 launchChild(2 * index + 1 , level + 1 )
6078 launchChild(2 * index + 2 , level + 1 )
6179 } else {
62- delay(1000 )
80+ if (rnd.nextBoolean()) {
81+ delay(1000 )
82+ } else {
83+ yield ()
84+ }
6385 }
6486 } finally {
6587 finished.incrementAndGet()
6688 }
6789 }
68- }
90+ }
0 commit comments