From a1f098795934a4ccc8a3e72b779e47b911eae0f4 Mon Sep 17 00:00:00 2001 From: Philipp Haller Date: Sun, 24 May 2009 14:15:40 +0000 Subject: Fixed #1999. --- src/actors/scala/actors/Scheduler.scala | 18 +------ .../tools/partest/nest/ConsoleFileManager.scala | 8 ++- .../scala/tools/partest/nest/ConsoleRunner.scala | 5 +- .../scala/tools/partest/nest/FileManager.scala | 14 +++++ src/partest/scala/tools/partest/nest/Worker.scala | 10 +--- test/files/jvm/actorgc_leak.check | 1 + test/files/jvm/actorgc_leak.scala | 63 ++++++++++++++++++++++ 7 files changed, 90 insertions(+), 29 deletions(-) create mode 100644 test/files/jvm/actorgc_leak.check create mode 100644 test/files/jvm/actorgc_leak.scala diff --git a/src/actors/scala/actors/Scheduler.scala b/src/actors/scala/actors/Scheduler.scala index 1d87c7a3c2..44371879a3 100644 --- a/src/actors/scala/actors/Scheduler.scala +++ b/src/actors/scala/actors/Scheduler.scala @@ -88,25 +88,11 @@ object Scheduler extends IScheduler { } def execute(task: Runnable) { - val t = currentThread - if (t.isInstanceOf[FJTaskRunner]) { - val tr = t.asInstanceOf[FJTaskRunner] - tr.push(new FJTask { - def run() { task.run() } - }) - } else - sched execute task + sched execute task } def execute(fun: => Unit) { - val t = currentThread - if (t.isInstanceOf[FJTaskRunner]) { - val tr = t.asInstanceOf[FJTaskRunner] - tr.push(new FJTask { - def run() { fun } - }) - } else - sched execute { fun } + sched execute { fun } } def shutdown() = sched.shutdown() diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala index cc6961f1bf..e33e12af4c 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala @@ -277,7 +277,7 @@ else def getFiles(kind: String, doCheck: Boolean, filter: Option[(String, Boolean)]): List[File] = { val dir = new File(srcDir, kind) NestUI.verbose("look in "+dir+" for tests") - if (dir.isDirectory) { + val files = if (dir.isDirectory) { if (!testFiles.isEmpty) { val dirpath = dir.getAbsolutePath testFiles filter { _.getParentFile.getAbsolutePath == dirpath } @@ -296,11 +296,15 @@ else } dir.listFiles(filter).toList } else // skip - Nil + Nil } else { NestUI.failure("Directory \"" + dir.getPath + "\" not found") Nil } + if (failed) + files filter { logFileExists(_, kind) } + else + files } def getFiles(kind: String, doCheck: Boolean): List[File] = diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala index 513aee5350..1a2cfd6580 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala @@ -23,8 +23,6 @@ class ConsoleRunner extends DirectRunner with RunnerUtils { List( TestSet("pos", fileFilter, "pos", "Testing compiler (on files whose compilation should succeed)"), - TestSet("pos5", fileFilter, "pos", - "Testing compiler (on files whose compilation should succeed on 1.5 JVM)"), TestSet("neg", fileFilter, "neg", "Testing compiler (on files whose compilation should fail)"), TestSet("run", fileFilter, "run", "Testing JVM backend"), @@ -179,10 +177,11 @@ class ConsoleRunner extends DirectRunner with RunnerUtils { val TestSet(loc, filter, kind, msg) = testSet val files = fileManager.getFiles(loc, true, filter) if (!files.isEmpty) { + NestUI.verbose("test files: "+files) NestUI.outline("\n"+msg+"\n") runTestsForFiles(files, kind) } else { - NestUI.failure("test dir empty\n") + NestUI.verbose("test dir empty\n") (0, 0) } } diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala index 625173b767..9c87e7ed6d 100644 --- a/src/partest/scala/tools/partest/nest/FileManager.scala +++ b/src/partest/scala/tools/partest/nest/FileManager.scala @@ -65,4 +65,18 @@ trait FileManager { var JAVA_OPTS = System.getProperty("scalatest.java_opts", "") var timeout = "1200000" + + def getLogFile(dir: File, fileBase: String, kind: String): LogFile = + new LogFile(dir, fileBase + "-" + kind + ".log") + + def getLogFile(file: File, kind: String): LogFile = { + val dir = file.getParentFile + val fileBase = basename(file.getName) + getLogFile(dir, fileBase, kind) + } + + def logFileExists(file: File, kind: String): Boolean = { + val logFile = getLogFile(file, kind) + logFile.exists && logFile.canRead + } } diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index cc664e37ae..22fb6d606e 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -92,18 +92,12 @@ class Worker(val fileManager: FileManager) extends Actor { var createdLogFiles: List[LogFile] = List() var createdOutputDirs: List[File] = List() - def createLogFile(dir: File, fileBase: String, kind: String): LogFile = { - val logFile = new LogFile(dir, fileBase + "-" + kind + ".log") + def createLogFile(file: File, kind: String): LogFile = { + val logFile = fileManager.getLogFile(file, kind) createdLogFiles = logFile :: createdLogFiles logFile } - def createLogFile(file: File, kind: String): LogFile = { - val dir = file.getParentFile - val fileBase = basename(file.getName) - createLogFile(dir, fileBase, kind) - } - def createOutputDir(dir: File, fileBase: String, kind: String): File = { val outDir = new File(dir, fileBase + "-" + kind + ".obj") if (!outDir.exists) diff --git a/test/files/jvm/actorgc_leak.check b/test/files/jvm/actorgc_leak.check new file mode 100644 index 0000000000..a965a70ed4 --- /dev/null +++ b/test/files/jvm/actorgc_leak.check @@ -0,0 +1 @@ +Done diff --git a/test/files/jvm/actorgc_leak.scala b/test/files/jvm/actorgc_leak.scala new file mode 100644 index 0000000000..5e2b9d51e1 --- /dev/null +++ b/test/files/jvm/actorgc_leak.scala @@ -0,0 +1,63 @@ + +import scala.actors.Actor + +object Test { + class FatActorFactory extends Actor { + def act() { + var cnt = 0 + Actor.loopWhile(cnt < fatActors) { + //if ((cnt % 5) == 0) println(cnt) + val fa = new FatActor() + fa.start() + cnt += 1 + if (cnt == fatActors) Monitor ! 'done + } + } + } + + class FatActor extends Actor { + def act() { + fat = new Array[Int](fatness) + react { + case 'hi => exit() + } + } + private var fat: Array[Int] = _ + } + + object Monitor extends Actor { + private var cnt = 0 + def act() { + Actor.loop { + react { + case 'done => { + cnt += 1 + if (cnt == factories) System.exit(0) // once GC pressure stops FatActors stop being collected, and as + } // a result ActorGC never finds out that they are defunct + } + } + } + } + + val factories = 4 // the number of factories to start + val fatActors = 50 // the number of FatActors for each factory to produce + val fatness = 1024*1024*10 + + def main(args: Array[String]) { + scala.actors.Scheduler.impl.shutdown() + val sched = { + val s = new scala.actors.FJTaskScheduler2 + s.start() + s + } + scala.actors.Scheduler.impl = sched + + Monitor.start() + for(i <- 1 to factories) { + //if ((i % 50) == 0) println(i) + val fa = new FatActorFactory() + fa.start() + } + println("Done") + } +} -- cgit v1.2.3