From 00c1ddf1811f1d4560cad91cf50c0a370323319d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Sun, 15 Jan 2017 14:39:19 +0100 Subject: [PATCH 01/11] useIncrementalCompilation = false avoid recompilation of all files every time, caused by known yet unfixed bugs. Also update to recent version See: - https://stackoverflow.com/questions/16963012/maven-compiler-recompile-all-files-instead-modified/19653164#19653164 - https://issues.apache.org/jira/browse/MCOMPILER-209 - https://issues.apache.org/jira/browse/MCOMPILER-205 --- org.coreasm.engine/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/org.coreasm.engine/pom.xml b/org.coreasm.engine/pom.xml index 465c825c..6b447a5d 100644 --- a/org.coreasm.engine/pom.xml +++ b/org.coreasm.engine/pom.xml @@ -96,9 +96,11 @@ org.apache.maven.plugins maven-compiler-plugin + 3.6.0 1.7 1.7 + false From 53e497919edfeee98454661a883b0a64a720882b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Sat, 14 Jan 2017 17:37:00 +0100 Subject: [PATCH 02/11] create additional test-jar Useful for external projects depending on test classes like the TestEngineDriver. --- org.coreasm.engine/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/org.coreasm.engine/pom.xml b/org.coreasm.engine/pom.xml index 6b447a5d..049f7cbd 100644 --- a/org.coreasm.engine/pom.xml +++ b/org.coreasm.engine/pom.xml @@ -91,6 +91,13 @@ maven-jar-plugin 2.4 + + + + test-jar + + + From a87d58f0ad14ecfc5011c1da5abe7b2d85d95d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Sat, 14 Jan 2017 17:37:31 +0100 Subject: [PATCH 03/11] move test-rsc/plugins to test-rsc/plugin-tests PluginClassLoader.loadCatalog(..., "plugins/") tries to load plugins from the test-rsc resp. from the test-jar as the folder name conflicts with the actual plugin folder. --- .../test-rsc/{plugins => plugin-tests}/caserule/Case1.casm | 0 .../test-rsc/{plugins => plugin-tests}/chooserule/Pick1.casm | 0 .../test-rsc/{plugins => plugin-tests}/chooserule/TestChoose.casm | 0 .../{plugins => plugin-tests}/collection/Collection1.casm | 0 .../test-rsc/{plugins => plugin-tests}/conditionalrule/If1.casm | 0 .../conditionalrule/TestConditionalTerm.casm | 0 .../test-rsc/{plugins => plugin-tests}/debuginfo/Debug1.casm | 0 .../test-rsc/{plugins => plugin-tests}/extendrule/Extend1.casm | 0 .../test-rsc/{plugins => plugin-tests}/forallrule/Forall1.casm | 0 .../test-rsc/{plugins => plugin-tests}/forallrule/Forall2.casm | 0 .../test-rsc/{plugins => plugin-tests}/foreachrule/Foreach1.casm | 0 .../test-rsc/{plugins => plugin-tests}/foreachrule/Foreach2.casm | 0 .../test-rsc/{plugins => plugin-tests}/io/TestIO1.casm | 0 .../{plugins => plugin-tests}/kernelextensions/Kernel1.casm | 0 .../test-rsc/{plugins => plugin-tests}/letrule/Let1.casm | 0 .../test-rsc/{plugins => plugin-tests}/letrule/LetResult1.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List10_drop.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List11_reverse.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List12_indexes.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List13_zip.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List14_zipwith.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List15_replicate.casm | 0 .../{plugins => plugin-tests}/list/List16_adding_removing.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List17_shift.casm | 0 .../{plugins => plugin-tests}/list/List18_comprehension.casm | 0 .../{plugins => plugin-tests}/list/List1_concatenation.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List2_head.casm | 0 .../{plugins => plugin-tests}/list/List3_flattenList.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List4_tail.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List5_last.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List6_cons.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List7_nth.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List8_setnth.casm | 0 .../test-rsc/{plugins => plugin-tests}/list/List9_take.casm | 0 .../test-rsc/{plugins => plugin-tests}/map/Map1_mapToPairs.casm | 0 .../test-rsc/{plugins => plugin-tests}/map/Map2_toMap.casm | 0 .../test-rsc/{plugins => plugin-tests}/map/Map3_add.casm | 0 .../test-rsc/{plugins => plugin-tests}/map/Map4_remove.casm | 0 .../{plugins => plugin-tests}/map/Map5_comprehension.casm | 0 .../{plugins => plugin-tests}/modularity/Modularity1.casm | 0 .../{plugins => plugin-tests}/modularity/ModularityTest.txt | 0 .../{plugins => plugin-tests}/number/Number1_functions.casm | 0 .../{plugins => plugin-tests}/number/Number2_numberRange.casm | 0 .../predicatelogic/PredicateLogic1_binaryOperations.casm | 0 .../predicatelogic/PredicateLogic2_ExistsIn.casm | 0 .../predicatelogic/PredicateLogic3_forallHold.casm | 0 .../predicatelogic/PredicateLogic4_not_notEqual.casm | 0 .../test-rsc/{plugins => plugin-tests}/queue/Queue1.casm | 0 .../{plugins => plugin-tests}/schedulingpolicies/Schedul1.casm | 0 .../{plugins => plugin-tests}/set/Set1_comprehension.casm | 0 .../{plugins => plugin-tests}/set/Set2_adding_removing.casm | 0 .../test-rsc/{plugins => plugin-tests}/set/Set3_binary.casm | 0 .../test-rsc/{plugins => plugin-tests}/signature/Signature1.casm | 0 .../signature/Signature2_derivedFunctions.casm | 0 .../test-rsc/{plugins => plugin-tests}/stack/Stack1.casm | 0 .../{plugins => plugin-tests}/string/String1_toString.casm | 0 .../test-rsc/{plugins => plugin-tests}/string/String2_strlen.casm | 0 .../{plugins => plugin-tests}/string/String3_matches.casm | 0 .../test-rsc/{plugins => plugin-tests}/time/Time1.casm | 0 .../{plugins => plugin-tests}/turboasm/TestAggregation.casm | 0 .../{plugins => plugin-tests}/turboasm/TurboASM1_iterate.casm | 0 .../{plugins => plugin-tests}/turboasm/TurboASM2_seqblock.casm | 0 .../{plugins => plugin-tests}/turboasm/TurboASM3_seq.casm | 0 .../{plugins => plugin-tests}/turboasm/TurboASM4_return.casm | 0 .../{plugins => plugin-tests}/turboasm/TurboASM5_local.casm | 0 .../{plugins => plugin-tests}/turboasm/TurboASM6_loc.casm | 0 .../{plugins => plugin-tests}/turboasm/TurboASM7_while.casm | 0 67 files changed, 0 insertions(+), 0 deletions(-) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/caserule/Case1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/chooserule/Pick1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/chooserule/TestChoose.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/collection/Collection1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/conditionalrule/If1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/conditionalrule/TestConditionalTerm.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/debuginfo/Debug1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/extendrule/Extend1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/forallrule/Forall1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/forallrule/Forall2.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/foreachrule/Foreach1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/foreachrule/Foreach2.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/io/TestIO1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/kernelextensions/Kernel1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/letrule/Let1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/letrule/LetResult1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List10_drop.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List11_reverse.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List12_indexes.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List13_zip.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List14_zipwith.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List15_replicate.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List16_adding_removing.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List17_shift.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List18_comprehension.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List1_concatenation.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List2_head.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List3_flattenList.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List4_tail.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List5_last.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List6_cons.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List7_nth.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List8_setnth.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/list/List9_take.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/map/Map1_mapToPairs.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/map/Map2_toMap.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/map/Map3_add.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/map/Map4_remove.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/map/Map5_comprehension.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/modularity/Modularity1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/modularity/ModularityTest.txt (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/number/Number1_functions.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/number/Number2_numberRange.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/predicatelogic/PredicateLogic1_binaryOperations.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/predicatelogic/PredicateLogic2_ExistsIn.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/predicatelogic/PredicateLogic3_forallHold.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/predicatelogic/PredicateLogic4_not_notEqual.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/queue/Queue1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/schedulingpolicies/Schedul1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/set/Set1_comprehension.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/set/Set2_adding_removing.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/set/Set3_binary.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/signature/Signature1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/signature/Signature2_derivedFunctions.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/stack/Stack1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/string/String1_toString.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/string/String2_strlen.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/string/String3_matches.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/time/Time1.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/turboasm/TestAggregation.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/turboasm/TurboASM1_iterate.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/turboasm/TurboASM2_seqblock.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/turboasm/TurboASM3_seq.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/turboasm/TurboASM4_return.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/turboasm/TurboASM5_local.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/turboasm/TurboASM6_loc.casm (100%) rename org.coreasm.engine/test-rsc/{plugins => plugin-tests}/turboasm/TurboASM7_while.casm (100%) diff --git a/org.coreasm.engine/test-rsc/plugins/caserule/Case1.casm b/org.coreasm.engine/test-rsc/plugin-tests/caserule/Case1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/caserule/Case1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/caserule/Case1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/chooserule/Pick1.casm b/org.coreasm.engine/test-rsc/plugin-tests/chooserule/Pick1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/chooserule/Pick1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/chooserule/Pick1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/chooserule/TestChoose.casm b/org.coreasm.engine/test-rsc/plugin-tests/chooserule/TestChoose.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/chooserule/TestChoose.casm rename to org.coreasm.engine/test-rsc/plugin-tests/chooserule/TestChoose.casm diff --git a/org.coreasm.engine/test-rsc/plugins/collection/Collection1.casm b/org.coreasm.engine/test-rsc/plugin-tests/collection/Collection1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/collection/Collection1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/collection/Collection1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/conditionalrule/If1.casm b/org.coreasm.engine/test-rsc/plugin-tests/conditionalrule/If1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/conditionalrule/If1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/conditionalrule/If1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/conditionalrule/TestConditionalTerm.casm b/org.coreasm.engine/test-rsc/plugin-tests/conditionalrule/TestConditionalTerm.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/conditionalrule/TestConditionalTerm.casm rename to org.coreasm.engine/test-rsc/plugin-tests/conditionalrule/TestConditionalTerm.casm diff --git a/org.coreasm.engine/test-rsc/plugins/debuginfo/Debug1.casm b/org.coreasm.engine/test-rsc/plugin-tests/debuginfo/Debug1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/debuginfo/Debug1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/debuginfo/Debug1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/extendrule/Extend1.casm b/org.coreasm.engine/test-rsc/plugin-tests/extendrule/Extend1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/extendrule/Extend1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/extendrule/Extend1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/forallrule/Forall1.casm b/org.coreasm.engine/test-rsc/plugin-tests/forallrule/Forall1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/forallrule/Forall1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/forallrule/Forall1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/forallrule/Forall2.casm b/org.coreasm.engine/test-rsc/plugin-tests/forallrule/Forall2.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/forallrule/Forall2.casm rename to org.coreasm.engine/test-rsc/plugin-tests/forallrule/Forall2.casm diff --git a/org.coreasm.engine/test-rsc/plugins/foreachrule/Foreach1.casm b/org.coreasm.engine/test-rsc/plugin-tests/foreachrule/Foreach1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/foreachrule/Foreach1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/foreachrule/Foreach1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/foreachrule/Foreach2.casm b/org.coreasm.engine/test-rsc/plugin-tests/foreachrule/Foreach2.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/foreachrule/Foreach2.casm rename to org.coreasm.engine/test-rsc/plugin-tests/foreachrule/Foreach2.casm diff --git a/org.coreasm.engine/test-rsc/plugins/io/TestIO1.casm b/org.coreasm.engine/test-rsc/plugin-tests/io/TestIO1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/io/TestIO1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/io/TestIO1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/kernelextensions/Kernel1.casm b/org.coreasm.engine/test-rsc/plugin-tests/kernelextensions/Kernel1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/kernelextensions/Kernel1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/kernelextensions/Kernel1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/letrule/Let1.casm b/org.coreasm.engine/test-rsc/plugin-tests/letrule/Let1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/letrule/Let1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/letrule/Let1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/letrule/LetResult1.casm b/org.coreasm.engine/test-rsc/plugin-tests/letrule/LetResult1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/letrule/LetResult1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/letrule/LetResult1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List10_drop.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List10_drop.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List10_drop.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List10_drop.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List11_reverse.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List11_reverse.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List11_reverse.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List11_reverse.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List12_indexes.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List12_indexes.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List12_indexes.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List12_indexes.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List13_zip.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List13_zip.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List13_zip.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List13_zip.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List14_zipwith.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List14_zipwith.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List14_zipwith.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List14_zipwith.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List15_replicate.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List15_replicate.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List15_replicate.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List15_replicate.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List16_adding_removing.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List16_adding_removing.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List16_adding_removing.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List16_adding_removing.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List17_shift.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List17_shift.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List17_shift.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List17_shift.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List18_comprehension.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List18_comprehension.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List18_comprehension.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List18_comprehension.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List1_concatenation.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List1_concatenation.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List1_concatenation.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List1_concatenation.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List2_head.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List2_head.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List2_head.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List2_head.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List3_flattenList.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List3_flattenList.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List3_flattenList.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List3_flattenList.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List4_tail.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List4_tail.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List4_tail.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List4_tail.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List5_last.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List5_last.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List5_last.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List5_last.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List6_cons.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List6_cons.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List6_cons.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List6_cons.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List7_nth.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List7_nth.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List7_nth.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List7_nth.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List8_setnth.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List8_setnth.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List8_setnth.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List8_setnth.casm diff --git a/org.coreasm.engine/test-rsc/plugins/list/List9_take.casm b/org.coreasm.engine/test-rsc/plugin-tests/list/List9_take.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/list/List9_take.casm rename to org.coreasm.engine/test-rsc/plugin-tests/list/List9_take.casm diff --git a/org.coreasm.engine/test-rsc/plugins/map/Map1_mapToPairs.casm b/org.coreasm.engine/test-rsc/plugin-tests/map/Map1_mapToPairs.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/map/Map1_mapToPairs.casm rename to org.coreasm.engine/test-rsc/plugin-tests/map/Map1_mapToPairs.casm diff --git a/org.coreasm.engine/test-rsc/plugins/map/Map2_toMap.casm b/org.coreasm.engine/test-rsc/plugin-tests/map/Map2_toMap.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/map/Map2_toMap.casm rename to org.coreasm.engine/test-rsc/plugin-tests/map/Map2_toMap.casm diff --git a/org.coreasm.engine/test-rsc/plugins/map/Map3_add.casm b/org.coreasm.engine/test-rsc/plugin-tests/map/Map3_add.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/map/Map3_add.casm rename to org.coreasm.engine/test-rsc/plugin-tests/map/Map3_add.casm diff --git a/org.coreasm.engine/test-rsc/plugins/map/Map4_remove.casm b/org.coreasm.engine/test-rsc/plugin-tests/map/Map4_remove.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/map/Map4_remove.casm rename to org.coreasm.engine/test-rsc/plugin-tests/map/Map4_remove.casm diff --git a/org.coreasm.engine/test-rsc/plugins/map/Map5_comprehension.casm b/org.coreasm.engine/test-rsc/plugin-tests/map/Map5_comprehension.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/map/Map5_comprehension.casm rename to org.coreasm.engine/test-rsc/plugin-tests/map/Map5_comprehension.casm diff --git a/org.coreasm.engine/test-rsc/plugins/modularity/Modularity1.casm b/org.coreasm.engine/test-rsc/plugin-tests/modularity/Modularity1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/modularity/Modularity1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/modularity/Modularity1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/modularity/ModularityTest.txt b/org.coreasm.engine/test-rsc/plugin-tests/modularity/ModularityTest.txt similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/modularity/ModularityTest.txt rename to org.coreasm.engine/test-rsc/plugin-tests/modularity/ModularityTest.txt diff --git a/org.coreasm.engine/test-rsc/plugins/number/Number1_functions.casm b/org.coreasm.engine/test-rsc/plugin-tests/number/Number1_functions.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/number/Number1_functions.casm rename to org.coreasm.engine/test-rsc/plugin-tests/number/Number1_functions.casm diff --git a/org.coreasm.engine/test-rsc/plugins/number/Number2_numberRange.casm b/org.coreasm.engine/test-rsc/plugin-tests/number/Number2_numberRange.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/number/Number2_numberRange.casm rename to org.coreasm.engine/test-rsc/plugin-tests/number/Number2_numberRange.casm diff --git a/org.coreasm.engine/test-rsc/plugins/predicatelogic/PredicateLogic1_binaryOperations.casm b/org.coreasm.engine/test-rsc/plugin-tests/predicatelogic/PredicateLogic1_binaryOperations.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/predicatelogic/PredicateLogic1_binaryOperations.casm rename to org.coreasm.engine/test-rsc/plugin-tests/predicatelogic/PredicateLogic1_binaryOperations.casm diff --git a/org.coreasm.engine/test-rsc/plugins/predicatelogic/PredicateLogic2_ExistsIn.casm b/org.coreasm.engine/test-rsc/plugin-tests/predicatelogic/PredicateLogic2_ExistsIn.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/predicatelogic/PredicateLogic2_ExistsIn.casm rename to org.coreasm.engine/test-rsc/plugin-tests/predicatelogic/PredicateLogic2_ExistsIn.casm diff --git a/org.coreasm.engine/test-rsc/plugins/predicatelogic/PredicateLogic3_forallHold.casm b/org.coreasm.engine/test-rsc/plugin-tests/predicatelogic/PredicateLogic3_forallHold.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/predicatelogic/PredicateLogic3_forallHold.casm rename to org.coreasm.engine/test-rsc/plugin-tests/predicatelogic/PredicateLogic3_forallHold.casm diff --git a/org.coreasm.engine/test-rsc/plugins/predicatelogic/PredicateLogic4_not_notEqual.casm b/org.coreasm.engine/test-rsc/plugin-tests/predicatelogic/PredicateLogic4_not_notEqual.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/predicatelogic/PredicateLogic4_not_notEqual.casm rename to org.coreasm.engine/test-rsc/plugin-tests/predicatelogic/PredicateLogic4_not_notEqual.casm diff --git a/org.coreasm.engine/test-rsc/plugins/queue/Queue1.casm b/org.coreasm.engine/test-rsc/plugin-tests/queue/Queue1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/queue/Queue1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/queue/Queue1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/schedulingpolicies/Schedul1.casm b/org.coreasm.engine/test-rsc/plugin-tests/schedulingpolicies/Schedul1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/schedulingpolicies/Schedul1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/schedulingpolicies/Schedul1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/set/Set1_comprehension.casm b/org.coreasm.engine/test-rsc/plugin-tests/set/Set1_comprehension.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/set/Set1_comprehension.casm rename to org.coreasm.engine/test-rsc/plugin-tests/set/Set1_comprehension.casm diff --git a/org.coreasm.engine/test-rsc/plugins/set/Set2_adding_removing.casm b/org.coreasm.engine/test-rsc/plugin-tests/set/Set2_adding_removing.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/set/Set2_adding_removing.casm rename to org.coreasm.engine/test-rsc/plugin-tests/set/Set2_adding_removing.casm diff --git a/org.coreasm.engine/test-rsc/plugins/set/Set3_binary.casm b/org.coreasm.engine/test-rsc/plugin-tests/set/Set3_binary.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/set/Set3_binary.casm rename to org.coreasm.engine/test-rsc/plugin-tests/set/Set3_binary.casm diff --git a/org.coreasm.engine/test-rsc/plugins/signature/Signature1.casm b/org.coreasm.engine/test-rsc/plugin-tests/signature/Signature1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/signature/Signature1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/signature/Signature1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/signature/Signature2_derivedFunctions.casm b/org.coreasm.engine/test-rsc/plugin-tests/signature/Signature2_derivedFunctions.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/signature/Signature2_derivedFunctions.casm rename to org.coreasm.engine/test-rsc/plugin-tests/signature/Signature2_derivedFunctions.casm diff --git a/org.coreasm.engine/test-rsc/plugins/stack/Stack1.casm b/org.coreasm.engine/test-rsc/plugin-tests/stack/Stack1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/stack/Stack1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/stack/Stack1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/string/String1_toString.casm b/org.coreasm.engine/test-rsc/plugin-tests/string/String1_toString.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/string/String1_toString.casm rename to org.coreasm.engine/test-rsc/plugin-tests/string/String1_toString.casm diff --git a/org.coreasm.engine/test-rsc/plugins/string/String2_strlen.casm b/org.coreasm.engine/test-rsc/plugin-tests/string/String2_strlen.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/string/String2_strlen.casm rename to org.coreasm.engine/test-rsc/plugin-tests/string/String2_strlen.casm diff --git a/org.coreasm.engine/test-rsc/plugins/string/String3_matches.casm b/org.coreasm.engine/test-rsc/plugin-tests/string/String3_matches.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/string/String3_matches.casm rename to org.coreasm.engine/test-rsc/plugin-tests/string/String3_matches.casm diff --git a/org.coreasm.engine/test-rsc/plugins/time/Time1.casm b/org.coreasm.engine/test-rsc/plugin-tests/time/Time1.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/time/Time1.casm rename to org.coreasm.engine/test-rsc/plugin-tests/time/Time1.casm diff --git a/org.coreasm.engine/test-rsc/plugins/turboasm/TestAggregation.casm b/org.coreasm.engine/test-rsc/plugin-tests/turboasm/TestAggregation.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/turboasm/TestAggregation.casm rename to org.coreasm.engine/test-rsc/plugin-tests/turboasm/TestAggregation.casm diff --git a/org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM1_iterate.casm b/org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM1_iterate.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM1_iterate.casm rename to org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM1_iterate.casm diff --git a/org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM2_seqblock.casm b/org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM2_seqblock.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM2_seqblock.casm rename to org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM2_seqblock.casm diff --git a/org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM3_seq.casm b/org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM3_seq.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM3_seq.casm rename to org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM3_seq.casm diff --git a/org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM4_return.casm b/org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM4_return.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM4_return.casm rename to org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM4_return.casm diff --git a/org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM5_local.casm b/org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM5_local.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM5_local.casm rename to org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM5_local.casm diff --git a/org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM6_loc.casm b/org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM6_loc.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM6_loc.casm rename to org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM6_loc.casm diff --git a/org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM7_while.casm b/org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM7_while.casm similarity index 100% rename from org.coreasm.engine/test-rsc/plugins/turboasm/TurboASM7_while.casm rename to org.coreasm.engine/test-rsc/plugin-tests/turboasm/TurboASM7_while.casm From 419ddadcb237c22439bd9fba60ad98d89ae78563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Sat, 14 Jan 2017 12:16:47 +0100 Subject: [PATCH 04/11] remove unused deprecated waitForIdleOrError --- .../src/org/coreasm/engine/CoreASMEngine.java | 14 ++------------ .../src/org/coreasm/engine/Engine.java | 6 ------ 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/org.coreasm.engine/src/org/coreasm/engine/CoreASMEngine.java b/org.coreasm.engine/src/org/coreasm/engine/CoreASMEngine.java index 371662b8..222e5083 100644 --- a/org.coreasm.engine/src/org/coreasm/engine/CoreASMEngine.java +++ b/org.coreasm.engine/src/org/coreasm/engine/CoreASMEngine.java @@ -474,16 +474,6 @@ public void updateState(Set update) * @see #removeObserver(EngineObserver) */ public Collection getObservers(); - - /** - * Waits for the engine to go to the idle or error mode. This - * method should periodically put the current thread in - * a sleep mode to avoid taking CPU time. - * - * @deprecated Use {@link #waitWhileBusy()} instead. - */ - @Deprecated - public void waitForIdleOrError(); /** * Waits for the engine to go to the idle/error mode. This @@ -497,10 +487,10 @@ public void updateState(Set update) /** * Returns true if the engine is * busy performing some operation. This condition is - * used in {@link #waitForIdleOrError()} to wait + * used in {@link #waitWhileBusy()} to wait * until the engine finishes its work. * - * @see #waitForIdleOrError() + * @see #waitWhileBusy() */ public boolean isBusy(); diff --git a/org.coreasm.engine/src/org/coreasm/engine/Engine.java b/org.coreasm.engine/src/org/coreasm/engine/Engine.java index 88000d43..872894d9 100644 --- a/org.coreasm.engine/src/org/coreasm/engine/Engine.java +++ b/org.coreasm.engine/src/org/coreasm/engine/Engine.java @@ -731,12 +731,6 @@ public boolean hasErrorOccurred() { return (lastError != null) || (engineMode == EngineMode.emError) ; } - @Override - @Deprecated - public void waitForIdleOrError() { - waitWhileBusy(); - } - @Override public void waitWhileBusy() { while (isBusy()) From a9d68765f754a219d05dceae86ba9fbcd946994c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Sat, 14 Jan 2017 19:25:12 +0100 Subject: [PATCH 05/11] rework waitWhileBusy Replace Thread yielding with a blocking wait to improve cpu usage. As engineBusy and engineMode are not final it is dangerous to synchronize on them, therefore a ReentrantLock is used. For the blocking wait a Condition is used that is signaled each time when the result of isBusy might change. --- .../src/org/coreasm/engine/Engine.java | 266 +++++++++++------- 1 file changed, 160 insertions(+), 106 deletions(-) diff --git a/org.coreasm.engine/src/org/coreasm/engine/Engine.java b/org.coreasm.engine/src/org/coreasm/engine/Engine.java index 872894d9..26b69559 100644 --- a/org.coreasm.engine/src/org/coreasm/engine/Engine.java +++ b/org.coreasm.engine/src/org/coreasm/engine/Engine.java @@ -57,6 +57,9 @@ import org.coreasm.util.Tools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; /** * This class provides the actual implementation of a CoreASM engine. It @@ -105,6 +108,9 @@ public class Engine implements ControlAPI { /** A flag which is on while engine is busy */ private volatile boolean engineBusy = false; + private final Lock isBusyLock = new ReentrantLock(); + private final Condition isBusyChange = isBusyLock.newCondition(); + /** Cache of EngineMode events */ private final Map> modeEventCache; @@ -733,13 +739,29 @@ public boolean hasErrorOccurred() { @Override public void waitWhileBusy() { - while (isBusy()) - Thread.yield(); + while (isBusy()) { + isBusyLock.lock(); + try { + isBusyChange.await(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + finally { + isBusyLock.unlock(); + } + } } @Override - public synchronized boolean isBusy() { - return (engineMode != EngineMode.emTerminated) && (engineBusy || !commandQueue.isEmpty()); + public boolean isBusy() { + isBusyLock.lock(); + try { + return (engineMode != EngineMode.emTerminated) && (engineBusy || !commandQueue.isEmpty()); + } + finally { + isBusyLock.unlock(); + } } /** @@ -779,7 +801,15 @@ public EngineThread(String name) { @Override public void run() { try { - engineBusy = true; + isBusyLock.lock(); + try { + engineBusy = true; + isBusyChange.signalAll(); + } + finally { + isBusyLock.unlock(); + } + while (!terminating) { try { @@ -806,9 +836,14 @@ public void run() { // Synchronize this with isBusy to avoid isBusy from returning false while the engine actually is busy // What happens is that engineBusy is read as false right before it is set to true and commandQueue.isEmpty() // is checked right after removing the command from the queue. In that case isBusy returns false. - synchronized (Engine.this) { + isBusyLock.lock(); + try { processNextCommand(); engineBusy = (getEngineMode() != EngineMode.emIdle); + isBusyChange.signalAll(); + } + finally { + isBusyLock.unlock(); } break; @@ -978,26 +1013,33 @@ public void run() { */ case emError: - // Throw out all commands except a recovery command - while (!commandQueue.isEmpty()) { - EngineCommand cmd = commandQueue.remove(0); - if (cmd != null) { - if (cmd.type == EngineCommand.CmdType.ecTerminate) { - next(EngineMode.emTerminating); - lastError = null; - logger.debug("Engine terminated by user command."); - break; - } - else if (cmd.type == EngineCommand.CmdType.ecRecover) { - // Recover by going to the idle mode - next(EngineMode.emIdle); - lastError = null; - logger.debug("Engine recovered from error by user command."); - break; + isBusyLock.lock(); + try { + // Throw out all commands except a recovery command + while (!commandQueue.isEmpty()) { + EngineCommand cmd = commandQueue.remove(0); + if (cmd != null) { + if (cmd.type == EngineCommand.CmdType.ecTerminate) { + next(EngineMode.emTerminating); + lastError = null; + logger.debug("Engine terminated by user command."); + break; + } else if (cmd.type == EngineCommand.CmdType.ecRecover) { + // Recover by going to the idle mode + next(EngineMode.emIdle); + lastError = null; + logger.debug("Engine recovered from error by user command."); + break; + } } } + + engineBusy = false; + isBusyChange.signalAll(); + } + finally { + isBusyLock.unlock(); } - engineBusy = false; case emTerminated: break; default: @@ -1028,15 +1070,22 @@ else if (cmd.type == EngineCommand.CmdType.ecRecover) { for (Plugin p: pluginLoader.getPlugins()) p.terminate(); + } catch (Error e) { + e.printStackTrace(); + } + + isBusyLock.lock(); + try { // empty command queue commandQueue.clear(); - - } catch (Error e) { - e.printStackTrace(); + engineBusy = false; + isBusyChange.signalAll(); + } + finally { + isBusyLock.unlock(); } - engineBusy = false; System.gc(); } @@ -1047,13 +1096,18 @@ else if (cmd.type == EngineCommand.CmdType.ecRecover) { * new mode of the engine */ private void next(EngineMode newMode) throws EngineException { - engineBusy = true; - - EngineMode oldMode = null; + EngineMode oldMode; - synchronized (engineMode) { + isBusyLock.lock(); + try { oldMode = engineMode; engineMode = newMode; + + engineBusy = true; + isBusyChange.signalAll(); + } + finally { + isBusyLock.unlock(); } Map map = null; @@ -1096,92 +1150,92 @@ private void processNextCommand() throws EngineException { // a state that is right before changing its // state boolean shouldRemoveFirstCommand = false; - synchronized (engineMode) { - EngineCommand cmd = null; - int rrc = 0; - String tempMsg = null; + EngineCommand cmd = null; + int rrc = 0; + String tempMsg = null; - synchronized (this) { - rrc = remainingRunCount--; - } - if (rrc > 0) - cmd = new EngineCommand(EngineCommand.CmdType.ecStep, null); - else if (!commandQueue.isEmpty()) { - cmd = commandQueue.get(0); - shouldRemoveFirstCommand = true; - } + synchronized (this) { + rrc = remainingRunCount--; + } + if (rrc > 0) + cmd = new EngineCommand(EngineCommand.CmdType.ecStep, null); + else if (!commandQueue.isEmpty()) { + cmd = commandQueue.get(0); + shouldRemoveFirstCommand = true; + } + + if (cmd == null) + return; + else + lastCommand = cmd; + + switch (cmd.type) { + + case ecTerminate: + next(EngineMode.emTerminating); + break; + + case ecInit: + next(EngineMode.emInitKernel); + break; - if (cmd == null) - return; - else - lastCommand = cmd; - - switch (cmd.type) { - - case ecTerminate: - next(EngineMode.emTerminating); - break; - - case ecInit: - next(EngineMode.emInitKernel); - break; - - case ecLoadSpec: - tempMsg = "Loading specification file"; - case ecOnlyParseSpec: - tempMsg = "Parsing specification file"; - case ecOnlyParseHeader: - tempMsg = "Parsing the header of the specification file"; - ParseCommandData cmdData = null; - if (cmd.metaData instanceof ParseCommandData) - cmdData = (ParseCommandData)cmd.metaData; - else { - cmdData = new ParseCommandData(true, cmd.metaData); + case ecLoadSpec: + tempMsg = "Loading specification file"; + case ecOnlyParseSpec: + tempMsg = "Parsing specification file"; + case ecOnlyParseHeader: + tempMsg = "Parsing the header of the specification file"; + ParseCommandData cmdData = null; + if (cmd.metaData instanceof ParseCommandData) + cmdData = (ParseCommandData)cmd.metaData; + else { + cmdData = new ParseCommandData(true, cmd.metaData); + } + if (cmdData.specInfo instanceof String) { + try { + specification = new Specification(Engine.this, new File((String)cmdData.specInfo)); + parser.setSpecification(specification); + logger.debug("{}: {}", tempMsg, cmdData.specInfo); + next(EngineMode.emParsingHeader); + } catch (FileNotFoundException e) { + error("Specification file is not found (" + cmdData.specInfo + ")\n. Nothing is loaded."); + } catch (IOException e) { + error("Specification file cannot be read from (" + cmdData.specInfo + ")\n. Nothing is loaded."); } - if (cmdData.specInfo instanceof String) { + } else + if (cmdData.specInfo instanceof NamedStringReader) { + final NamedStringReader nsrData = (NamedStringReader)cmdData.specInfo; try { - specification = new Specification(Engine.this, new File((String)cmdData.specInfo)); + specification = new Specification(Engine.this, nsrData.reader, nsrData.fileName); parser.setSpecification(specification); - logger.debug("{}: {}", tempMsg, cmdData.specInfo); + logger.debug("{}.", tempMsg); next(EngineMode.emParsingHeader); - } catch (FileNotFoundException e) { - error("Specification file is not found (" + cmdData.specInfo + ")\n. Nothing is loaded."); } catch (IOException e) { - error("Specification file cannot be read from (" + cmdData.specInfo + ")\n. Nothing is loaded."); + error("Specification file cannot be read from (" + nsrData.fileName + ")\n. Nothing is loaded."); } } else - if (cmdData.specInfo instanceof NamedStringReader) { - final NamedStringReader nsrData = (NamedStringReader)cmdData.specInfo; - try { - specification = new Specification(Engine.this, nsrData.reader, nsrData.fileName); - parser.setSpecification(specification); - logger.debug("{}.", tempMsg); - next(EngineMode.emParsingHeader); - } catch (IOException e) { - error("Specification file cannot be read from (" + nsrData.fileName + ")\n. Nothing is loaded."); - } - } else - error("The specification passed to the engine is invalid."); - break; - - case ecStep: - next(EngineMode.emStartingStep); - break; - - case ecRun: - if (cmd.metaData instanceof Integer) { - int i = ((Integer) cmd.metaData).intValue(); - if (i > 0) - synchronized (this) { - remainingRunCount = i; - } - } - break; - case ecRecover: + error("The specification passed to the engine is invalid."); break; + + case ecStep: + next(EngineMode.emStartingStep); + break; + + case ecRun: + if (cmd.metaData instanceof Integer) { + int i = ((Integer) cmd.metaData).intValue(); + if (i > 0) + synchronized (this) { + remainingRunCount = i; + } } - if (shouldRemoveFirstCommand) - commandQueue.remove(0); + break; + case ecRecover: + break; + } + + if (shouldRemoveFirstCommand) { + commandQueue.remove(0); } } } From cf7010d5a4a55bc9a0e06cbbe84363f390add8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Sun, 15 Jan 2017 15:59:36 +0100 Subject: [PATCH 06/11] single threaded TestEngineDriver --- .../coreasm/engine/test/TestEngineDriver.java | 129 +++++++----------- 1 file changed, 47 insertions(+), 82 deletions(-) diff --git a/org.coreasm.engine/test/org/coreasm/engine/test/TestEngineDriver.java b/org.coreasm.engine/test/org/coreasm/engine/test/TestEngineDriver.java index 0d2c4305..85d8c5b6 100644 --- a/org.coreasm.engine/test/org/coreasm/engine/test/TestEngineDriver.java +++ b/org.coreasm.engine/test/org/coreasm/engine/test/TestEngineDriver.java @@ -1,6 +1,5 @@ package org.coreasm.engine.test; -import java.io.File; import java.io.PrintStream; import java.util.LinkedList; import java.util.List; @@ -24,9 +23,9 @@ import org.coreasm.util.Logger; import org.coreasm.util.Tools; -public class TestEngineDriver implements Runnable, EngineStepObserver, EngineErrorObserver { +public class TestEngineDriver implements EngineStepObserver, EngineErrorObserver { - protected static List runningInstances = null; + protected static List runningInstances = new LinkedList<>(); protected Engine engine; @@ -34,27 +33,22 @@ public enum TestEngineDriverStatus { stopped, running, paused }; - private TestEngineDriverStatus status = TestEngineDriverStatus.running; + private TestEngineDriverStatus status = TestEngineDriverStatus.paused; private boolean updateFailed; protected CoreASMError lastError; - private int stepsLimit; + private Exception exception = null; + private boolean stopOnEmptyUpdates; private boolean stopOnStableUpdates; private boolean stopOnEmptyActiveAgents; private boolean stopOnFailedUpdates; - - private volatile boolean shouldStop; - private volatile boolean shouldPause; private TestEngineDriver(String pluginFolders) { - if (runningInstances == null) - runningInstances = new LinkedList(); runningInstances.add(this); CoreASMGlobal.setRootFolder(Tools.getRootFolder()); engine = (Engine) org.coreasm.engine.CoreASMEngineFactory.createEngine(); engine.addObserver(this); - shouldStop = false; if (System.getProperty(EngineProperties.PLUGIN_FOLDERS_PROPERTY) != null) pluginFolders += EngineProperties.PLUGIN_FOLDERS_DELIM @@ -85,7 +79,6 @@ public void setDefaultConfig() stopOnStableUpdates = false; stopOnEmptyActiveAgents = true; stopOnFailedUpdates = false; - stepsLimit = -1; //means infinite steps } public Engine getEngine() { @@ -103,17 +96,7 @@ public static TestEngineDriver newLaunch(String abspathname, String pluginFolder return td; } - public void dolaunch(String abspathname) { - Thread t = new Thread(this); - - try { - t.setName("CoreASM run of " + - abspathname.substring(abspathname.lastIndexOf(File.separator))); - } - catch (Throwable e) { - t.setName("CoreASM run of " + abspathname); - } - + private void dolaunch(String abspathname) { if (engine.getEngineMode() == EngineMode.emError) { engine.recover(); engine.waitWhileBusy(); @@ -121,15 +104,13 @@ public void dolaunch(String abspathname) { engine.loadSpecification(abspathname); engine.waitWhileBusy(); - - t.start(); } - @Override - public void run() + private void executeStepsImpl(int stepsLimit) { int step = 0; - Exception exception = null; + + boolean doShutdown = false; Set updates, prevupdates = null; @@ -141,81 +122,65 @@ public void run() } while (engine.getEngineMode() == EngineMode.emIdle) { + status = TestEngineDriverStatus.running; + + //execute a step + engine.waitWhileBusy(); + engine.step(); + step++; + engine.waitWhileBusy(); - //set current mode - if (shouldStop) { - engine.waitWhileBusy(); + updates = engine.getUpdateSet(0); + if (terminated(updates, prevupdates)) { + doShutdown = true; break; } - else if (shouldPause) { - status = TestEngineDriverStatus.paused; - Thread.sleep(1); - } - else - { - status = TestEngineDriverStatus.running; - - //execute a step - engine.waitWhileBusy(); - engine.step(); - step++; - engine.waitWhileBusy(); - - updates = engine.getUpdateSet(0); - if (terminated(updates, prevupdates)) - break; - prevupdates = updates; - if (step == stepsLimit) { - step = 0; - shouldPause = true; - } + prevupdates = updates; + if (step == stepsLimit) { + break; } - } + if (engine.getEngineMode() != EngineMode.emIdle) handleError(); } catch (Exception e) { + doShutdown = true; exception = e; e.printStackTrace(); } finally { - if (runningInstances != null && runningInstances.contains(this)) { - runningInstances.remove(this); - this.engine.removeObserver(this); - - if (exception != null) - System.err.println("[!] Run is terminated with exception " + exception); - - this.engine.terminate(); - this.engine.hardInterrupt(); - - engine.waitWhileBusy(); - - status = TestEngineDriverStatus.stopped; + if (doShutdown) { + stop(); + } + else { + status = TestEngineDriverStatus.paused; } } } - public void resume() { - if (stepsLimit == 0) - stepsLimit = -1; - shouldPause = false; - while (getStatus() != TestEngineDriverStatus.running) - Thread.yield(); - } - public void stop() { - shouldStop = true; - while (getStatus() != TestEngineDriverStatus.stopped) - Thread.yield(); + if (runningInstances.contains(this)) { + runningInstances.remove(this); + this.engine.removeObserver(this); + + if (exception != null) + System.err.println("[!] Run is terminated with exception " + exception); + + this.engine.terminate(); + this.engine.hardInterrupt(); + + engine.waitWhileBusy(); + + status = TestEngineDriverStatus.stopped; + } } public void executeSteps(int numberOfSteps) { - stepsLimit = numberOfSteps; - resume(); - while (getStatus() == TestEngineDriverStatus.running) - Thread.yield(); + if (numberOfSteps == 0) + numberOfSteps = -1; //means infinite steps + + executeStepsImpl(numberOfSteps); } From 79ebc066bb2b34f05ea471cc627c7387add93d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Tue, 11 Apr 2017 09:24:58 +0200 Subject: [PATCH 07/11] add NanoTimeFunctionElement - provides System.nanoTime to measure elapsed time --- .../plugins/time/NanoTimeFunctionElement.java | 50 +++++++++++++++++++ .../engine/plugins/time/TimePlugin.java | 3 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 org.coreasm.engine/src/org/coreasm/engine/plugins/time/NanoTimeFunctionElement.java diff --git a/org.coreasm.engine/src/org/coreasm/engine/plugins/time/NanoTimeFunctionElement.java b/org.coreasm.engine/src/org/coreasm/engine/plugins/time/NanoTimeFunctionElement.java new file mode 100644 index 00000000..f90298e1 --- /dev/null +++ b/org.coreasm.engine/src/org/coreasm/engine/plugins/time/NanoTimeFunctionElement.java @@ -0,0 +1,50 @@ +/* + * NanoTimeFunctionElement.java 1.0 + * + * Copyright (C) 2006 Roozbeh Farahbod + * + * Last modified by $Author: rfarahbod $ on $Date: 2011-03-29 02:05:21 +0200 (Di, 29 Mrz 2011) $. + * + * Licensed under the Academic Free License version 3.0 + * http://www.opensource.org/licenses/afl-3.0.php + * http://www.coreasm.org/afl-3.0.php + * + */ + +package org.coreasm.engine.plugins.time; + +import org.coreasm.engine.absstorage.Element; +import org.coreasm.engine.absstorage.FunctionElement; +import org.coreasm.engine.plugins.number.NumberElement; + +import java.util.List; + +/** + * Implements 'nanoTime' as a monitored function that returns the current value of the running Java Virtual Machine's + * high-resolution time source, in nanoseconds. + * + * @author André Wolski + * + */ +public class NanoTimeFunctionElement extends FunctionElement { + + /** Name of this function */ + public static final String NANOTIME_FUNC_NAME = "nanoTime"; + + public NanoTimeFunctionElement() { + super(); + setFClass(FunctionClass.fcMonitored); + } + + /* (non-Javadoc) + * @see org.coreasm.engine.absstorage.FunctionElement#getValue(java.util.List) + */ + @Override + public Element getValue(List args) { + if (args.size() > 0) + return Element.UNDEF; + else + return NumberElement.getInstance(System.nanoTime()); + } + +} diff --git a/org.coreasm.engine/src/org/coreasm/engine/plugins/time/TimePlugin.java b/org.coreasm.engine/src/org/coreasm/engine/plugins/time/TimePlugin.java index 81c35c4b..c95fcc21 100644 --- a/org.coreasm.engine/src/org/coreasm/engine/plugins/time/TimePlugin.java +++ b/org.coreasm.engine/src/org/coreasm/engine/plugins/time/TimePlugin.java @@ -37,7 +37,7 @@ */ public class TimePlugin extends Plugin implements VocabularyExtender { - public static final VersionInfo VERSION_INFO = new VersionInfo(0, 2, 0, ""); + public static final VersionInfo VERSION_INFO = new VersionInfo(0, 3, 0, ""); private final Set dependencyList; @@ -75,6 +75,7 @@ public Map getFunctions() { if (functions == null) { functions = new HashMap(); functions.put(NowFunctionElement.NOW_FUNC_NAME, new NowFunctionElement()); + functions.put(NanoTimeFunctionElement.NANOTIME_FUNC_NAME, new NanoTimeFunctionElement()); functions.put(StepCountFunctionElement.FUNC_NAME, new StepCountFunctionElement(capi)); } return functions; From 6be3f2abba910dcc7778700aa0896dbfd273869d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Mon, 26 Mar 2018 11:23:22 +0200 Subject: [PATCH 08/11] Engine: replace custom synchronized CommandQueue with LinkedBlockingQueue I couldn't measure a perfomance difference, but this design looks better than something custom --- .../src/org/coreasm/engine/Engine.java | 128 ++++-------------- 1 file changed, 29 insertions(+), 99 deletions(-) diff --git a/org.coreasm.engine/src/org/coreasm/engine/Engine.java b/org.coreasm.engine/src/org/coreasm/engine/Engine.java index 26b69559..e11a377c 100644 --- a/org.coreasm.engine/src/org/coreasm/engine/Engine.java +++ b/org.coreasm.engine/src/org/coreasm/engine/Engine.java @@ -15,17 +15,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.Reader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Properties; -import java.util.Set; import org.coreasm.engine.absstorage.AbstractStorage; import org.coreasm.engine.absstorage.Element; @@ -57,6 +48,8 @@ import org.coreasm.util.Tools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -118,8 +111,7 @@ public class Engine implements ControlAPI { private Map> serviceRegistry; /** User command queue */ -// private Queue commandQueue; - private final CommandQueue commandQueue; + private final LinkedBlockingQueue commandQueue; /** Properties of the engine */ private EngineProperties properties; @@ -168,7 +160,7 @@ protected Engine(java.util.Properties properties) { engineThread = new EngineThread(name); // initializing objects - commandQueue = new CommandQueue(); + commandQueue = new LinkedBlockingQueue<>(); //allPlugins = new HashMap(); //loadedPlugins = new PluginDB(); pluginLoader = new PluginManager(this); @@ -220,8 +212,8 @@ private void resetEngine() { @Override public void initialize() { - commandQueue - .add(new EngineCommand(EngineCommand.CmdType.ecInit, null)); + commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecInit, + null)); } @Override @@ -460,8 +452,8 @@ public void softInterrupt() { @Override public void step() { - commandQueue - .add(new EngineCommand(EngineCommand.CmdType.ecStep, null)); + commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecStep, + null)); } @Override @@ -1016,21 +1008,19 @@ public void run() { isBusyLock.lock(); try { // Throw out all commands except a recovery command - while (!commandQueue.isEmpty()) { - EngineCommand cmd = commandQueue.remove(0); - if (cmd != null) { - if (cmd.type == EngineCommand.CmdType.ecTerminate) { - next(EngineMode.emTerminating); - lastError = null; - logger.debug("Engine terminated by user command."); - break; - } else if (cmd.type == EngineCommand.CmdType.ecRecover) { - // Recover by going to the idle mode - next(EngineMode.emIdle); - lastError = null; - logger.debug("Engine recovered from error by user command."); - break; - } + EngineCommand cmd; + while ((cmd = commandQueue.poll()) != null) { + if (cmd.type == EngineCommand.CmdType.ecTerminate) { + next(EngineMode.emTerminating); + lastError = null; + logger.debug("Engine terminated by user command."); + break; + } else if (cmd.type == EngineCommand.CmdType.ecRecover) { + // Recover by going to the idle mode + next(EngineMode.emIdle); + lastError = null; + logger.debug("Engine recovered from error by user command."); + break; } } @@ -1150,7 +1140,7 @@ private void processNextCommand() throws EngineException { // a state that is right before changing its // state boolean shouldRemoveFirstCommand = false; - EngineCommand cmd = null; + EngineCommand cmd; int rrc = 0; String tempMsg = null; @@ -1159,9 +1149,11 @@ private void processNextCommand() throws EngineException { } if (rrc > 0) cmd = new EngineCommand(EngineCommand.CmdType.ecStep, null); - else if (!commandQueue.isEmpty()) { - cmd = commandQueue.get(0); - shouldRemoveFirstCommand = true; + else { + cmd = commandQueue.peek(); + if (cmd != null) { + shouldRemoveFirstCommand = true; + } } if (cmd == null) @@ -1235,7 +1227,7 @@ else if (!commandQueue.isEmpty()) { } if (shouldRemoveFirstCommand) { - commandQueue.remove(0); + commandQueue.poll(); } } } @@ -1394,68 +1386,6 @@ public EngineCommand(CmdType type, Object metaData) { } -/** - * An array list with synchronized methods. - * - * @author Roozbeh Farahbod - * - */ -class CommandQueue extends ArrayList { - - private static final long serialVersionUID = 1L; - - @Override - public synchronized boolean add(EngineCommand e) { - return super.add(e); - } - - @Override - public synchronized void add(int index, EngineCommand element) { - super.add(index, element); - } - - @Override - public synchronized void clear() { - super.clear(); - } - - @Override - public synchronized boolean contains(Object o) { - return super.contains(o); - } - - @Override - public synchronized EngineCommand get(int index) { - return super.get(index); - } - - @Override - public synchronized boolean isEmpty() { - return super.isEmpty(); - } - - @Override - public synchronized EngineCommand remove(int index) { - return super.remove(index); - } - - @Override - public synchronized boolean remove(Object o) { - return super.remove(o); - } - - @Override - public synchronized int size() { - return super.size(); - } - - @Override - public synchronized String toString() { - return super.toString(); - } - -} - /* * Meta-data of a parseHeader command */ From 037424392d06854cc9391bf999f30cf72419b0da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Mon, 26 Mar 2018 11:43:28 +0200 Subject: [PATCH 09/11] Engine: use AtomicInteger instead of synchronized (this) Again: no measureable performance difference, but nicer design --- .../src/org/coreasm/engine/Engine.java | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/org.coreasm.engine/src/org/coreasm/engine/Engine.java b/org.coreasm.engine/src/org/coreasm/engine/Engine.java index e11a377c..5b49d091 100644 --- a/org.coreasm.engine/src/org/coreasm/engine/Engine.java +++ b/org.coreasm.engine/src/org/coreasm/engine/Engine.java @@ -50,6 +50,7 @@ import org.slf4j.LoggerFactory; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -123,7 +124,7 @@ public class Engine implements ControlAPI { private final LinkedList interpreterListeners; /** Remaining steps of the current run */ - private int remainingRunCount = 0; + private AtomicInteger remainingRunCount = new AtomicInteger(0); /** Last error occurred in the engine */ private volatile CoreASMError lastError = null; @@ -445,9 +446,7 @@ public void hardInterrupt() { @Override public void softInterrupt() { - synchronized (engineThread) { - remainingRunCount = 0; - } + remainingRunCount.set(0); } @Override @@ -1141,12 +1140,9 @@ private void processNextCommand() throws EngineException { // state boolean shouldRemoveFirstCommand = false; EngineCommand cmd; - int rrc = 0; + int rrc = remainingRunCount.getAndDecrement(); String tempMsg = null; - synchronized (this) { - rrc = remainingRunCount--; - } if (rrc > 0) cmd = new EngineCommand(EngineCommand.CmdType.ecStep, null); else { @@ -1216,10 +1212,9 @@ private void processNextCommand() throws EngineException { case ecRun: if (cmd.metaData instanceof Integer) { int i = ((Integer) cmd.metaData).intValue(); - if (i > 0) - synchronized (this) { - remainingRunCount = i; - } + if (i > 0) { + remainingRunCount.set(i); + } } break; case ecRecover: From e7ea15f4e80c47622473316384c63fe0692ba293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Wed, 28 Mar 2018 11:10:13 +0200 Subject: [PATCH 10/11] Engine: fix typo --- org.coreasm.engine/src/org/coreasm/engine/Engine.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.coreasm.engine/src/org/coreasm/engine/Engine.java b/org.coreasm.engine/src/org/coreasm/engine/Engine.java index 5b49d091..51b7d8ee 100644 --- a/org.coreasm.engine/src/org/coreasm/engine/Engine.java +++ b/org.coreasm.engine/src/org/coreasm/engine/Engine.java @@ -1037,13 +1037,13 @@ public void run() { } } catch (CoreASMError ce) { error(ce); - logger.error( "Error occured: {}", ce.showError()); + logger.error( "Error occurred: {}", ce.showError()); } catch (Throwable e) { if (e instanceof ParserException) error(new CoreASMError((ParserException)e)); else error(e); - logger.error("Exception occured. ", e); + logger.error("Exception occurred. ", e); // StackTraceElement[] trace = e.getStackTrace(); // for (StackTraceElement ste: trace) // logger.error( ste.toString()); From c750929c2365026d7f7954a1010d5c78388cabba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Wolski?= Date: Fri, 13 Apr 2018 21:26:03 +0200 Subject: [PATCH 11/11] Engine: remove idle yield; use commandQueue.take This allows the Engine to be idle for a longer period of time without constantly yielding. - the updates of `engineBusy` and locks of `isBusyLock` should now be easier to follow -* i.e. idle == being in a blocking wait for the next command - `isBusyChanged` has been changed to `isNotBusy` --- .../src/org/coreasm/engine/Engine.java | 155 ++++++++---------- 1 file changed, 65 insertions(+), 90 deletions(-) diff --git a/org.coreasm.engine/src/org/coreasm/engine/Engine.java b/org.coreasm.engine/src/org/coreasm/engine/Engine.java index 51b7d8ee..3b517e05 100644 --- a/org.coreasm.engine/src/org/coreasm/engine/Engine.java +++ b/org.coreasm.engine/src/org/coreasm/engine/Engine.java @@ -100,10 +100,10 @@ public class Engine implements ControlAPI { private volatile EngineMode engineMode = EngineMode.emIdle; /** A flag which is on while engine is busy */ - private volatile boolean engineBusy = false; + private volatile boolean engineBusy = true; private final Lock isBusyLock = new ReentrantLock(); - private final Condition isBusyChange = isBusyLock.newCondition(); + private final Condition isNotBusy = isBusyLock.newCondition(); /** Cache of EngineMode events */ private final Map> modeEventCache; @@ -211,28 +211,42 @@ private void resetEngine() { } } + private void addCommand(EngineCommand command) { + isBusyLock.lock(); + try { + // set engine busy here, as the EngineThread could set it only after removing this command, + // which would leave a short time in which `isBusy` would erroneously report `false`, + // as the queue might be empty before the EngineThread would've set engineBusy = true; + engineBusy = true; + commandQueue.add(command); + } + finally { + isBusyLock.unlock(); + } + } + @Override public void initialize() { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecInit, + addCommand(new EngineCommand(EngineCommand.CmdType.ecInit, null)); } @Override public void terminate() { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecTerminate, + addCommand(new EngineCommand(EngineCommand.CmdType.ecTerminate, null)); } @Override public void recover() { if (getEngineMode() == EngineMode.emError) - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecRecover, + addCommand(new EngineCommand(EngineCommand.CmdType.ecRecover, null)); } @Override public void loadSpecification(String specFileName) { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecLoadSpec, + addCommand(new EngineCommand(EngineCommand.CmdType.ecLoadSpec, specFileName)); } @@ -243,13 +257,13 @@ public void loadSpecification(Reader src) { @Override public void loadSpecification(String name, Reader src) { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecLoadSpec, + addCommand(new EngineCommand(EngineCommand.CmdType.ecLoadSpec, new NamedStringReader(name, src))); } @Override public void parseSpecification(String specFileName) { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecOnlyParseSpec, + addCommand(new EngineCommand(EngineCommand.CmdType.ecOnlyParseSpec, specFileName)); } @@ -260,7 +274,7 @@ public void parseSpecification(Reader src) { @Override public void parseSpecification(String name, Reader src) { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecOnlyParseSpec, + addCommand(new EngineCommand(EngineCommand.CmdType.ecOnlyParseSpec, new NamedStringReader(name, src))); } @@ -284,7 +298,7 @@ public void parseSpecificationHeader(String name, Reader src) { @Override public void parseSpecificationHeader(String specFileName, boolean loadPlugins) { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecOnlyParseHeader, + addCommand(new EngineCommand(EngineCommand.CmdType.ecOnlyParseHeader, new ParseCommandData(loadPlugins, specFileName))); } @@ -295,7 +309,7 @@ public void parseSpecificationHeader(Reader src, boolean loadPlugins) { @Override public void parseSpecificationHeader(String name, Reader src, boolean loadPlugins) { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecOnlyParseHeader, + addCommand(new EngineCommand(EngineCommand.CmdType.ecOnlyParseHeader, new ParseCommandData(loadPlugins, new NamedStringReader(name, src)))); } @@ -451,13 +465,13 @@ public void softInterrupt() { @Override public void step() { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecStep, + addCommand(new EngineCommand(EngineCommand.CmdType.ecStep, null)); } @Override public void run(int i) { - commandQueue.add(new EngineCommand(EngineCommand.CmdType.ecRun, + addCommand(new EngineCommand(EngineCommand.CmdType.ecRun, new Integer(i))); } @@ -730,31 +744,25 @@ public boolean hasErrorOccurred() { @Override public void waitWhileBusy() { - while (isBusy()) { - isBusyLock.lock(); - try { - isBusyChange.await(); - } - catch (InterruptedException e) { - e.printStackTrace(); - } - finally { - isBusyLock.unlock(); - } - } - } - - @Override - public boolean isBusy() { isBusyLock.lock(); try { - return (engineMode != EngineMode.emTerminated) && (engineBusy || !commandQueue.isEmpty()); + if (isBusy()) { + isNotBusy.await(); + } + } + catch (InterruptedException e) { + e.printStackTrace(); } finally { isBusyLock.unlock(); } } + @Override + public boolean isBusy() { + return (engineMode != EngineMode.emTerminated) && (engineBusy || !commandQueue.isEmpty()); + } + /** * This is the execution thread of a CoreASM engine. This class implements * Runnable. @@ -792,17 +800,9 @@ public EngineThread(String name) { @Override public void run() { try { - isBusyLock.lock(); - try { - engineBusy = true; - isBusyChange.signalAll(); - } - finally { - isBusyLock.unlock(); - } - - while (!terminating) { + assert engineBusy; + try { EngineMode engineMode = getEngineMode(); @@ -813,29 +813,12 @@ public void run() { next(EngineMode.emError); } - // if engine mode is idle and there is no user command, - // sleep for a short time - if ((engineMode == EngineMode.emIdle && commandQueue.isEmpty()) - || engineMode == EngineMode.emError) - Thread.yield(); - engineMode = getEngineMode(); switch (engineMode) { case emIdle: - // Synchronize this with isBusy to avoid isBusy from returning false while the engine actually is busy - // What happens is that engineBusy is read as false right before it is set to true and commandQueue.isEmpty() - // is checked right after removing the command from the queue. In that case isBusy returns false. - isBusyLock.lock(); - try { - processNextCommand(); - engineBusy = (getEngineMode() != EngineMode.emIdle); - isBusyChange.signalAll(); - } - finally { - isBusyLock.unlock(); - } + processNextCommand(); break; case emInitKernel: @@ -1024,7 +1007,7 @@ public void run() { } engineBusy = false; - isBusyChange.signalAll(); + isNotBusy.signalAll(); } finally { isBusyLock.unlock(); @@ -1069,7 +1052,7 @@ public void run() { commandQueue.clear(); engineBusy = false; - isBusyChange.signalAll(); + isNotBusy.signalAll(); } finally { isBusyLock.unlock(); @@ -1085,19 +1068,8 @@ public void run() { * new mode of the engine */ private void next(EngineMode newMode) throws EngineException { - EngineMode oldMode; - - isBusyLock.lock(); - try { - oldMode = engineMode; - engineMode = newMode; - - engineBusy = true; - isBusyChange.signalAll(); - } - finally { - isBusyLock.unlock(); - } + final EngineMode oldMode = engineMode; + engineMode = newMode; Map map = null; EngineModeEvent event = null; @@ -1128,17 +1100,13 @@ private void next(EngineMode newMode) throws EngineException { /** * If more steps needs to be performed, fakes a new step command; - * otherwise it fetches another command from the command queue and + * otherwise it blocks for the next command from the command queue and * switches the engine mode based on that command. It uses * next(EngineMode) to change the engine mode. * * @see #next(EngineMode) */ - private void processNextCommand() throws EngineException { - // This is here to avoid leaving the engine in - // a state that is right before changing its - // state - boolean shouldRemoveFirstCommand = false; + private void processNextCommand() throws EngineException, InterruptedException { EngineCommand cmd; int rrc = remainingRunCount.getAndDecrement(); String tempMsg = null; @@ -1146,16 +1114,27 @@ private void processNextCommand() throws EngineException { if (rrc > 0) cmd = new EngineCommand(EngineCommand.CmdType.ecStep, null); else { - cmd = commandQueue.peek(); - if (cmd != null) { - shouldRemoveFirstCommand = true; + isBusyLock.lock(); + try { + if (commandQueue.isEmpty()) { + // we will block until something is put into the commandQueue, + // which means we are not busy. Before something is put into the queue + // engineBusy must be set to `true` + engineBusy = false; + isNotBusy.signalAll(); + } } + finally { + isBusyLock.unlock(); + } + + // blocking wait for the next command + cmd = commandQueue.take(); } - if (cmd == null) - return; - else - lastCommand = cmd; + assert engineBusy; + + lastCommand = cmd; switch (cmd.type) { @@ -1220,10 +1199,6 @@ private void processNextCommand() throws EngineException { case ecRecover: break; } - - if (shouldRemoveFirstCommand) { - commandQueue.poll(); - } } }