Skip to content

Commit

Permalink
This is an attempt to prevent concurrency errors in treadle (#93)
Browse files Browse the repository at this point in the history
- For BitMasks use TrieMap and a more careful get or update scheme
- Reference: [github.com/scala/bug/issues/7943](scala/bug#7943)
  • Loading branch information
chick committed Apr 2, 2019
1 parent 77cf325 commit 8262634
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions src/main/scala/treadle/utils/BitUtils.scala
Expand Up @@ -4,7 +4,7 @@ package treadle.utils

import treadle.executable.Big

import scala.collection.mutable
import scala.collection.concurrent.TrieMap

object BitUtils {
//================= Int Section ======================
Expand Down Expand Up @@ -179,17 +179,23 @@ case class BitMasksBigs(bitWidth: Int) {
}

object BitMasks {
private val alreadyCreatedInts = new mutable.HashMap[Int, BitMasksInts]
private val alreadyCreatedLongs = new mutable.HashMap[Int, BitMasksLongs]
private val alreadyCreatedBigs = new mutable.HashMap[Int, BitMasksBigs]
private val alreadyCreatedInts = new TrieMap[Int, BitMasksInts]
private val alreadyCreatedLongs = new TrieMap[Int, BitMasksLongs]
private val alreadyCreatedBigs = new TrieMap[Int, BitMasksBigs]

/** Factory for BitMasksInts
* makes sure there is only one instance per bitWidth
* @param bitWidth signal size
* @return
*/
def getBitMasksInts(bitWidth: Int): BitMasksInts = {
alreadyCreatedInts.getOrElseUpdate(bitWidth, BitMasksInts(bitWidth))

alreadyCreatedInts.get(bitWidth) match {
case Some(v) => v
case None =>
val v = BitMasksInts(bitWidth)
alreadyCreatedInts.putIfAbsent(bitWidth, v).getOrElse(v)
}
}

/** Factory for BitMasksBigs
Expand All @@ -198,7 +204,12 @@ object BitMasks {
* @return
*/
def getBitMasksLongs(bitWidth: Int): BitMasksLongs = {
alreadyCreatedLongs.getOrElseUpdate(bitWidth, BitMasksLongs(bitWidth))
alreadyCreatedLongs.get(bitWidth) match {
case Some(v) => v
case None =>
val v = BitMasksLongs(bitWidth)
alreadyCreatedLongs.putIfAbsent(bitWidth, v).getOrElse(v)
}
}

/** Factory for BitMasksBigs
Expand All @@ -207,6 +218,11 @@ object BitMasks {
* @return
*/
def getBitMasksBigs(bitWidth: Int): BitMasksBigs = {
alreadyCreatedBigs.getOrElseUpdate(bitWidth, BitMasksBigs(bitWidth))
alreadyCreatedBigs.get(bitWidth) match {
case Some(v) => v
case None =>
val v = BitMasksBigs(bitWidth)
alreadyCreatedBigs.putIfAbsent(bitWidth, v).getOrElse(v)
}
}
}

0 comments on commit 8262634

Please sign in to comment.