/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. */ /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.thingml.compilers.c.posixmt; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.sintef.thingml.Handler; import org.sintef.thingml.Message; import org.sintef.thingml.Port; import org.sintef.thingml.Property; import org.sintef.thingml.Region; import org.sintef.thingml.Session; import org.sintef.thingml.StateMachine; import org.sintef.thingml.Thing; import org.sintef.thingml.constraints.ThingMLHelpers; import org.sintef.thingml.helpers.CompositeStateHelper; import org.sintef.thingml.helpers.RegionHelper; import org.sintef.thingml.helpers.StateHelper; import org.sintef.thingml.helpers.ThingHelper; import org.thingml.compilers.DebugProfile; import org.thingml.compilers.c.CCompilerContext; import org.thingml.compilers.c.CThingApiCompiler; /** * * @author sintef */ public class PosixMTThingApiCompiler extends CThingApiCompiler { @Override protected void generateCHeaderAnnotation(Thing thing, StringBuilder builder, CCompilerContext ctx) { builder.append("#include \"runtime.h\"\n"); super.generateCHeaderAnnotation(thing, builder, ctx); } protected List<Region> regionSession(Region r) { List<Region> res = new ArrayList<Region>(); res.addAll(RegionHelper.allContainedSessions(r)); for(Session s : RegionHelper.allContainedSessions(r)) res.addAll(regionSession(s)); return res; } @Override protected void generateInstanceStruct(Thing thing, StringBuilder builder, CCompilerContext ctx, DebugProfile debugProfile) { builder.append("// Definition of the sessions stuct:\n\n"); StateMachine sm = ThingMLHelpers.allStateMachines(thing).get(0); if(!CompositeStateHelper.allContainedSessions(sm).isEmpty()) { builder.append("struct session_t;\n\n"); } builder.append("// Definition of the instance stuct:\n"); builder.append("struct " + ctx.getInstanceStructName(thing) + " {\n"); builder.append("bool active;\n"); builder.append("bool alive;\n"); //builder.append("// Variables for the ID of the instance\n"); //builder.append("int id;\n"); builder.append("// Variables for the ID of the ports of the instance\n"); //if(ctx.containsDebug(ctx.getCurrentConfiguration(), thing)) { if(debugProfile.isActive()) { builder.append("bool debug;\n"); builder.append("char * name;\n"); } for (Port p : ThingMLHelpers.allPorts(thing)) { builder.append("uint16_t id_"); builder.append(p.getName()); builder.append(";\n"); } //fifo builder.append("struct instance_fifo fifo;\n"); //Sessions builder.append("\n// Instances of different sessions\n"); for(Session s : CompositeStateHelper.allContainedSessions(sm)) { builder.append("struct session_t * sessions_" + s.getName() + ";\n"); } // Variables for each region to store its current state builder.append("\n// Variables for the current instance state\n"); // This should normally be checked before and should never be true if (ThingMLHelpers.allStateMachines(thing).size() > 1) { throw new Error("Info: Thing " + thing.getName() + " has " + ThingMLHelpers.allStateMachines(thing).size() + " state machines. " + "Error: Code generation for Things with several state machines not implemented."); } if (ThingMLHelpers.allStateMachines(thing).size() > 0) { builder.append("int initState;\n"); for (Region r : RegionHelper.allContainedRegionsAndSessions(sm)) { builder.append("int " + ctx.getStateVarName(r) + ";\n"); } } // Create variables for all the properties defined in the Thing and States builder.append("// Variables for the properties of the instance\n"); for (Property p : ThingHelper.allPropertiesInDepth(thing)) { builder.append(ctx.getCType(p.getType()) + " "); if (p.getCardinality() != null) {//array builder.append("* "); } builder.append(ctx.getCVarName(p)); builder.append(";\n"); if(p.getCardinality() != null) {//array builder.append("uint16_t "); builder.append(ctx.getCVarName(p)); builder.append("_size;\n"); } } builder.append("\n};\n"); if(!CompositeStateHelper.allContainedSessions(ThingMLHelpers.allStateMachines(thing).get(0)).isEmpty()) { builder.append("struct session_t {\n"); builder.append(" struct " + ctx.getInstanceStructName(thing) + " s;\n"); builder.append(" pthread_t thread;\n"); builder.append(" byte fifo_array[65535];\n"); builder.append(" struct session_t * next;\n"); builder.append("};\n\n"); } } @Override protected void generatePublicPrototypes(Thing thing, StringBuilder builder, CCompilerContext cctx) { PosixMTCompilerContext ctx = (PosixMTCompilerContext) cctx; builder.append("// Message enqueue\n"); for (Port p : ThingMLHelpers.allPorts(thing)) { for (Message m : p.getReceives()) { if(StateHelper.canHandle(ThingMLHelpers.allStateMachines(thing).get(0), p, m)) { builder.append("void enqueue_" + thing.getName() + "_" + p.getName() + "_" + m.getName()); ctx.appendFormalParametersForEnqueue(builder, thing, m); builder.append(";\n"); } } } builder.append("\n// Fork Sessions\n"); for(Session s : RegionHelper.allContainedSessions(ThingMLHelpers.allStateMachines(thing).get(0))) { builder.append("void fork_" + s.getName() + "(struct " + ctx.getInstanceStructName(thing) + " * _instance);\n\n"); } builder.append("\n// ProcessMessageQueue\n"); builder.append("int " + thing.getName() + "_processMessageQueue(struct " + ctx.getInstanceStructName(thing) + " * _instance);\n\n"); builder.append("// Run\n"); builder.append("void " + thing.getName() + "_run(struct " + ctx.getInstanceStructName(thing) + " * _instance);\n\n"); } }