Link Library API 9 Processor API
API Reference Manual  /  8 Link Library API  / 

Link Component API

link_components.create_simple()

NAME
create_simple — create a simple link component class
SYNOPSIS
create_simple(link_class, endpoint_class, connector_type,
              class_desc, basename = None, help_categories = [])

DESCRIPTION
Create a simple link component class based on the following parameters:

Name of the link implementation class
endpoint_class
Name of the link endpoint class
connector_type
Name of the connector type for component connections
class_desc
Component description
basename
Prefix used to create new component names when none is provided

RETURN VALUE
A new component class from which to inherit
EXAMPLE
from link_components import create_simple

class datagram_link(
    create_simple(link_class = 'datagram_link_impl',
                  endpoint_class = 'datagram_link_endpoint',
                  connector_type = 'datagram-link',
                  class_desc = "datagram link",
                  basename = 'datagram_link')):
    """The datagram link component creates a datagram-link, which is a simple
    broadcast bus forwarding messages (as sequences of bytes) from a sender
    device to all other devices present of the link. The datagram-link is both
    an example of how to build a link with the Simics Link Library, and a
    simple broadcast link that can be reused when multi-cell communication
    between devices is necessary. Refer to the <cite>Link Library Programming
    Guide</cite> for more information."""

link_components.link_component

NAME
link_component — link components base class
DESCRIPTION
Class from which to inherit when creating a new custom link component.
EXAMPLE
class ethernet_switch(link_components.link_component):
    """Ethernet switch: this component represents a switched Ethernet network,
    allowing any number of devices to connect and optimizing the packet routing
    according to what is learned about the MAC addresses talking on the link."""
    
    _class_desc = 'an Ethernet switch component'
    _help_categories = ['Ethernet']

    class basename(link_components.link_component.basename):
        val = 'ethernet_switch'
 
    def create_unconnected_endpoint(self, cnt):
        return create_vlan_switch_endpoint(self.get_slot('link'), None,
                                           None, True)

    def register_connector_templates(self):
        self.eth_tmpl = self.add_link_connector_template(
            name = 'ethernet-link-connector',
            type = 'ethernet-link',
            growing = True,
            create_unconnected_endpoint = self.create_unconnected_endpoint)

    def add_objects(self):
        self.add_pre_obj_with_name('link', 'eth-switch-link',
                                   self.get_link_object_name(),
                                   goal_latency = self.goal_latency.val,
                                   global_id = self.global_id.val)
        self.add_link_connector('device', self.eth_tmpl)

link_components.link_component.add_link_connector()

NAME
add_link_connector — add a new initial connector
SYNOPSIS
add_link_connector(self, slot_template, cnt_tmpl)

DESCRIPTION
Add a new initial connector. The slot_template argument is the name of the connector in the component. The cnt_tmpl argument is the template used for the connector, previously registered with add_connector_template().
RETURN VALUE
None
EXAMPLE
class ethernet_switch(link_components.link_component):
    """Ethernet switch: this component represents a switched Ethernet network,
    allowing any number of devices to connect and optimizing the packet routing
    according to what is learned about the MAC addresses talking on the link."""
    
    _class_desc = 'an Ethernet switch component'
    _help_categories = ['Ethernet']

    class basename(link_components.link_component.basename):
        val = 'ethernet_switch'
 
    def create_unconnected_endpoint(self, cnt):
        return create_vlan_switch_endpoint(self.get_slot('link'), None,
                                           None, True)

    def register_connector_templates(self):
        self.eth_tmpl = self.add_link_connector_template(
            name = 'ethernet-link-connector',
            type = 'ethernet-link',
            growing = True,
            create_unconnected_endpoint = self.create_unconnected_endpoint)

    def add_objects(self):
        self.add_pre_obj_with_name('link', 'eth-switch-link',
                                   self.get_link_object_name(),
                                   goal_latency = self.goal_latency.val,
                                   global_id = self.global_id.val)
        self.add_link_connector('device', self.eth_tmpl)

link_components.link_component.add_link_connector_template()

NAME
add_link_connector_template — add a link connector template
SYNOPSIS
add_link_connector_template(self, name, type, growing,
                            create_unconnected_endpoint,
                            get_check_data    = None,
                            get_connect_data  = None,
                            check             = None,
                            connect           = None,
                            disconnect        = None,
                            allow_new_cnt     = lambda: True,
                            allow_destroy_cnt = lambda: True)

