Note on Implications and Implementation of Reflection ------------------------------------------------------ It is claimed that concurrent object-oriented programming models (COOPs), such as the actor model and its derivatives, would help make it easier to write good parallel programs, through combining the computational power of concurrency with the modeling power of sequential object-oriented programming [1]. Objects provide an effective means for structuring sequential software systems in term of components and interfaces, as well as a useful abstraction for writing parallel programs. An object can maintain its own internal parallelism and control concurrency constraints imposed upon it by other objects. However, this claim cannot be fulfilled for distributed real-time applications, without further considering some important aspects, such as timing constraints, resource management and portability. The functionality of a real-time system requires not only logical correctness, but also temporal correctness. Otherwise, the services of the real-time system will become useless. Reflection is an important dynamic feature, which enables a programmer to control certain components of the underlying system during the cause of execution [2]. In a reflective system there usually exist two kinds of manipulated data, one used to represent the application to be performed, and another used to model the structure and behaviour of the underlying system during the computation. The causal relation between those two kinds of data should be maintained correctly and efficiently. Figure 1 depicts the reflective relationship between application and underlying system, where reflection can be done along either direction: top-down concreting indicates more detailed realization of the application, bottom-up abstraction indicates how to hide dependency on the underlying system. In this paper, we will discuss some implications of reflection on describing predictable and portable distributed real-time applications, as well as how to efficiently implement a reflective system. The relationship between computation, reflection and underlying system. Predictable Performance Until now, a reflective system is often used to deal with the issues of concreting. For example, meta-interpretation can be described in the form of reflection. The reflective system will take care about a number of data and associated operations which are needed to interpret an user program and keep the correct operational semantics. One important aspect of a distributed real-time is to guarantee predictable performance, that is, all timing constraints on the service of the system are met [3]. For some real-time applications, parallel processing may be the only promising approach to achieve a demanded high performance. One in which the timing constraints can be met is to allocate adequate resources to execute an application. Assignment and management of various software and hardware resources are complicated especially when resources are limited. Scheduling can be done statically before runtime, or dynamically during the execution of the application. Static scheduling approaches determine their policies a priori, and they have a low runtime overhead, but are inflexible and may lead to poor resource utilization. In contrast, dynamic scheduling approaches are more flexible and can utilize resources more efficiently, but are more costly in terms of runtime overhead. Scheduling must take timing requirements into account. It is difficult to find an optimal scheduling policy, especially for a dynamic scheduler. The scheduling problem can be represented as a traversal through a search tree. Heuristic algorithms may be helpful to guide search, by cutting off useless sub-trees of the search space. Reflectionf can be used to search a suitable schedule at runtime for an application, since the reflective model holds information about the structure and behaviour of the computation. A programmer can annotate some timing requirements and dependency constraints in the form of reflection, e.g. pre-emptive scheduling should be available for emergencies when resources are inadequate. Portability In the following, the abstraction aspect of reflection will be elaborated. We shall point out that reflection can also help forward portability. It is desirable that a program written for a particular architecture would be run on any type of parallel machines, without costly effects and changes. Since there exist so many different parallel machines, it is difficult to obtain portability for parallel programs. The degree of portability depends on the way in which machine dependency is represented in the programs. Suppose that a program contains some machine dependent expressions. Without loss of efficiency, the program can only be run on machines which are compatible at a low level. The efficiency of the program cannot be sustained on other types of machines, since they necessitate interpretation of those machine dependent expressions. With the help of reflection, a machine dependent expression can be represented in a high level abstraction (meta) form, separately from other machine independent operations. During execution, the abstract version of machine dependent operations will be customized in accordance with the underlying system, hopefully with an acceptable degree of performance degradation. Implementation of reflection According to Maes's definition, there are at least two approaches to implement a reflective models: procedural reflection in which there is a one-to-one relationship between meta-object and base-object, and declarative reflection in which a meta-object can monitor a groups of base-objects [2]. The ABCL/R adopts the procedural reflection, where a meta-object is defined as an executor for its base-object [4]. All incoming message arriving at the base-object will be forwarded to the meta-object. It is the meta-object to decide how to process the messages and maintain the states of the base-object. Although the procedural reflection defines a clear and simple causal relation, the frequent communications between meta- and base-objects will cause difficulties for efficient implementations of such a reflective model to achieve reasonable high performance. On the other hand, the locality of computation should also be taken into account, not only for the local state of an object, but also for frequent interactions among a group of of objects sharing some common resources [5]. We introduce module as an entity of resources management, by extending the traditional definition of module in the context of sequential programming where a module stands for a collection of logically related objects and operations and is used to support information hiding, abstract data types and separate compilation. The new functionalities of a module will include to maintain and allocate certain software and hardware resources among its constituent objects, to reinforce constraints on the execution of the constituent objects, and to perform the reflective computation of the constituent objects. Thus a module may contain schedulers, meta-object and other data structures. Messages flowing between objects are classified into reflective and non-reflective messages. The execution of a reflective message will change the behaviour of the destination object. A message which is not reflective is regarded as being non-reflective. Figure 2 shows that a module contains a meta-object and two base-objects. All incoming messages will first arrive at these two base-objects. The base-objects will process the non-reflective messages and forward the reflective to the meta-object. The meta-object processes the reflective messages and synchronize the execution of its base-objects. A number of different communication protocols between meta- and base-objects can be defined, with various degrees of parallel execution of the objects. Conclusion Remarks Reflection is a promising mechanism to help to obtain predictable performance, portability and other desirable features. We have illustrated some useful roles played by reflection between applications and underlying systems, and how reflective behaviour can be realized based on the module structures. However, more comprehensive work needs to be done on these uses of reflection. The module based reflection system has being studied as a part of the on-going EDA (Extended Dataflow Actor) project, and a prototype will be implemented on transputers in the near future [6]. References [1] G. Agha, Concurrent object-oriented programming. CACM, Sept. 1990. [2] P. Maes, Concepts and experiments in computational reflection, Proc. OOPSLA 1987 [3] Y. Ishikawa et al, Object-Oriented Real-Time Language Design: Constructs for Timing Constraints, Proc. ECOOP/OOPSLA 1990 [4] A. Yonezawa, ABCL: An object-oriented concurrent system. MIT press, 1990. [5] D. Skillicorn, Architecture-independent parallel computation, Computer, Dec. 1990 [6] L-E. Thorelli, H. Wu, The EDA project: principles, status, and plans, 1991. -----------------------