diff options
-rw-r--r-- | src/actors/scala/actors/Future.scala | 3 | ||||
-rw-r--r-- | src/actors/scala/actors/Reactor.scala | 2 | ||||
-rw-r--r-- | test/files/jvm/t2530.check | 21 | ||||
-rw-r--r-- | test/files/jvm/t2530.scala | 86 |
4 files changed, 111 insertions, 1 deletions
diff --git a/src/actors/scala/actors/Future.scala b/src/actors/scala/actors/Future.scala index e26b0b02df..38b268d795 100644 --- a/src/actors/scala/actors/Future.scala +++ b/src/actors/scala/actors/Future.scala @@ -127,7 +127,8 @@ object Futures { Actor.receive(reaction) } - awaitWith(partFuns) + if (partFuns.length > 0) + awaitWith(partFuns) var results: List[Option[Any]] = Nil val size = resultsMap.size diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala index 7fda8678c1..1015b2eb15 100644 --- a/src/actors/scala/actors/Reactor.scala +++ b/src/actors/scala/actors/Reactor.scala @@ -34,6 +34,7 @@ trait Reactor extends OutputChannel[Any] { /* The actor's mailbox. */ private[actors] val mailbox = new MessageQueue("Reactor") + // guarded by this private[actors] val sendBuffer = new Queue[(Any, OutputChannel[Any])] /* If the actor waits in a react, continuation holds the @@ -121,6 +122,7 @@ trait Reactor extends OutputChannel[Any] { def receiver: Actor = this.asInstanceOf[Actor] + // guarded by this private[actors] def drainSendBuffer(mbox: MessageQueue) { while (!sendBuffer.isEmpty) { val item = sendBuffer.dequeue() diff --git a/test/files/jvm/t2530.check b/test/files/jvm/t2530.check new file mode 100644 index 0000000000..0f1c02158d --- /dev/null +++ b/test/files/jvm/t2530.check @@ -0,0 +1,21 @@ + Iteration 1 succeeded + Iteration 2 succeeded + Iteration 3 succeeded + Iteration 4 succeeded + Iteration 5 succeeded + Iteration 6 succeeded + Iteration 7 succeeded + Iteration 8 succeeded + Iteration 9 succeeded + Iteration 10 succeeded + Iteration 11 succeeded + Iteration 12 succeeded + Iteration 13 succeeded + Iteration 14 succeeded + Iteration 15 succeeded + Iteration 16 succeeded + Iteration 17 succeeded + Iteration 18 succeeded + Iteration 19 succeeded + Iteration 20 succeeded +Test done with no deadlock. Try again, it will not occur... diff --git a/test/files/jvm/t2530.scala b/test/files/jvm/t2530.scala new file mode 100644 index 0000000000..642fb05a5d --- /dev/null +++ b/test/files/jvm/t2530.scala @@ -0,0 +1,86 @@ +import scala.actors.{Future, Futures} + +object Test { + + def main(args:Array[String]) : Unit = { + //scala.actors.Debug.level = 3 + val size = /*if (args.length > 0) Integer.parseInt(args(0)) else*/ 8 + val (m,n) = (size, size) + def random = (for (i <- 0 until m*n) yield java.lang.Math.random).toArray + val A = Matrix(m, n, random) + val B = Matrix(m, n, random) + val format = new java.text.DecimalFormat("000.00'ms'"); + var iter = 1 + val done = 21 + while (iter < done) { + val start = System.nanoTime() + val result = A * B + val time = System.nanoTime() - start + result match { + case Some(result) => { + printf(" Iteration %2d succeeded %n", iter/*, format.format(time / 1e6)*/) + iter += 1 + } + case None => { + printf(">>>> Iteration %2d failed after %s <<<<< %n", iter, format.format(time / 1e6)) + iter = done + } + } + } + println("Test done with no deadlock. Try again, it will not occur...") + } +} + +case class Matrix(numRows: Int, numCols: Int, values: Array[Double]) { + + def this(m:Int, n:Int) = this(m, n, new Array[Double](m*n)) + + def offset(i:Int, j:Int) = i * numCols + j + def apply(i:Int, j:Int) = values( offset(i,j) ) + def update(i:Int, j:Int, value:Double) = values(offset(i, j)) = value; + + def *(by:Matrix) = { + val aM = numRows + val aN = numCols + assert(aM == by.numCols) + assert(aN == by.numRows) + val resultMatrix = new Matrix(aM, aM) + val m = aM.asInstanceOf[Int] + val n = aN.asInstanceOf[Int] + + val rows = for (j <- 0 until m) yield { + Futures.future { + val b_j = new Array[Double](n) + var k = 0 + while (k < n) { // sadly, while loops are still faster than for loops + b_j(k) = by(k,j) + k += 1 + } + var i = 0 + while (i < m) { + var s = 0.0d; + k = 0 + while (k < n) { + s += Matrix.this(i,k) * b_j(k) + k += 1 + } + resultMatrix(i,j) = s + i += 1 + } + //printf("future %d of %d completed.%n", j, m) + j + } + } + + // rows.foreach { x=> x() } // This appears to force sequential execution, so use: + // timeout is 10 years; see http://lampsvn.epfl.ch/trac/scala/ticket/2515 + + val done = Futures.awaitAll(10*365*24*60*60*1000, rows.toArray : _*) // list to array, as varargs. + + if (done.contains(None)) + None + else + Some(resultMatrix) + } + +} |