DESCRIPTION
This function registers a new connector template for the component. From this template, connectors will be created either statically, via the add_objects() function, or dynamically if requested. Component templates can be customized through the parameters of add_link_connector_template():

name
is the name of the template, which will be saved in each connector, so that they can find out from which template they were created.
type
is the connector type.
growing
indicates whether the connector is static, or should grow dynamically as connections are made. Static connectors must be created in add_objects(), and will act as classic component connectors. A dynamic connector will make sure that there is always a free connector of that template available, by increasing or decreasing the number of connectors of this template in the link. Note that several templates can have the same connector type. Each template will make sure that its connectors grow or shrink separately.
create_unconnected_endpoint
is the function to call when a new endpoint pre-conf-object must be created. This endpoint is not yet connected to a device.
get_check_data
(optional) is called whenever the standard get_check_data() is called. It may return any additional data necessary for the check() call. The standard get_check_data() will already return the endpoint object.
get_connect_data
(optional) is similar to get_check_data, but for the connect() call.
check
(optional) is called whenever the standard check() is called. It may return True (connection accepted) or False (connection refused). The standard implementation returns always True.
connect
(optional) is called whenever the standard connect() is called. The standard connect() will set the device attribute in the endpoint. connect may take any additional action it deems necessary.
disconnect
(optional) is called whenever the standard disconnect() is called. The standard disconnect() does not do anything as the endpoint object will be destroyed soon after. disconnect() may take any additional action for the disconnection to succeed.
allow_new_nct
(optional) is used only for growing connectors. It is called every time a new connection is made to ask if creating a new empty connector is allowed. It may return True (new connector allowed) or False (no new connector). The default function always returns True (unlimited number of connectors allowed, with always one free).
allow_destroy_cnt
(optional) is used only for growing connectors. It is called every time a connection is severed to ask if the connector being disconnected should be destroyed. It may return True (destroy the connector) or False (let the connector). The endpoint object associated will be automatically destroyed with the connector, or replaced if the connector is left. The default function returns always True (unlimited number of connectors allowed, with always one free).

RETURN VALUE
The registered connector template
EXAMPLE
class ethernet_cable(link_components.link_component):
    """Ethernet cable: this component represents a two-points Ethernet cable,
    allowing two devices to connect to each other."""

    _class_desc = 'an Ethernet cable component'
    _help_categories = ['Ethernet']
    
    class basename(link_components.link_component.basename):
        val = 'ethernet_cable'

    class connector_count(SimpleAttribute(0, 'i')):
        """Total number of occupied connectors"""

    def allow_new_connector(self):
        if self.connector_count.val == 2:
            # all connectors are occupied
            return False
        elif self.connector_count.val == 1:
            # there is already one free connector
            self.connector_count.val += 1
            return False
        else:
            self.connector_count.val += 1
            return True

    def allow_destroy_connector(self):
        if self.connector_count.val == 2:
            # two connectors occupied, so let one become free
            self.connector_count.val -= 1
            return False
        else:
            # one connector was occupied, one free, so destroy one
            self.connector_count.val -= 1
            return True

    def create_unconnected_endpoint(self, cnt):
        return create_cable_endpoint(self.get_slot('link'), None)

    def register_connector_templates(self):
        self.eth_tmpl = self.add_link_connector_template(
            name = 'single-ethernet-link-connector',
            type = 'ethernet-link',
            growing = True,
            create_unconnected_endpoint = self.create_unconnected_endpoint,
            allow_new_cnt = self.allow_new_connector,
            allow_destroy_cnt = self.allow_destroy_connector)

    def add_objects(self):
        self.add_pre_obj_with_name('link', 'eth-cable-link',
                                   self.get_link_object_name(),
                                   goal_latency = self.goal_latency.val,
                                   global_id = self.global_id.val)
        self.add_link_connector('device', self.eth_tmpl)

link_components.link_component.add_objects()

NAME
add_objects — add link object and initial connectors
SYNOPSIS
add_objects(self)

