blob: 8c6be03bae3d87dc3f158849cb385340665e00c6 [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.io.File;
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.CustomObjectsStore;
import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
import org.eclipse.app4mc.slg.config.CodehookType;
import org.eclipse.app4mc.slg.config.ConfigModel;
import org.eclipse.app4mc.slg.config.util.ConfigModelUtils;
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;
@Inject private CustomObjectsStore customObjsStore;
private static final String DEFAULT = "default";
// ---------- generic part "def create new transform(...)" ----------
// ---------------------------------------------testing fetchig names
/* final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
public static void listFilesInFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesInFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
}
*/
// ------------------------------------------------testing fetchig names
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) {
final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);
if (isIncFileEmpty(tu)) {
//----------------------------------/* fetch headers names*/--------------------------------------
// to fetch the headers names we use the getHeaderFilesDirectories function and we go through every directory with the for loop
boolean enableExtCode = Boolean.parseBoolean(properties.getProperty("enableExternalCode"));
if(enableExtCode) {
// input property to test if we need to include the external code headerfiles
for (String hDir : ConfigModelUtils.getHeaderFilesDirectories(configModel,CodehookType.RUNNABLE))
{
final File folder = new File(hDir.trim()); // fetching all the names in the headerfile directory.
String names = ConfigModelUtils.getHeaderFilesIncludeMultiString(folder);
incAppend(tu,names);
}
}
//------------------------------------------------------------------------
incAppend(tu, LinuxRunnableGenerator.snippetIncStart());
}
if (isSrcFileEmpty(tu)) {
srcAppend(tu, LinuxRunnableGenerator.snippetSrcStart(configModel));
}
// write header
incAppend(tu, "\n//Runnable " + runnable.getName() + "----\n");
incAppend(tu, "void " + "run_"+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.ticksSumMap.put(DEFAULT, calc.ticksSumMap.get(DEFAULT)+ticks.getDefault().getAverage().intValue());
}
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"));
boolean enableExtCode = Boolean.parseBoolean(properties.getProperty("enableExternalCode"));
String codeString = LinuxRunnableGenerator.syntheticLoad(runnable,useExperimental,properties,enableExtCode);
srcAppend(tu, LinuxRunnableGenerator.snippetSrcBody(runnable, codeString, enableExtCode ));
}
}