| /** |
| ******************************************************************************** |
| * 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.generators |
| |
| import org.eclipse.app4mc.amalthea.model.impl.DiscreteValueConstantImpl |
| import org.eclipse.app4mc.amalthea.model.impl.DiscreteValueStatisticsImpl |
| import org.eclipse.app4mc.slg.config.ConfigModel |
| import org.eclipse.app4mc.slg.config.TickType |
| |
| class LinuxTicksUtilsGenerator { |
| |
| // Suppress default constructor |
| private new() { |
| throw new IllegalStateException("Utility class"); |
| } |
| |
| // ---------- names of generated 'C' functions ---------- |
| static def String getExecCall(String params) '''burnTicks(«params»)''' |
| |
| /*'''executeTicks_«valueClass.toString.split("\\.").last»(«params»)'''*/ |
| // -------------------------------------------------------------------- |
| static def String generateTicks(Object valueClass) { |
| switch valueClass { |
| case DiscreteValueConstantImpl: ''' |
| void «getExecCall("int ticks")» { |
| burnTicks(ticks); |
| } |
| |
| ''' |
| case DiscreteValueStatisticsImpl: ''' |
| void «getExecCall("double average, int lowerBound, int upperBound")» { |
| burnTicksStatistics(average, lowerBound, upperBound); |
| } |
| |
| ''' |
| default: '''''' |
| /* |
| * ''' |
| * WARNING:VALUE_FORMAT_NOT_SUPPORTED: «valueClass» |
| * |
| ''' */ |
| } |
| } |
| |
| // ----- public interfaces ----- |
| static def String burnTicks(String burnTicksBody) ''' |
| void burnTicks(int ticks) { |
| «burnTicksBody» |
| } |
| |
| ''' |
| |
| // select statistics parameter according to configuration model |
| // TODO: choose final names of configuration parameters |
| static def String chooseTicks(ConfigModel configModel) { |
| switch configModel.defaultTickType { |
| case TickType.MINIMUM: "lowerBound" |
| case TickType.MAXIMUM: "upperBound" |
| case TickType.AVERAGE: "(int)average" |
| default: "(int)average" |
| } |
| } |
| |
| static def String burnTicksStatistics(ConfigModel configModel) ''' |
| void burnTicksStatistics(double average, int lowerBound, int upperBound) { |
| burnTicks(«chooseTicks(configModel)»); |
| } |
| |
| ''' |
| |
| // ----- default implementations ----- |
| static def String burnTicksDefault() ''' |
| // default implementation of tick burning |
| int numLoops = ticks / 400; |
| # if defined (__x86_64__) |
| int i; |
| for (i = 0; i < numLoops; i++) { |
| «FOR i : 1..400» |
| __asm volatile("nop"); |
| «ENDFOR» |
| } |
| # elif defined (__x86_32__) |
| for (i = 0; i < numLoops; i++) { |
| «FOR i : 1..400» |
| __asm volatile("mov r0, r0"); |
| «ENDFOR» |
| } |
| # elif defined (__aarch64__) |
| for (i = 0; i < numLoops; i++) { |
| «FOR i : 1..400» |
| __asm volatile("mov x0, x0"); |
| «ENDFOR» |
| } |
| # endif |
| ''' |
| |
| // ********************** API's to generate decleration ************************** |
| static def String burnTicksDeclaration() ''' |
| void burnTicks(int ticks); |
| |
| ''' |
| |
| static def String burnTicksStatisticsDecleration() ''' |
| void burnTicksStatistics(double average, int lowerBound, int upperBound); |
| |
| ''' |
| |
| static def String generateTicksDeclaration(Object valueClass) { |
| switch valueClass { |
| case DiscreteValueConstantImpl: ''' |
| void «getExecCall("int ticks")»; |
| |
| ''' |
| case DiscreteValueStatisticsImpl: ''' |
| void «getExecCall("double average, int lowerBound, int upperBound")»; |
| |
| ''' |
| default: '''''' |
| /* |
| * ''' |
| * WARNING:VALUE_FORMAT_NOT_SUPPORTED: «valueClass» |
| * |
| ''' */ |
| } |
| } |
| |
| } |