use of org.osate.aadl2.contrib.timing.TimingProperties in project osate2 by osate.
the class FlowLatencyAnalysisSwitch method processSamplingAndQueuingTimes.
/*
* boundBusOrRequiredClassifier is a ComponentInstance if it is a bus bound to connection instance, or a
* ComponentClassifier if it is a virtual bus required by a connection connnection or vb.
*
* bindingConnection is the ConnectionInstance that boundBusOrRequiredClassifier is bound to if
* boundBusOrRequiredClassifier is a componentInstance. Otherwise it is null.
*/
private void processSamplingAndQueuingTimes(final NamedElement boundBusOrRequiredClassifier, final ConnectionInstance bindingConnection, final LatencyContributor latencyContributor) {
// XXX: [Code Coverage] boundBus cannot be null.
if (boundBusOrRequiredClassifier != null) {
final ComponentCategory cc = boundBusOrRequiredClassifier instanceof ComponentInstance ? ((ComponentInstance) boundBusOrRequiredClassifier).getCategory() : ((ComponentClassifier) boundBusOrRequiredClassifier).getCategory();
double period = hasPeriod.contains(cc) ? PropertyUtils.getScaled(TimingProperties::getPeriod, boundBusOrRequiredClassifier, TimeUnits.MS).orElse(0.0) : 0.0;
if (period > 0) {
// add sampling latency due to the protocol or bus being periodic
LatencyContributor samplingLatencyContributor = new LatencyContributorComponent(boundBusOrRequiredClassifier, report.isMajorFrameDelay());
samplingLatencyContributor.setBestCaseMethod(LatencyContributorMethod.SAMPLED_PROTOCOL);
samplingLatencyContributor.setWorstCaseMethod(LatencyContributorMethod.SAMPLED_PROTOCOL);
samplingLatencyContributor.setSamplingPeriod(period);
latencyContributor.addSubContributor(samplingLatencyContributor);
// add queuing latency: always zero in this case
LatencyContributor queuingLatencyContributor = new LatencyContributorComponent(boundBusOrRequiredClassifier, report.isMajorFrameDelay());
queuingLatencyContributor.setBestCaseMethod(LatencyContributorMethod.QUEUED);
queuingLatencyContributor.setWorstCaseMethod(LatencyContributorMethod.QUEUED);
queuingLatencyContributor.setMinimum(0.0);
queuingLatencyContributor.setMaximum(0.0);
latencyContributor.addSubContributor(queuingLatencyContributor);
} else {
/*
* Issue 1148
*
* if "boundBus" is really a bound component instance, and not a required component classifier,
* then we remember the bus as asynchronous. Later in fillInQueuingTimes() we go through this list,
* and then find all the connection instances bound to this bus. For each connection,
* we compute the sum of the max transmission times of the OTHER connections bound to the bus. This
* we set as the worse case queuing time. (Best case is 0.)
*
* We also remember the bus--connection pair that needs the queuing latency by storing its latency contributor.
*/
if (bindingConnection != null) {
final ComponentInstance boundBus = (ComponentInstance) boundBusOrRequiredClassifier;
/* Set the bus order and then add it to the ordered set */
if (!busOrder.containsKey(boundBus)) {
busOrder.put(boundBus, nextBusId++);
asyncBuses.add(boundBus);
}
connectionsToContributors.put(new Pair<>(boundBus, bindingConnection), latencyContributor);
}
}
}
}
use of org.osate.aadl2.contrib.timing.TimingProperties in project osate2 by osate.
the class Binpack method analyzeInstanceModel.
@Override
protected void analyzeInstanceModel(final IProgressMonitor monitor, final AnalysisErrorReporterManager errManager, final SystemInstance root, final SystemOperationMode som) {
try {
monitor.beginTask("Binding threads to processors in " + root.getName(), IProgressMonitor.UNKNOWN);
logInfo("Binpacker Analysis Report\n");
/*
* Verify that all the busses have a transmission time
*/
final ForAllElement addBuses = new ForAllElement(errManager) {
@Override
public void process(Element obj) {
checkBuses((ComponentInstance) obj);
}
};
addBuses.processPreOrderComponentInstance(root, ComponentCategory.BUS);
/*
* Find and report all thread and device instances that don't have a
* period specified.
*/
EList<Element> incompletethreads = new ForAllElement() {
@Override
protected boolean suchThat(Element obj) {
final ComponentCategory cat = ((ComponentInstance) obj).getCategory();
if (cat == ComponentCategory.THREAD || cat == ComponentCategory.DEVICE) {
return org.osate.pluginsupport.properties.PropertyUtils.getScaled(TimingProperties::getPeriod, (ComponentInstance) obj, TimeUnits.MS).orElse(0.0) == 0.0;
} else {
return false;
}
}
}.processPreOrderComponentInstance(root);
for (final Iterator<Element> i = incompletethreads.iterator(); i.hasNext(); ) {
final ComponentInstance o = (ComponentInstance) i.next();
logWarning((InstanceModelUtil.isThread(o) ? "Thread " : "Device ") + o.getComponentInstancePath() + " is missing period property. Using default of 1 ns");
}
/*
* Find and report all thread instances that don't have a
* compute execution time specified.
*/
incompletethreads = new ForAllElement() {
@Override
protected boolean suchThat(Element obj) {
return GetProperties.getThreadExecutioninMilliSec((ComponentInstance) obj) == 0.0;
}
}.processPreOrderComponentInstance(root, ComponentCategory.THREAD);
for (final Iterator<Element> i = incompletethreads.iterator(); i.hasNext(); ) {
final ComponentInstance o = (ComponentInstance) i.next();
logWarning("Thread " + o.getComponentInstancePath() + " is missing compute_execution_time or InstructionsPerDispatch property. Using default of 0 ns");
}
/*
* Find if all the port connections have data size
*/
final ForAllElement addThreadConnections = new ForAllElement(errManager) {
@Override
public void process(Element obj) {
if (obj instanceof ConnectionInstance) {
final ConnectionInstance connInst = (ConnectionInstance) obj;
if (connInst.getKind() == ConnectionKind.PORT_CONNECTION) {
final FeatureInstance src = (FeatureInstance) connInst.getSource();
Feature srcAP = src.getFeature();
Classifier cl = srcAP.getClassifier();
if (cl instanceof DataClassifier) {
DataClassifier srcDC = (DataClassifier) cl;
if (AadlContribUtils.getDataSize(srcDC, SizeUnits.BYTES) == 0) {
logWarning("Data size of connection source port " + src.getComponentInstancePath() + " not specified");
}
}
}
}
}
};
addThreadConnections.processPreOrderAll(root);
/* The partitionChoice is set in initializeANalysis() */
NoExpansionExpansor expansor = new NoExpansionExpansor();
LowLevelBinPacker packer = null;
if (partitionChoice == IMMEDIATE_PARTITION) {
packer = new BFCPBinPacker(expansor);
} else if (partitionChoice == DEFER_EXEC_TIME) {
packer = new DFCPBinPacker(expansor);
} else if (partitionChoice == DEFER_BANDWIDTH) {
packer = new DFBPBinPacker(expansor);
}
AssignmentResult result = binPackSystem(root, expansor, packer, errManager, som);
reportResults(som, result);
if (result.isSuccess()) {
showResults(som, root, result);
} else {
showNoResults(som);
}
} catch (InvalidModelException e) {
error(e.getElement(), e.getMessage());
}
}
use of org.osate.aadl2.contrib.timing.TimingProperties in project osate2 by osate.
the class AbstractResourceAnalysis method getThreadExecutioninMIPS.
protected static double getThreadExecutioninMIPS(ComponentInstance threadinstance) {
if (!InstanceModelUtil.isThread(threadinstance)) {
return 0;
}
double mips = getThreadExecutionIPDinMIPS(threadinstance);
if (mips == 0) {
double period = PropertyUtils.getScaled(TimingProperties::getPeriod, threadinstance, TimeUnits.SEC).orElse(0.0);
double exectimeval = PropertyUtils.getScaledRange(TimingProperties::getComputeExecutionTime, threadinstance, TimeUnits.SEC).orElse(RealRange.ZEROED).getMaximum();
if (exectimeval > 0 && period > 0) {
final ComponentInstance thread = threadinstance;
double mipspersec = TimingProperties.getReferenceProcessor(thread).map(pci -> getMIPSCapacityInMIPS(pci, 0.0)).orElse(0.0);
if (mipspersec == 0) {
mipspersec = getBoundPhysicalProcessorMIPS(threadinstance);
}
double time = exectimeval / period;
mips = time * mipspersec;
}
}
return mips;
}
use of org.osate.aadl2.contrib.timing.TimingProperties in project osate2 by osate.
the class PriorityInversion method checkDecreasingPriority.
/**
* Check if explicitly assigned priorities in a thread list (sorted in increasing period order)
* violate rate monotic priorities
*
* Checking is done by rate group. Inside a group all threads must have priority lower than the
* lowest priority in any previous rate group.
*
* Threads without priority assignment are reported as a warning
*
* @since 2.0
*/
public void checkDecreasingPriority(List<Element> threadList) {
// => priorities should decrease
if (threadList.isEmpty()) {
return;
}
/**
* The period of the current rate group
*/
double groupPeriod = -1.0;
/**
* The lowest priority (so far) in the current rate group
*/
long groupLowestPriority = Long.MAX_VALUE;
/**
* The lowest priority encountered before the current rate group
*/
long lowestPriority = Long.MAX_VALUE;
for (Element e : threadList) {
ComponentInstance thread = (ComponentInstance) e;
double period = PropertyUtils.getScaled(TimingProperties::getPeriod, thread, TimeUnits.MS).orElse(0.0);
long priority = GetProperties.getPriority(thread, Long.MIN_VALUE);
if (priority == Long.MIN_VALUE) {
errManager.warning(thread, "Thread '" + thread.getName() + "' has no priority assigned");
} else {
if (period == groupPeriod) {
// just record the lowest priority in the current rate group
if (priority < groupLowestPriority) {
groupLowestPriority = priority;
}
} else {
// switch to next group
groupPeriod = period;
if (groupLowestPriority < lowestPriority) {
lowestPriority = groupLowestPriority;
}
groupLowestPriority = priority;
}
if (priority >= lowestPriority) {
// priority inversion
errManager.error(thread, "Thread '" + thread.getName() + "' with priority " + priority + " causes priority inversion");
}
}
}
}
use of org.osate.aadl2.contrib.timing.TimingProperties in project osate2 by osate.
the class GetProperties method getComputeDeadlineinMilliSec.
public static double getComputeDeadlineinMilliSec(final NamedElement ne) {
Property deadline = lookupPropertyDefinition(ne, TimingProperties._NAME, TimingProperties.COMPUTE_DEADLINE);
UnitLiteral milliSecond = findUnitLiteral(deadline, AadlProject.MS_LITERAL);
return PropertyUtils.getScaledNumberValue(ne, deadline, milliSecond, 0.0);
}
Aggregations