osate / osate2

Open Source AADL2 Tool Environment
http://osate.org
Eclipse Public License 2.0
39 stars 8 forks source link

Bound processor methods do not parallel the bound connection/bus methods #2702

Open AaronGreenhouse opened 3 years ago

AaronGreenhouse commented 3 years ago

Summary

The processor binding methods in InstanceModelUtil are not like the methods for dealing with connection/bus binding. They do not deal with binding via subcomponents in the same way.

Expected behavior The connection binding methods are known to be okay as they are used in the bus load analysis. They correctly handle both cases of binding:

In particular, the method getConnectionBindings() returns the set of components the input component is directly bound to. It finds this by looking up the property association for Actual_Connection_Binding on the input component, and by looking at the containing component of the input component. However the method getProcessorBindings() only looks at the property association for Actual_Processor_Binding. It doesn't look at the containing component.

Instead there are methods like getBoundPhysicalProcessor(), getBoundPhysicalProcessors(), getBoundVirtualProcessors(),but these check if the binding is direct of indirect.

There is no way to test if the component is directly bound to a processor.

Actual behavior

Need a method for bindings that works like getConnectionBindings(). And the other methods should be cleaned up to be more like the connection binding methods.

It's not clear what this will break, if anything is relying on the not quite right implementation right now.

AaronGreenhouse commented 3 years ago

Method should be like these, taken from MixedTrustAnalysis

    /**
     * return set of components the specified instance object (thread, thread group, process, system, virtual processor, device) is directly bound to.
     * Takes into account that virtual processors may be subcomponents of other virtual processors or processors.
     * @param io An instance object for a thread, thread group, process, system, virtual processor, or device.
     * @return A list of the processor or virtual processor instance objects that <code>io</code> is directly bound to.
     */
    private static List<InstanceObject> getProcessorBindings(final InstanceObject io) {
        final List<InstanceObject> bindinglist = DeploymentProperties.getActualProcessorBinding(io)
                .orElse(Collections.emptyList());
        /**
         * If we have a virtual processor, we consider that it is bound to
         * its containing processor or virtual processor.
         */
        if (bindinglist.isEmpty() && io instanceof ComponentInstance
                && ((ComponentInstance) io).getCategory() == ComponentCategory.VIRTUAL_PROCESSOR) {
            final ComponentInstance parent = io.getContainingComponentInstance();
            if (parent.getCategory() == ComponentCategory.PROCESSOR
                    || parent.getCategory() == ComponentCategory.VIRTUAL_PROCESSOR) {
                return Collections.singletonList(parent);
            }
        }
        return bindinglist;
    }

    /**
     * Test if {@code boundObject} is directly or indirectly bound to {@code processor}.
     * It could be bound to a virtual processor which in turn is bound to a processor.
     * the component instance can be a thread, process, or a virtual processor instance
     * @param boundObject Am instance object representing a  thread, thread group, process, system, virtual processor, or device.
     * @param processor A component instance representing a processor or virtual processor.
     * @return {@code true} if and only if {@code boundObject} is bound to {@code processor}
     */
    private static boolean isBoundToProcessor(InstanceObject boundObject, ComponentInstance processor) {
        final List<InstanceObject> bindinglist = getProcessorBindings(boundObject);
        for (final InstanceObject boundCompInstance : bindinglist) {
            if (InstanceModelUtil.isVirtualProcessor(boundCompInstance)) {
                // it is bound to or contained in
                if (isBoundToProcessor(boundCompInstance, processor)) {
                    return true;
                }
            } else if (boundCompInstance == processor) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get all virtual processors bound to the given processor or virtual processor.
     * @param procOrVP A component instance representing a processor or virtual processor,
     * @return A list of all the virtual processors directly or indirectly bound to {@code procOrVP}.
     */
    public static EList<ComponentInstance> getBoundVirtualProcessors(final ComponentInstance procOrVP) {
        final SystemInstance root = procOrVP.getSystemInstance();
        final EList<ComponentInstance> virtualProcs = root
                .getAllComponentInstances(ComponentCategory.VIRTUAL_PROCESSOR);
        final EList<ComponentInstance> result = new BasicEList<ComponentInstance>();
        for (final ComponentInstance ci : virtualProcs) {
            if (isBoundToProcessor(ci, procOrVP)) {
                result.add(ci);
            }
        }
        return result;
    }