All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fujitsu.vdmj.in.definitions.INSystemDefinition Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *
 *	Copyright (c) 2016 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 .
 *	SPDX-License-Identifier: GPL-3.0-or-later
 *
 ******************************************************************************/

package com.fujitsu.vdmj.in.definitions;

import java.util.HashMap;

import com.fujitsu.vdmj.in.INNode;
import com.fujitsu.vdmj.in.annotations.INAnnotationList;
import com.fujitsu.vdmj.in.definitions.visitors.INDefinitionVisitor;
import com.fujitsu.vdmj.mapper.ClassMapper;
import com.fujitsu.vdmj.messages.RTLogger;
import com.fujitsu.vdmj.runtime.Context;
import com.fujitsu.vdmj.runtime.ContextException;
import com.fujitsu.vdmj.runtime.RootContext;
import com.fujitsu.vdmj.runtime.ValueException;
import com.fujitsu.vdmj.scheduler.ResourceScheduler;
import com.fujitsu.vdmj.tc.definitions.TCBUSClassDefinition;
import com.fujitsu.vdmj.tc.definitions.TCCPUClassDefinition;
import com.fujitsu.vdmj.tc.lex.TCNameList;
import com.fujitsu.vdmj.tc.lex.TCNameToken;
import com.fujitsu.vdmj.tc.types.TCClassType;
import com.fujitsu.vdmj.tc.types.TCType;
import com.fujitsu.vdmj.tc.types.TCUndefinedType;
import com.fujitsu.vdmj.values.BUSValue;
import com.fujitsu.vdmj.values.CPUValue;
import com.fujitsu.vdmj.values.NameValuePairList;
import com.fujitsu.vdmj.values.ObjectValue;
import com.fujitsu.vdmj.values.QuoteValue;
import com.fujitsu.vdmj.values.RealValue;
import com.fujitsu.vdmj.values.UpdatableValue;
import com.fujitsu.vdmj.values.ValueList;
import com.fujitsu.vdmj.values.ValueSet;

public class INSystemDefinition extends INClassDefinition
{
	private static final long serialVersionUID = 1L;
	private static ObjectValue systemObject = null;

	public static NameValuePairList getSystemMembers()
	{
		if (systemObject != null)
		{
			return systemObject.members.asList();
		}

		return null;
	}
	
	public static ObjectValue getSystemObject()
	{
		return systemObject;
	}

	public INSystemDefinition(INAnnotationList annotations, TCNameToken className, TCClassType type, INDefinitionList members)
	{
		super(annotations, className, type, new TCNameList(), members, new INDefinitionList(),
			new INDefinitionList(), new INClassList(), null, false);
	}

	public void systemInit(ResourceScheduler scheduler, RootContext initialContext)
	{
		initialContext.setThreadState(CPUValue.vCPU);

		try
		{
			// First go through the definitions, looking for CPUs to decl
			// before we can deploy to them in the constructor. We have to
			// predict the CPU numbers at this point.

			INDefinitionList cpudefs = new INDefinitionList();
			int cpuNumber = 1;
			TCCPUClassDefinition cpudef = null;

			for (INDefinition d: definitions)
			{
				TCType t = d.getType();

				if (t instanceof TCClassType)
				{
					INInstanceVariableDefinition ivd = (INInstanceVariableDefinition)d;
					TCClassType ct = (TCClassType)t;

					if (ct.classdef instanceof TCCPUClassDefinition)
					{
						cpudefs.add(d);
						cpudef = (TCCPUClassDefinition)ct.classdef;

	    				RTLogger.log(
	    					"CPUdecl -> id: " + (cpuNumber++) +
	    					" expl: " + !(ivd.expType instanceof TCUndefinedType) +
	    					" sys: \"" + name.getName() + "\"" +
	    					" name: \"" + d.name.getName() + "\"");
					}
				}
			}

			// Run the constructor to do any deploys etc.

			systemObject = makeNewInstance(null, new ValueList(),
					initialContext, new HashMap(), false);

			// Do CPUs first so that default BUSses can connect all CPUs.

			INCPUClassDefinition instance = ClassMapper.getInstance(INNode.MAPPINGS).convert(cpudef);
			ValueSet cpus = new ValueSet();

			for (INDefinition d: cpudefs)
			{
    			UpdatableValue v = (UpdatableValue)systemObject.members.get(d.name);
    			CPUValue cpu = null;

    			if (v.isUndefined())
    			{
    				ValueList args = new ValueList();

    				args.add(new QuoteValue("FCFS"));	// Default policy
    				args.add(new RealValue(0));			// Default speed

    				cpu = (CPUValue)instance.newInstance(null, args, initialContext);
    				v.set(location, cpu, initialContext);
    			}
    			else
    			{
    				cpu = (CPUValue)v.deref();
    			}

    			// Set the name and scheduler for the CPU resource, and
    			// associate the resource with the scheduler.

    			cpu.setup(scheduler, d.name.getName());
    			cpus.add(cpu);
			}

			// We can create vBUS now that all the CPUs have been created
			// This must be first, to ensure it's bus number 0.

			BUSValue.vBUS = INBUSClassDefinition.makeVirtualBUS(cpus);
			BUSValue.vBUS.setup(scheduler, "vBUS");

			for (INDefinition d: definitions)
			{
				TCType t = d.getType();

				if (t instanceof TCClassType)
				{
					TCClassType ct = (TCClassType)t;

					if (ct.classdef instanceof TCBUSClassDefinition)
					{
						UpdatableValue v = (UpdatableValue)systemObject.members.get(d.name);
	    				BUSValue bus = null;

						if (!v.isUndefined())
						{
							bus = (BUSValue)v.deref();

							// Set the name and scheduler for the BUS resource, and
							// associate the resource with the scheduler.

							bus.setup(scheduler, d.name.getName());
						}
					}
				}
			}

			// For efficiency, we create a 2D array of CPU-to-CPU bus links
			BUSValue.createMap(initialContext, cpus);
		}
		catch (ContextException e)
		{
			throw e;
		}
		catch (ValueException e)
		{
			abort(e);
		}
    	catch (Exception e)
    	{
    		abort(4135, "Cannot instantiate a system class", initialContext);
    	}
	}

	@Override
	public ObjectValue newInstance(
		INDefinition ctorDefinition, ValueList argvals, Context ctxt)
	{
		abort(4135, "Cannot instantiate system class " + name, ctxt);
		return null;
	}

	@Override
	public  R apply(INDefinitionVisitor visitor, S arg)
	{
		return visitor.caseSystemDefinition(this, arg);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy