@@ -9,38 +9,49 @@ import java.util.concurrent.atomic.AtomicInteger
9
9
import dotty .tools .dotc .core .Phases .Phase
10
10
import dotty .tools .dotc .core .Contexts ._
11
11
12
- sealed trait AsyncHelper {
13
-
14
- def newUnboundedQueueFixedThreadPool
15
- (nThreads : Int ,
16
- shortId : String , priority : Int = Thread .NORM_PRIORITY ) : ThreadPoolExecutor
17
- def newBoundedQueueFixedThreadPool
18
- (nThreads : Int , maxQueueSize : Int , rejectHandler : RejectedExecutionHandler ,
19
- shortId : String , priority : Int = Thread .NORM_PRIORITY ) : ThreadPoolExecutor
12
+ sealed trait ThreadPoolFactory {
13
+
14
+ def newUnboundedQueueFixedThreadPool (
15
+ nThreads : Int ,
16
+ shortId : String ,
17
+ priority : Int = Thread .NORM_PRIORITY ) : ThreadPoolExecutor
18
+
19
+ def newBoundedQueueFixedThreadPool (
20
+ nThreads : Int ,
21
+ maxQueueSize : Int ,
22
+ rejectHandler : RejectedExecutionHandler ,
23
+ shortId : String ,
24
+ priority : Int = Thread .NORM_PRIORITY ) : ThreadPoolExecutor
20
25
}
21
26
22
27
23
- object AsyncHelper {
24
- def apply (phase : Phase )(using Context ): AsyncHelper = ctx.profiler match {
25
- case NoOpProfiler => new BasicAsyncHelper (phase)
26
- case r : RealProfiler => new ProfilingAsyncHelper (phase, r)
28
+ object ThreadPoolFactory {
29
+ def apply (phase : Phase )(using Context ): ThreadPoolFactory = ctx.profiler match {
30
+ case NoOpProfiler => new BasicThreadPoolFactory (phase)
31
+ case r : RealProfiler => new ProfilingThreadPoolFactory (phase, r)
27
32
}
28
33
29
- private abstract class BaseAsyncHelper (phase : Phase )( using Context ) extends AsyncHelper {
34
+ private abstract class BaseThreadPoolFactory (phase : Phase ) extends ThreadPoolFactory {
30
35
val baseGroup = new ThreadGroup (s " dotc- ${phase.phaseName}" )
36
+
31
37
private def childGroup (name : String ) = new ThreadGroup (baseGroup, name)
32
38
33
- protected def wrapRunnable (r : Runnable , shortId: String ): Runnable
39
+ // Invoked when a new `Worker` is created, see `CommonThreadFactory.newThread`
40
+ protected def wrapWorker (worker : Runnable , shortId: String ): Runnable = worker
34
41
35
- protected class CommonThreadFactory (shortId : String ,
36
- daemon : Boolean = true ,
37
- priority : Int ) extends ThreadFactory {
42
+ protected final class CommonThreadFactory (
43
+ shortId : String ,
44
+ daemon : Boolean = true ,
45
+ priority : Int ) extends ThreadFactory {
38
46
private val group : ThreadGroup = childGroup(shortId)
39
47
private val threadNumber : AtomicInteger = new AtomicInteger (1 )
40
48
private val namePrefix = s " ${baseGroup.getName}- $shortId- "
41
49
42
- override def newThread (r : Runnable ): Thread = {
43
- val wrapped = wrapRunnable(r, shortId)
50
+ // Invoked by the `ThreadPoolExecutor` when creating a new worker thread. The argument
51
+ // runnable is the `Worker` (which extends `Runnable`). Its `run` method gets tasks from
52
+ // the thread pool and executes them (on the thread created here).
53
+ override def newThread (worker : Runnable ): Thread = {
54
+ val wrapped = wrapWorker(worker, shortId)
44
55
val t : Thread = new Thread (group, wrapped, namePrefix + threadNumber.getAndIncrement, 0 )
45
56
if (t.isDaemon != daemon) t.setDaemon(daemon)
46
57
if (t.getPriority != priority) t.setPriority(priority)
@@ -49,7 +60,7 @@ object AsyncHelper {
49
60
}
50
61
}
51
62
52
- private final class BasicAsyncHelper (phase : Phase )( using Context ) extends BaseAsyncHelper (phase) {
63
+ private final class BasicThreadPoolFactory (phase : Phase ) extends BaseThreadPoolFactory (phase) {
53
64
54
65
override def newUnboundedQueueFixedThreadPool (nThreads : Int , shortId : String , priority : Int ): ThreadPoolExecutor = {
55
66
val threadFactory = new CommonThreadFactory (shortId, priority = priority)
@@ -62,11 +73,9 @@ object AsyncHelper {
62
73
// like Executors.newFixedThreadPool
63
74
new ThreadPoolExecutor (nThreads, nThreads, 0L , TimeUnit .MILLISECONDS , new ArrayBlockingQueue [Runnable ](maxQueueSize), threadFactory, rejectHandler)
64
75
}
65
-
66
- override protected def wrapRunnable (r : Runnable , shortId: String ): Runnable = r
67
76
}
68
77
69
- private class ProfilingAsyncHelper (phase : Phase , private val profiler : RealProfiler )( using Context ) extends BaseAsyncHelper (phase) {
78
+ private class ProfilingThreadPoolFactory (phase : Phase , private val profiler : RealProfiler ) extends BaseThreadPoolFactory (phase) {
70
79
71
80
override def newUnboundedQueueFixedThreadPool (nThreads : Int , shortId : String , priority : Int ): ThreadPoolExecutor = {
72
81
val threadFactory = new CommonThreadFactory (shortId, priority = priority)
@@ -80,13 +89,13 @@ object AsyncHelper {
80
89
new SinglePhaseInstrumentedThreadPoolExecutor (nThreads, nThreads, 0L , TimeUnit .MILLISECONDS , new ArrayBlockingQueue [Runnable ](maxQueueSize), threadFactory, rejectHandler)
81
90
}
82
91
83
- override protected def wrapRunnable ( r : Runnable , shortId: String ): Runnable = {
92
+ override protected def wrapWorker ( worker : Runnable , shortId : String ): Runnable = {
84
93
() =>
85
94
val data = new ThreadProfileData
86
95
localData.set(data)
87
96
88
97
val profileStart = profiler.snapThread(0 )
89
- try r .run finally {
98
+ try worker .run finally {
90
99
val snap = profiler.snapThread(data.idleNs)
91
100
val threadRange = ProfileRange (profileStart, snap, phase, shortId, data.taskCount, Thread .currentThread())
92
101
profiler.completeBackground(threadRange)
0 commit comments