blob: e25eef49a0342479c7fb0df7b2ecf174c00c3a3a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017-2020 Dortmund University of Applied Sciences and Arts and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dortmund University of Applied Sciences and Arts - initial API and implementation
*******************************************************************************/
package org.eclipse.app4mc.multicore.partitioning.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.app4mc.amalthea.model.AmaltheaFactory;
import org.eclipse.app4mc.amalthea.model.ConstraintsModel;
import org.eclipse.app4mc.amalthea.model.LabelAccess;
import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
import org.eclipse.app4mc.amalthea.model.Runnable;
import org.eclipse.app4mc.amalthea.model.RunnableEntityGroup;
import org.eclipse.app4mc.amalthea.model.RunnableOrderType;
import org.eclipse.app4mc.amalthea.model.RunnableSequencingConstraint;
import org.eclipse.app4mc.amalthea.model.SWModel;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.slf4j.LoggerFactory;
public class CheckLabels {
private ConstraintsModel cm;
private SWModel swm;
public SWModel getSwm() {
return this.swm;
}
public void setSwm(final SWModel swm) {
this.swm = swm;
}
public void setCMModel(final ConstraintsModel cm) {
this.cm = cm;
}
public ConstraintsModel getCMModel() {
return this.cm;
}
/**
* identifies LabelAccesses within a software model, and creates
* RunnableSequencingConstraints. E.g.: If runnable A writes a label and
* runnable B reads the same label, the corresponding created RSC will have
* runnable A as a RunnableGroupEntry in RunnableGroup0 and runnable B as a
* RunnableGroupEntry in RunnableGroup1.
*/
public IStatus run(final IProgressMonitor monitor) {
if (null != monitor) {
monitor.beginTask("Performing label access analysis...", this.swm.getRunnables().size());
}
final AmaltheaFactory factory = AmaltheaFactory.eINSTANCE;
if (this.cm == null) {
this.cm = factory.createConstraintsModel();
}
final HashMap<Runnable, List<Runnable>> deps = new HashMap<>();
this.swm.getLabels().stream().forEach(l -> {
final Set<LabelAccess> lars = l.getLabelAccesses().stream().filter(la -> la.getAccess().equals(LabelAccessEnum.READ))
.collect(Collectors.toSet());
final Set<LabelAccess> laws = l.getLabelAccesses().stream().filter(lac -> lac.getAccess().equals(LabelAccessEnum.WRITE))
.collect(Collectors.toSet());
if (!lars.isEmpty() && !laws.isEmpty()) {
fillDeps(deps, lars, laws);
}
});
deps.keySet().stream().forEach(key -> deps.get(key).stream().forEach(value -> {
final RunnableSequencingConstraint rsc = factory.createRunnableSequencingConstraint();
rsc.setOrderType(RunnableOrderType.SUCCESSOR);
final RunnableEntityGroup prg1 = factory.createRunnableEntityGroup();
final RunnableEntityGroup prg2 = factory.createRunnableEntityGroup();
prg1.getRunnables().add(key);
prg2.getRunnables().add(value);
rsc.getRunnableGroups().add(prg1);
rsc.getRunnableGroups().add(prg2);
rsc.setName(key.getName() + "-->" + value.getName());
this.cm.getRunnableSequencingConstraints().add(rsc);
}));
LoggerFactory.getLogger(CheckLabels.class).debug("Label Access Analysis finished and created {} RunnableSequencingConstraints.",
this.cm.getRunnableSequencingConstraints().size());
return Status.OK_STATUS;
}
private void fillDeps(final HashMap<Runnable, List<Runnable>> deps, final Set<LabelAccess> lars, final Set<LabelAccess> laws) {
laws.stream().forEach(law -> {
if (law.eContainer().eContainer() instanceof Runnable) {
Runnable key = null;
try {
key = (Runnable) law.eContainer().eContainer();
}
catch (final Exception e) {
key = (Runnable) law.eContainer().eContainer().eContainer();
}
checkReadingRunnables(deps, lars, key);
}
});
}
private void checkReadingRunnables(final HashMap<Runnable, List<Runnable>> deps, final Set<LabelAccess> lars, final Runnable key) {
for (final LabelAccess lar : lars) {
Runnable value = null;
try {
value = (Runnable) lar.eContainer().eContainer();
}
catch (final Exception e) {
value = (Runnable) lar.eContainer().eContainer().eContainer();
}
if (null != key && null != value && !key.equals(value)) {
if (!deps.containsKey(key)) {
final List<Runnable> tmp = new ArrayList<>();
tmp.add(value);
deps.put(key, tmp);
}
else if (!deps.get(key).contains(value)) {
deps.get(key).add(value);
}
}
}
}
}