Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a23bf88

Browse files
committed
implement:priority-queue/support
1 parent 02a4dda commit a23bf88

File tree

1 file changed

+46
-39
lines changed

1 file changed

+46
-39
lines changed
+46-39
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
// This file contains the job queue implementation which re-order jobs based on their priority.
2-
// The current implementation is much simple to be easily debugged, but should be re-implemented
3-
// using priority queue ideally.
42

53
import _CJavaScriptEventLoop
64

7-
#if compiler(>=5.5)
8-
95
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
106
struct QueueState: Sendable {
117
fileprivate var headJob: UnownedJob? = nil
@@ -14,51 +10,66 @@ struct QueueState: Sendable {
1410

1511
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
1612
extension JavaScriptEventLoop {
13+
private var queueLock: NSLock {
14+
NSLock()
15+
}
1716

1817
func insertJobQueue(job newJob: UnownedJob) {
19-
withUnsafeMutablePointer(to: &queueState.headJob) { headJobPtr in
20-
var position: UnsafeMutablePointer<UnownedJob?> = headJobPtr
21-
while let cur = position.pointee {
22-
if cur.rawPriority < newJob.rawPriority {
23-
newJob.nextInQueue().pointee = cur
24-
position.pointee = newJob
25-
return
26-
}
27-
position = cur.nextInQueue()
28-
}
29-
newJob.nextInQueue().pointee = nil
30-
position.pointee = newJob
31-
}
18+
queueLock.lock()
19+
defer { queueLock.unlock() }
20+
21+
insertJob(newJob)
3222

33-
// TODO: use CAS when supporting multi-threaded environment
3423
if !queueState.isSpinning {
35-
self.queueState.isSpinning = true
24+
queueState.isSpinning = true
3625
JavaScriptEventLoop.shared.queueMicrotask {
3726
self.runAllJobs()
3827
}
3928
}
4029
}
4130

31+
private func insertJob(_ newJob: UnownedJob) {
32+
var current = queueState.headJob
33+
var previous: UnownedJob? = nil
34+
35+
while let cur = current, cur.rawPriority >= newJob.rawPriority {
36+
previous = cur
37+
current = cur.nextInQueue().pointee
38+
}
39+
40+
newJob.nextInQueue().pointee = current
41+
if let prev = previous {
42+
prev.nextInQueue().pointee = newJob
43+
} else {
44+
queueState.headJob = newJob
45+
}
46+
}
47+
4248
func runAllJobs() {
4349
assert(queueState.isSpinning)
4450

45-
while let job = self.claimNextFromQueue() {
46-
#if compiler(>=5.9)
47-
job.runSynchronously(on: self.asUnownedSerialExecutor())
48-
#else
49-
job._runSynchronously(on: self.asUnownedSerialExecutor())
50-
#endif
51+
while let job = claimNextFromQueue() {
52+
executeJob(job)
5153
}
5254

5355
queueState.isSpinning = false
5456
}
5557

58+
private func executeJob(_ job: UnownedJob) {
59+
#if compiler(>=5.9)
60+
job.runSynchronously(on: self.asUnownedSerialExecutor())
61+
#else
62+
job._runSynchronously(on: self.asUnownedSerialExecutor())
63+
#endif
64+
}
65+
5666
func claimNextFromQueue() -> UnownedJob? {
57-
if let job = self.queueState.headJob {
58-
self.queueState.headJob = job.nextInQueue().pointee
59-
return job
60-
}
61-
return nil
67+
queueLock.lock()
68+
defer { queueLock.unlock() }
69+
70+
guard let job = queueState.headJob else { return nil }
71+
queueState.headJob = job.nextInQueue().pointee
72+
return job
6273
}
6374
}
6475

@@ -75,21 +86,17 @@ fileprivate extension UnownedJob {
7586
var rawPriority: UInt32 { flags.priority }
7687

7788
func nextInQueue() -> UnsafeMutablePointer<UnownedJob?> {
78-
return withUnsafeMutablePointer(to: &asImpl().pointee.SchedulerPrivate.0) { rawNextJobPtr in
79-
let nextJobPtr = UnsafeMutableRawPointer(rawNextJobPtr).bindMemory(to: UnownedJob?.self, capacity: 1)
80-
return nextJobPtr
89+
withUnsafeMutablePointer(to: &asImpl().pointee.SchedulerPrivate.0) { rawNextJobPtr in
90+
UnsafeMutableRawPointer(rawNextJobPtr).bindMemory(to: UnownedJob?.self, capacity: 1)
8191
}
8292
}
83-
8493
}
8594

8695
fileprivate struct JobFlags {
8796
var bits: UInt32 = 0
8897

89-
var priority: UInt32 {
90-
get {
91-
(bits & 0xFF00) >> 8
98+
var priority: UInt32 {
99+
(bits & 0xFF00) >> 8
92100
}
93-
}
94101
}
95-
#endif
102+
#endif

0 commit comments

Comments
 (0)