/******************************************************************************* * * Copyright (c) 2009 Fujitsu Services Ltd. * * Author: Nick Battle * * This file is part of VDMJ. * * VDMJ is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VDMJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VDMJ. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ package org.overture.interpreter.values; import java.util.LinkedList; import java.util.List; import java.util.Vector; import org.overture.ast.types.AClassType; import org.overture.interpreter.runtime.Context; import org.overture.interpreter.runtime.ContextException; import org.overture.interpreter.scheduler.BUSResource; import org.overture.interpreter.scheduler.BusThread; import org.overture.interpreter.scheduler.CPUResource; import org.overture.interpreter.scheduler.FCFSPolicy; import org.overture.interpreter.scheduler.MessageRequest; import org.overture.interpreter.scheduler.MessageResponse; import org.overture.interpreter.scheduler.ResourceScheduler; import org.overture.interpreter.scheduler.SchedulingPolicy; public class BUSValue extends ObjectValue { private static final long serialVersionUID = 1L; private static List<BUSValue> busses = new LinkedList<BUSValue>(); private static BUSValue[][] cpumap = null; public static BUSValue vBUS = null; public final BUSResource resource; public BUSValue(AClassType classtype, NameValuePairMap map, ValueList argvals) { super(classtype, map, new Vector<ObjectValue>(), null, null); QuoteValue parg = (QuoteValue) argvals.get(0); SchedulingPolicy policy = SchedulingPolicy.factory(parg.value.toUpperCase()); RealValue sarg = (RealValue) argvals.get(1); double speed = sarg.value; SetValue set = (SetValue) argvals.get(2); List<CPUResource> cpulist = new Vector<CPUResource>(); for (Value v : set.values) { CPUValue cpuv = (CPUValue) v.deref(); cpulist.add(cpuv.resource); } resource = new BUSResource(false, policy, speed, cpulist); busses.add(this); } public BUSValue(AClassType type, ValueSet cpus) { super(type, new NameValuePairMap(), new Vector<ObjectValue>(), null, null); List<CPUResource> cpulist = new Vector<CPUResource>(); for (Value v : cpus) { CPUValue cpuv = (CPUValue) v.deref(); cpulist.add(cpuv.resource); } resource = new BUSResource(true, new FCFSPolicy(), 0, cpulist); vBUS = this; busses.add(this); } public void setup(ResourceScheduler scheduler, String name) { resource.setName(name); scheduler.register(resource); } public void transmit(MessageRequest request) { resource.transmit(request); } public void reply(MessageResponse response) { resource.reply(response); } @Override public String toString() { return resource.toString(); } public boolean isVirtual() { return resource.isVirtual(); } public static void init() { BUSResource.init(); busses.clear(); // Can't create the vBUS until we know all the CPUs. } public static void start() { for (BUSValue bus : busses) { new BusThread(bus.resource, 0).start(); } } public String getName() { return resource.getName(); } public int getNumber() { return resource.getNumber(); } public static void createMap(Context ctxt, ValueSet allCPUs) { int max = allCPUs.size() + 1; // vCPU missing cpumap = new BUSValue[max][max]; for (int i = 0; i < max; i++) { cpumap[i][0] = vBUS; cpumap[0][i] = vBUS; } for (Value fv : allCPUs) { CPUValue from = (CPUValue) fv; for (Value tv : allCPUs) { CPUValue to = (CPUValue) tv; if (from == to) { continue; } BUSValue bus = findRealBUS(from, to); if (bus == null) { continue; // May be OK - separated island CPUs } int nf = from.getNumber(); int nt = to.getNumber(); if (cpumap[nf][nt] == null) { cpumap[nf][nt] = bus; } else if (cpumap[nf][nt] != bus) { throw new ContextException(4139, "CPUs " + from.getName() + " and " + to.getName() + " connected by " + bus.getName() + " and " + cpumap[nf][nt].getName(), ctxt.location, ctxt); } } } } private static BUSValue findRealBUS(CPUValue from, CPUValue to) { for (BUSValue bus : busses) { if (bus != vBUS && bus.resource.links(from.resource, to.resource)) { return bus; } } return null; } public static BUSValue lookupBUS(CPUValue from, CPUValue to) { return cpumap[from.getNumber()][to.getNumber()]; } }