DESCRIPTION
This function should be overridden when inheriting from link_component. It is expected to create a pre-conf-object for the link and to add the initial connectors of the component using link_component.add_link_connector(). add_objects() is only called when creating a component from scratch; when restoring a checkpoint, objects are assumed to have already been created.
RETURN VALUE
None
EXAMPLE
class ethernet_switch(link_components.link_component):
    """Ethernet switch: this component represents a switched Ethernet network,
    allowing any number of devices to connect and optimizing the packet routing
    according to what is learned about the MAC addresses talking on the link."""
    
    _class_desc = 'an Ethernet switch component'
    _help_categories = ['Ethernet']

    class basename(link_components.link_component.basename):
        val = 'ethernet_switch'
 
    def create_unconnected_endpoint(self, cnt):
        return create_vlan_switch_endpoint(self.get_slot('link'), None,
                                           None, True)

    def register_connector_templates(self):
        self.eth_tmpl = self.add_link_connector_template(
            name = 'ethernet-link-connector',
            type = 'ethernet-link',
            growing = True,
            create_unconnected_endpoint = self.create_unconnected_endpoint)

    def add_objects(self):
        self.add_pre_obj_with_name('link', 'eth-switch-link',
                                   self.get_link_object_name(),
                                   goal_latency = self.goal_latency.val,
                                   global_id = self.global_id.val)
        self.add_link_connector('device', self.eth_tmpl)

link_components.link_component.get_link_object_name()

NAME
get_link_object_name — return a unique link object name
SYNOPSIS
get_link_object_name(self)

DESCRIPTION
Return a unique link object name based on the link component name. This is useful for ensuring that all link components with the same name in a distributed simulation will indeed represent the same link.
RETURN VALUE
A unique link name
EXAMPLE
class ethernet_switch(link_components.link_component):
    """Ethernet switch: this component represents a switched Ethernet network,
    allowing any number of devices to connect and optimizing the packet routing
    according to what is learned about the MAC addresses talking on the link."""
    
    _class_desc = 'an Ethernet switch component'
    _help_categories = ['Ethernet']

    class basename(link_components.link_component.basename):
        val = 'ethernet_switch'
 
    def create_unconnected_endpoint(self, cnt):
        return create_vlan_switch_endpoint(self.get_slot('link'), None,
                                           None, True)

    def register_connector_templates(self):
        self.eth_tmpl = self.add_link_connector_template(
            name = 'ethernet-link-connector',
            type = 'ethernet-link',
            growing = True,
            create_unconnected_endpoint = self.create_unconnected_endpoint)

    def add_objects(self):
        self.add_pre_obj_with_name('link', 'eth-switch-link',
                                   self.get_link_object_name(),
                                   goal_latency = self.goal_latency.val,
                                   global_id = self.global_id.val)
        self.add_link_connector('device', self.eth_tmpl)

link_components.link_component.register_connector_templates()

NAME
register_connector_templates — register connector templates
SYNOPSIS
register_connector_templates(self)

DESCRIPTION
This function should be overridden when inheriting from link_component. It is expected to register the connector templates that will be used in add_objects(). Unlike add_objects(), this function is always called when creating the component, either from scratch or when restoring a checkpoint.
RETURN VALUE
None
EXAMPLE
class ethernet_switch(link_components.link_component):
    """Ethernet switch: this component represents a switched Ethernet network,
    allowing any number of devices to connect and optimizing the packet routing
    according to what is learned about the MAC addresses talking on the link."""
    
    _class_desc = 'an Ethernet switch component'
    _help_categories = ['Ethernet']

    class basename(link_components.link_component.basename):
        val = 'ethernet_switch'
 
    def create_unconnected_endpoint(self, cnt):
        return create_vlan_switch_endpoint(self.get_slot('link'), None,
                                           None, True)

    def register_connector_templates(self):
        self.eth_tmpl = self.add_link_connector_template(
            name = 'ethernet-link-connector',
            type = 'ethernet-link',
            growing = True,
            create_unconnected_endpoint = self.create_unconnected_endpoint)

    def add_objects(self):
        self.add_pre_obj_with_name('link', 'eth-switch-link',
                                   self.get_link_object_name(),
                                   goal_latency = self.goal_latency.val,
                                   global_id = self.global_id.val)
        self.add_link_connector('device', self.eth_tmpl)

Link Library API 9 Processor API