Friedrich-Alexander-Universität UnivisSearch FAU-Logo
Techn. Fakultšt Willkommen am Department Informatik FAU-Logo
Logo I4
Department of Computer Science 4
Documentation
  Hello World: First Steps
  Toolchain
  Raw Memory Access
  Inter-Domain Comm.
  Service Protection
  CiAO backend
  core module API

Inter-Domain Comm.
  Portals
    - Example
    - KESORC directives
    - Code usage
    - Parameter Passing
  Shared Memory
Dept. of Computer Science  >  CS 4  >  Research  >  KESO  >  Documentation  >  Inter-Domain Communication
Inter-Domain Communication

KESO allows you to spatially isolate different applications or parts of one application by putting the parts to be isolated from another in different domains. This is done by simply defining multiple Domain blocks in the $KESORC file. Normally, the isolated applications or application components will need to communicate with each other. KESO provides two OS-independant mechanisms for exchanging data between different domains, portals and shared memory, the usage of which will be explained in this howto. The CiAO backend additionally offers KESO APIs to use CiAO's native inter-application communication mechanisms, which are primarily intended to exchange data between Java applications and native applications. These mechanisms will not be discussed in this howto.

The Portal mechanism

Portals are the primary inter-domain communication mechanism. The concept is similar to that of Java RMI. The portal mechanism enable a domain (the service domain) to export a service to other domains (the client domains). The service is described by a Java interface definition, and manifests in the service domain in the form of a service object, that is an instance of a class implementing the service interface. The portal mechanism allows control flows in the client domains to invoke the methods of the service interface in the protection context of the service domain.

Example: TickerService

Portals The example in the figure shows four domains. The Srv domain exports a service named TickerService, described by the Java interface TickerService, that is imported by the client domains A and B. Domain C does not import the service and hence will not be able to use it at runtime.

The TickerService defines one method, roundtrip(), which constitutes our example service. This method is implemented by the class TickerServiceImpl, which contains an additional method foo(). Since foo() is not defined by the service interface, it does not become part of the exported service and can thus not be (directly) invoked by control flows of the client domains.

jino statically creates an instance of the TickerServiceImpl in the service domain. In addition, a proxy object (the portal) is allocated; the proxy object is an instance of an automatically generated class that also implements the TickerService interface. Calling the roundtrip() method on the proxy object switches the execution domain context to the service domain, calls the roundtrip() on the service object and upon return restores the original execution domain context.

Definition in the KESORC configuration file

Exported services need to be defined in the Domain block of the service domain in the $KESORC file. Likewise, client domains need to declare which services they want to access by defining an Import block for each imported service.

World (TickerService) { System (AVR) { Domain (Srv) { # export service named TickerService Service (TickerService) { # interface describing the service ServiceInterface="TickerService"; # class implementing the service (must implement the above interface) ServiceClass="TickerServiceImpl"; } } Domain (A) { # import the TickerService # makes this domain a client domain that service Import (TickerService) { } } Domain (B) { Import (TickerService) { } } Domain (C) { } } }

The above example shows the relevant portions of a $KESORC configuration file for the TickerService example. Irrelevant parts such as heap and task definitions are omitted to keep the example clear.

The TickerService is provided by the domain Srv by defining a Service block in the Domain block of that domain. The name of the service block becomes the name of the service, which will be used when referring to this service from both the code and other statements of the configuration file. Thus, the name chosen for the service must not be reused in another service definition. The service block needs to contain two attributes:

  • The ServiceInterface attribute contains the fully qualified name of Java interface describing the service. The service interface needs to extend the Portal marker interface.
  • The ServiceClass attribute contains the fully qualified name of the class that shall provide the implementation for the service. The service object created for the service will be an instance of this class. The service class needs to implement the Service marker interface.

All domains that want to use a service need to import that service using an Import block. The name of the block refers to the service that is to be imported. In our example, the domains A and B use this service, thus their Domain blocks contain the appropriate import statements. Domain C does not import the service, and consequently will not be able to access it at runtime.

Usage in the Java code

To access the service from the Java code, the control flow that want to invoke a portal call needs to get hold of the proxy object for that service. For this, it uses the lookup() method of the PortalService:

TickerService ts = (TickerService) PortalService.lookup("TickerService"); ts.roundtrip();

The definitions of the service interface and the service class do not differ from other Java class definition, except that the Portal marker interface needs to be extended by the service interface and the Service marker interface must be implemented by the service class:

// TickerService.java public interface TickerService extends keso.core.Portal { public void roundtrip(); }

// TickerServiceImpl.java public class TickerService implements keso.core.Service,TickerService { public void roundtrip() { /* do something /* } private void foo() { /* do something else */ } }

Parameter/Return value Passing

The spatial isolation in KESO relies on a logical separation of the domains' object heaps (implemented as physical heap separation in KESO). This means that each dynamically allocated object is visible to exactly one domain at any time. To retain this separation, objects cannot be passed by reference in the invocation of portal calls, since this would make the passed object visible in both the client and the service domain. The same issue also affects return values of portal calls.

To avoid this problem, KESO passes both primitive values and objects by value when given as parameters to or returned by a portal call. For passed objects, the entire transitive closure of the object is cloned to the heap of the service domain, i.e. the the directly referenced object is cloned, all objects referenced by this objects, all objects referenced by these objects, and so on. In some cases, this may lead to a large portion of the object heap being cloned. Also, changes to the object clones in the service domain are not propagated back to the client domain. The programmer needs to keep this in mind when using portal calls. It is best to avoid using non-primitive parameters or return values in service interfaces if possible. To enable the programmer to constrain the objects being copied, KESO provides the NonCopyable marker interface. Objects of classes that implement this interface are not cloned during a portal call. Instead, the reference is replaced by a null reference.

Shared Memory

The by-value parameter passing of portals may be expensive if two domains need to cooperate on a large amount of data. For this special case, there is a second mechanism for sharing data between domains in KESO, shared memory. KESO's shared memory is based on Memory objects, that provide primitive data access to an area of raw memory. The howto on programming device drivers discusses the use of Memory objects.

Contrary to the programming of device drivers, the shared memory area needs to be a regular memory area rather than an address region in that memory-mapped device registers reside. To allocate such an area of memory, use the allocMemory() or allocStaticMemory() services of the MemoryService class.

Now after having allocated the shared memory region, the other domain(s) that the domain wants to share the data with also need to be able to access the area. This happens by providing the Memory object via a service or passing it as parameter to a portal call in the other domain(s). The by-value invocation and return value semantic of the portal call will clone the Memory object in the target domain, but it will still refer to the same area of memory. Thus, the participating domains each use a different Memory object, but all memory accesses through any of these objects happen on the same area of memory - the raw memory area allocated originally allocated by one domain has thus become a shared memory region.

In the same manner as with Memory objects referring to device memory areas, the abstraction of memory-mapped objects may also be used based on raw memory regions of regular memory. To create such a mapping from an existing Memory object, use the mapMemoryToStaticObject() service provided by the MemoryService class.

  Contact Last modified: 2011-01-18 13:05   MS