From ef9c4b5713d7b0329000df53e6516cca23b81bd9 Mon Sep 17 00:00:00 2001 From: Peter Feiler Date: Fri, 27 Jul 2018 15:15:04 -0400 Subject: [PATCH 1/2] Now checks and give warning if partition is not in processor 653 schedule. --- .../flows/FlowLatencyAnalysisSwitch.java | 60 ++++++++++++++----- .../osate/analysis/flows/FlowLatencyUtil.java | 33 +++++----- 2 files changed, 62 insertions(+), 31 deletions(-) diff --git a/analyses/org.osate.analysis.flows/src/org/osate/analysis/flows/FlowLatencyAnalysisSwitch.java b/analyses/org.osate.analysis.flows/src/org/osate/analysis/flows/FlowLatencyAnalysisSwitch.java index a36ec7e44cb..d7c164f9efa 100644 --- a/analyses/org.osate.analysis.flows/src/org/osate/analysis/flows/FlowLatencyAnalysisSwitch.java +++ b/analyses/org.osate.analysis.flows/src/org/osate/analysis/flows/FlowLatencyAnalysisSwitch.java @@ -223,10 +223,21 @@ public void mapComponentInstance(final EndToEndFlowInstance etef, final FlowElem double partitionLatency = FlowLatencyUtil.getPartitionPeriod(firstPartition); List schedule = FlowLatencyUtil.getModuleSchedule(firstPartition); double partitionDuration = FlowLatencyUtil.getPartitionDuration(firstPartition, schedule); + LatencyContributorComponent partitionLatencyContributor = new LatencyContributorComponent( + firstPartition, report.isMajorFrameDelay()); + if (!FlowLatencyUtil.isInSchedule(firstPartition, schedule)) { + partitionLatencyContributor + .reportWarning("Partition not found in ARINC653 schedule of processor " + + FlowLatencyUtil.getModule(firstPartition).getName()); + } if (partitionDuration > 0) { - LatencyContributorComponent partitionLatencyContributor = new LatencyContributorComponent( - firstPartition, report.isMajorFrameDelay()); - partitionLatencyContributor.setSamplingPeriod(partitionLatency); + if (partitionLatency == 0) { + partitionLatencyContributor.setSamplingPeriod(partitionDuration); + partitionLatencyContributor + .reportInfo("No partition period/rate. Using partition duration"); + } else { + partitionLatencyContributor.setSamplingPeriod(partitionLatency); + } double frameOffset = FlowLatencyUtil.getPartitionFrameOffset(firstPartition, schedule); partitionLatencyContributor.setPartitionOffset(frameOffset); partitionLatencyContributor.setPartitionDuration(partitionDuration); @@ -234,8 +245,9 @@ public void mapComponentInstance(final EndToEndFlowInstance etef, final FlowElem partitionLatencyContributor.setBestCaseMethod(LatencyContributorMethod.PARTITION_SCHEDULE); entry.addContributor(partitionLatencyContributor); } else { - LatencyContributorComponent partitionLatencyContributor = new LatencyContributorComponent( - firstPartition, report.isMajorFrameDelay()); + if (partitionLatency == 0) { + partitionLatencyContributor.reportInfo("No partition period/rate. Using zero"); + } partitionLatencyContributor.setSamplingPeriod(partitionLatency); partitionLatencyContributor.setWorstCaseMethod(LatencyContributorMethod.PARTITION_FRAME); partitionLatencyContributor.setBestCaseMethod(LatencyContributorMethod.PARTITION_FRAME); @@ -256,9 +268,13 @@ public void mapComponentInstance(final EndToEndFlowInstance etef, final FlowElem double partitionLatency = FlowLatencyUtil.getPartitionPeriod(firstPartition); List schedule = FlowLatencyUtil.getModuleSchedule(firstPartition); double partitionDuration = FlowLatencyUtil.getPartitionDuration(firstPartition, schedule); + LatencyContributorComponent platencyContributor = new LatencyContributorComponent(firstPartition, + report.isMajorFrameDelay()); + if (!FlowLatencyUtil.isInSchedule(firstPartition, schedule)) { + platencyContributor.reportWarning("Partition not found in ARINC653 schedule of processor " + + FlowLatencyUtil.getModule(firstPartition).getName()); + } if (partitionDuration > 0) { - LatencyContributorComponent platencyContributor = new LatencyContributorComponent(firstPartition, - report.isMajorFrameDelay()); platencyContributor.setSamplingPeriod(partitionLatency); double frameOffset = FlowLatencyUtil.getPartitionFrameOffset(firstPartition, schedule); platencyContributor.setPartitionOffset(frameOffset); @@ -267,8 +283,6 @@ public void mapComponentInstance(final EndToEndFlowInstance etef, final FlowElem platencyContributor.setBestCaseMethod(LatencyContributorMethod.PARTITION_SCHEDULE); entry.addContributor(platencyContributor); } else { - LatencyContributorComponent platencyContributor = new LatencyContributorComponent(firstPartition, - report.isMajorFrameDelay()); platencyContributor.setSamplingPeriod(partitionLatency); platencyContributor.setWorstCaseMethod(LatencyContributorMethod.PARTITION_FRAME); platencyContributor.setBestCaseMethod(LatencyContributorMethod.PARTITION_FRAME); @@ -416,9 +430,18 @@ public void mapConnectionInstance(final EndToEndFlowInstance etef, final FlowEle if (partitionDuration > 0) { LatencyContributor ioLatencyContributor = new LatencyContributorComponent(srcPartition, report.isMajorFrameDelay()); + if (!FlowLatencyUtil.isInSchedule(srcPartition, schedule)) { + ioLatencyContributor.reportWarning("Partition not found in ARINC653 schedule of processor " + + FlowLatencyUtil.getModule(srcPartition).getName()); + } ioLatencyContributor.setWorstCaseMethod(LatencyContributorMethod.PARTITION_OUTPUT); ioLatencyContributor.setBestCaseMethod(LatencyContributorMethod.PARTITION_OUTPUT); - ioLatencyContributor.setSamplingPeriod(partitionLatency); + if (partitionLatency == 0) { + ioLatencyContributor.setSamplingPeriod(partitionDuration); + ioLatencyContributor.reportInfo("No partition period/rate. Using partition duration"); + } else { + ioLatencyContributor.setSamplingPeriod(partitionLatency); + } double frameOffset = FlowLatencyUtil.getPartitionFrameOffset(srcPartition, schedule); ioLatencyContributor.setPartitionOffset(frameOffset); ioLatencyContributor.setPartitionDuration(partitionDuration); @@ -496,19 +519,26 @@ public void mapConnectionInstance(final EndToEndFlowInstance etef, final FlowEle double partitionLatency = FlowLatencyUtil.getPartitionPeriod(dstPartition); List schedule = FlowLatencyUtil.getModuleSchedule(dstPartition); double partitionDuration = FlowLatencyUtil.getPartitionDuration(dstPartition, schedule); + LatencyContributorComponent platencyContributor = new LatencyContributorComponent(dstPartition, + report.isMajorFrameDelay()); + if (!FlowLatencyUtil.isInSchedule(dstPartition, schedule)) { + platencyContributor.reportWarning("Partition not found in ARINC653 schedule of processor " + + FlowLatencyUtil.getModule(dstPartition).getName()); + } if (partitionDuration > 0) { - LatencyContributorComponent platencyContributor = new LatencyContributorComponent(dstPartition, - report.isMajorFrameDelay()); - platencyContributor.setSamplingPeriod(partitionLatency); double frameOffset = FlowLatencyUtil.getPartitionFrameOffset(dstPartition, schedule); platencyContributor.setPartitionOffset(frameOffset); + if (partitionLatency == 0) { + platencyContributor.setSamplingPeriod(partitionDuration); + platencyContributor.reportInfo("No partition period. Using partition duration"); + } else { + platencyContributor.setSamplingPeriod(partitionLatency); + } platencyContributor.setPartitionDuration(partitionDuration); platencyContributor.setWorstCaseMethod(LatencyContributorMethod.PARTITION_SCHEDULE); platencyContributor.setBestCaseMethod(LatencyContributorMethod.PARTITION_SCHEDULE); entry.addContributor(platencyContributor); } else { - LatencyContributorComponent platencyContributor = new LatencyContributorComponent(dstPartition, - report.isMajorFrameDelay()); platencyContributor.setSamplingPeriod(partitionLatency); platencyContributor.setWorstCaseMethod(LatencyContributorMethod.PARTITION_FRAME); platencyContributor.setBestCaseMethod(LatencyContributorMethod.PARTITION_FRAME); diff --git a/analyses/org.osate.analysis.flows/src/org/osate/analysis/flows/FlowLatencyUtil.java b/analyses/org.osate.analysis.flows/src/org/osate/analysis/flows/FlowLatencyUtil.java index ff197d12851..c484fbd1730 100644 --- a/analyses/org.osate.analysis.flows/src/org/osate/analysis/flows/FlowLatencyUtil.java +++ b/analyses/org.osate.analysis.flows/src/org/osate/analysis/flows/FlowLatencyUtil.java @@ -245,25 +245,14 @@ public static ConnectionInstance getPreviousConnection(final EndToEndFlowInstanc /** - * find virtual processor with a period or ARINC653 partition (bound to processor with ARINC653 major frame) + * Return first virtual processor. Usually processes are only assigned to one VP. * @param componentInstance system, process, thread or other entity bound to a processor and running inside a partition. * @return partition */ public static ComponentInstance getPartition(ComponentInstance componentInstance) { Collection vprocessors = InstanceModelUtil.getBoundVirtualProcessors(componentInstance); for (ComponentInstance vproc : vprocessors) { - Collection procs = InstanceModelUtil.getBoundPhysicalProcessors(vproc); - for (ComponentInstance proc : procs) { - if (GetProperties.hasAssignedPropertyValue(proc, "ARINC653::Module_Major_Frame")) { - return vproc; - } - } - if (GetProperties.hasAssignedPropertyValue(vproc, "Period")) { - return vproc; - } - if (GetProperties.hasAssignedPropertyValue(vproc, "ARINC653::Module_Major_Frame")) { - return vproc; - } + return vproc; } return null; } @@ -343,12 +332,12 @@ public static ComponentInstance getModule(ComponentInstance partition) { * return the offset of the partition start time relative to the major frame * utilizes the window schedule of the module for the partition * @param partition This can be a virtual processor representing a partition or a component instance tagged with SEI properties - * @return offset or -1 if no schedule, no virtual processor as ARINC653 partition, or no processor. + * @return offset, no virtual processor as ARINC653 partition, or no processor. */ public static double getPartitionFrameOffset(ComponentInstance partition, List schedule) { double res = 0.0; if ((schedule == null) || (schedule.size() == 0)) { - return -1; + return res; } for (ARINC653ScheduleWindow window : schedule) { if (window.getPartition() == partition) { @@ -357,7 +346,19 @@ public static double getPartitionFrameOffset(ComponentInstance partition, List schedule) { + if (schedule == null) { + return true; + } + for (ARINC653ScheduleWindow window : schedule) { + if (window.getPartition() == partition) { + return true; + } + } + return false; } /** From 74f7b0a6c73c4f37dbfbd112c5d2170b2842a402 Mon Sep 17 00:00:00 2001 From: Peter Feiler Date: Mon, 30 Jul 2018 21:33:29 -0400 Subject: [PATCH 2/2] Added test that checks on warning if partition is not in schedule --- .../flows/tests/ARINC653ScheduleTest.xtend | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 analyses/org.osate.analysis.flows.tests/src/org/osate/analysis/flows/tests/ARINC653ScheduleTest.xtend diff --git a/analyses/org.osate.analysis.flows.tests/src/org/osate/analysis/flows/tests/ARINC653ScheduleTest.xtend b/analyses/org.osate.analysis.flows.tests/src/org/osate/analysis/flows/tests/ARINC653ScheduleTest.xtend new file mode 100644 index 00000000000..aeb172e7b4f --- /dev/null +++ b/analyses/org.osate.analysis.flows.tests/src/org/osate/analysis/flows/tests/ARINC653ScheduleTest.xtend @@ -0,0 +1,99 @@ +package org.osate.analysis.flows.tests + +import com.google.inject.Inject +import com.itemis.xtext.testing.XtextTest +import org.eclipse.core.runtime.NullProgressMonitor +import org.eclipse.xtext.testing.InjectWith +import org.eclipse.xtext.testing.XtextRunner +import org.junit.Test +import org.junit.runner.RunWith +import org.osate.aadl2.AadlPackage +import org.osate.aadl2.SystemImplementation +import org.osate.aadl2.instantiation.InstantiateModel +import org.osate.analysis.flows.FlowLatencyAnalysisSwitch +import org.osate.result.RealValue +import org.osate.testsupport.Aadl2InjectorProvider +import org.osate.testsupport.TestHelper + +import static org.junit.Assert.* + +import static extension org.junit.Assert.assertEquals +import org.osate.aadl2.instance.ComponentInstance +import org.osate.aadl2.NamedElement + +@RunWith(typeof(XtextRunner)) +@InjectWith(typeof(Aadl2InjectorProvider)) +class ARINC653ScheduleTest extends XtextTest { + + @Inject + TestHelper testHelper + + @Test + def void VPLatencyContribution() { + + val pkg = testHelper.parseString(vplatencyText) + val cls = pkg.ownedPublicSection.ownedClassifiers + assertTrue('', cls.exists[name == 's1.i1']) + + // instantiate + val sysImpl = cls.findFirst[name == 's1.i1'] as SystemImplementation + val instance = InstantiateModel.instantiate(sysImpl) + assertEquals("s1_i1_Instance", instance.name) + + // check flow latency + val som = instance.systemOperationModes.head + val checker = new FlowLatencyAnalysisSwitch(new NullProgressMonitor, instance) + val latencyresult = checker.invoke(instance, som, true, true, true, true) + val resab = latencyresult.results.get(0) + assertTrue((resab.values.get(1) as RealValue).value == (1.0)) + assertTrue((resab.values.get(2) as RealValue).value == (1.0)) + assertTrue((resab.values.get(3) as RealValue).value == (0.0)) + assertTrue((resab.values.get(4) as RealValue).value == (0.0)) + assertTrue((resab.values.get(5) as RealValue).value == (0.0)) + assertTrue((resab.values.get(6) as RealValue).value == (0.0)) + resab.subResults.size.assertEquals(5) + resab.diagnostics.size.assertEquals(1) + val subres = resab.subResults.get(3) + val partnoschedule = subres.sourceReference as NamedElement + assertTrue(partnoschedule instanceof ComponentInstance) + assertEquals(partnoschedule.name,"sub3") + assertEquals(subres.diagnostics.size, 4) + val warn = subres.diagnostics.get(0) + assertEquals(warn.message, "Partition not found in ARINC653 schedule of processor sub4") + } + + val vplatencyText = ''' +package partition2 +public + with ARINC653; + + system s1 + end s1; + + system implementation s1.i1 + subcomponents + sub1: abstract a1; + sub2: abstract a1; + sub3: virtual processor {Period => 1 ms;}; + sub4: processor; + sub5: virtual processor; + connections + conn1: feature sub1.f1 -> sub2.f1; + flows + etef1: end to end flow sub1 -> conn1 -> sub2; + properties + Actual_Processor_Binding => (reference (sub3)) applies to sub2; + Actual_Processor_Binding => (reference (sub4)) applies to sub3; + Actual_Processor_Binding => (reference (sub5)) applies to sub1; + Actual_Processor_Binding => (reference (sub4)) applies to sub5; + ARINC653::Module_Schedule => ([Partition => reference (sub5);]) applies to sub4; + end s1.i1; + + abstract a1 + features + f1: feature; + end a1; +end partition2; + ''' + +}