Skip to content

Commit

Permalink
Possibly speed up BlockingCircularQueue
Browse files Browse the repository at this point in the history
- Independent read and write locks, so the writer doesn't have to
contend with readers.
- Add call to super.paintComponent
- Remove debug output
  • Loading branch information
noelwelsh committed Sep 21, 2024
1 parent 44e83fa commit bbb36a0
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,43 @@ final class BlockingCircularQueue[A: ClassTag](capacity: Int) {
private val data: Array[A] = Array.ofDim(capacity)
private var writeIdx = 0
private var readIdx = 0

private val readLock = Object()
private val writeLock = Object()

// Number of elements that can be read from data. 0 <= readable < capacity
var readable = 0

def add(e: A): Boolean = {
// Acquire the monitor, so we can safely modify internal state and notify
// readers waiting on it when we've added the element.
this.synchronized {
try {
data(writeIdx) = e
readable = (readable + 1).min(capacity)
writeLock.synchronized {
readLock.synchronized {

try {
data(writeIdx) = e
readable = (readable + 1).min(capacity)

// If we just caught up to readIdx, increement readIdx so it now points
// to the oldest data
if writeIdx == readIdx && readable == capacity
then readIdx = (readIdx + 1) % capacity
// If we just caught up to readIdx, increement readIdx so it now points
// to the oldest data
if writeIdx == readIdx && readable == capacity
then readIdx = (readIdx + 1) % capacity

writeIdx = (writeIdx + 1) % capacity
} finally {
// Wake up any readers waiting for data
this.notifyAll()
writeIdx = (writeIdx + 1) % capacity
} finally {
// Wake up any readers waiting for data
readLock.notifyAll()
}
}
}

true
true
}
}

def take(): A = {
this.synchronized {
readLock.synchronized {
while readable == 0 do {
this.wait()
readLock.wait()
}

val elt = data(readIdx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ final class Java2DPanel(
}

override def paintComponent(context: Graphics): Unit = {
super.paintComponents(context)
val gc = context.asInstanceOf[Graphics2D]
Java2d.setup(gc)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ object Pointillism extends IOApp {

clicks
.scan(List.empty[Point])((pts, pt) => pt :: pts)
.debug(a => s"Point $a")
.map(pts => curve(pts))
.evalMap(picture => canvas.render(picture))
.compile
Expand Down

0 comments on commit bbb36a0

Please sign in to comment.