blob: dbdae5d37d0fea394900c5ad5b5a731585e3e5f4 [file] [log] [blame]
/**
* Copyright (c) 2020-2021 Robert Bosch GmbH.
*
* 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:
* Robert Bosch GmbH - initial API and implementation
*/
package org.eclipse.app4mc.slg.linux.transformers.sw;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.LabelAccess;
import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
import org.eclipse.app4mc.amalthea.model.LabelAccessStatistic;
import org.eclipse.app4mc.amalthea.model.MinAvgMaxStatistic;
import org.eclipse.app4mc.amalthea.model.NumericStatistic;
import org.eclipse.app4mc.amalthea.model.ProcessingUnitDefinition;
import org.eclipse.app4mc.amalthea.model.Runnable;
import org.eclipse.app4mc.amalthea.model.SingleValueStatistic;
import org.eclipse.app4mc.amalthea.model.Ticks;
import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
import org.eclipse.app4mc.slg.linux.generators.LinuxRunnableGenerator;
import org.eclipse.app4mc.slg.linux.generators.LinuxRunnableGenerator.Calculation;
import org.eclipse.app4mc.slg.linux.transformers.LinuxBaseTransformer;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@Singleton
public class LinuxRunnableTransformer extends LinuxBaseTransformer {
@Inject private Properties properties;
// ---------- generic part "def create new transform(...)" ----------
private final Map<List<Object>, SLGTranslationUnit> transformCache = new HashMap<>();
@Override
public Map<List<Object>, SLGTranslationUnit> getCache() {
return this.transformCache;
}
public SLGTranslationUnit transform(final Runnable runnable) {
final List<Object> key = new ArrayList<>(Arrays.asList(runnable));
final SLGTranslationUnit tu;
synchronized (transformCache) {
if (transformCache.containsKey(key)) {
return transformCache.get(key);
}
tu = createTranslationUnit(runnable);
transformCache.put(key, tu);
}
// if translation unit is newly created and valid -> create files
if (tu.isValid()) {
doTransform(tu, runnable);
}
return tu;
}
// ---------------------------------------------------
private SLGTranslationUnit createTranslationUnit(final Runnable runnable) {
if ((runnable == null)) {
return new SLGTranslationUnit("UNSPECIFIED RUNNABLE");
} else {
String basePath = "synthetic_gen";
String moduleName = "runnables";
String call = runnable.getName() + "()";
return new SLGTranslationUnit(basePath, moduleName, call);
}
}
private void doTransform(final SLGTranslationUnit tu, final Runnable runnable) {
genFiles(tu, runnable);
}
private void genFiles(SLGTranslationUnit tu, final Runnable runnable) {
if (isIncFileEmpty(tu)) {
incAppend(tu, LinuxRunnableGenerator.snippetIncStart());
}
if (isSrcFileEmpty(tu)) {
srcAppend(tu, LinuxRunnableGenerator.snippetSrcStart());
}
// write header
incAppend(tu, "\n//Runnable " + runnable.getName() + "----\n");
incAppend(tu, "void " + runnable.getName() + "(char* coreName);\n");
Calculation calc = new Calculation();
calc.ticksSumMap.put("default", Integer.valueOf(0));
if (runnable != null && runnable.getActivityGraph() != null) {
for (ActivityGraphItem item : runnable.getActivityGraph().getItems()) {
if (item instanceof Ticks) {
Ticks ticks = (Ticks) item;
if (ticks.getDefault() != null && ticks.getDefault().getAverage() != null) {
calc.ticksSum += ticks.getDefault().getAverage().intValue();
calc.ticksSumMap.put("default", calc.ticksSum);
}
Set<ProcessingUnitDefinition> puDefinitions = ticks.getExtended().keySet();
for (ProcessingUnitDefinition puDef : puDefinitions) {
if (puDef != null) {
String puDefName = puDef.getName();
if (!calc.ticksSumMap.containsKey(puDefName)) {
calc.ticksSumMap.put(puDefName, 0);
}
calc.ticksSumMap.put(puDefName, calc.ticksSumMap.get(puDefName)
+ ticks.getExtended().get(puDef).getAverage().intValue());
}
}
} else if (item instanceof LabelAccess) {
LabelAccess la = (LabelAccess) item;
Float value = Float
.parseFloat(properties.getOrDefault("labelAccessStatisticValueDefault", "1.0F").toString());
LabelAccessStatistic labelStatistic = la.getStatistic();
if (labelStatistic != null) {
NumericStatistic labelStatisticValue = labelStatistic.getValue();
if (labelStatisticValue instanceof SingleValueStatistic) {
value = ((SingleValueStatistic) labelStatisticValue).getValue();
} else if (labelStatisticValue instanceof MinAvgMaxStatistic) {
// TODO: provide a configuration option, to select appropriate value
// from labelStatistic (min/max/avg)
// right now considering the average value
value = ((MinAvgMaxStatistic) labelStatisticValue).getAvg();
}
}
if (la.getAccess() == LabelAccessEnum.READ) {
calc.readsSum += value.intValue();
} else if (la.getAccess() == LabelAccessEnum.WRITE) {
calc.writesSum += value.intValue();
}
}
}
}
boolean useExperimental = Boolean.parseBoolean(properties.getProperty("experimentalCodeSnippetMatching"));
String codeString = LinuxRunnableGenerator.syntheticLoad(useExperimental);
srcAppend(tu, LinuxRunnableGenerator.snippetSrcBody(runnable, codeString));
}
}