Rosette: An object-oriented concurrent systems architecture

A number of concurrent computers have been designed, such as [Ametek 1988] and [NCUBE 1986]. Taking advantage of concurrency on these computers will require new languages, operating systems, and environments to support the programming, monitoring and control of applications. The Rosette project at MCC is developing a system architecture for general-purpose concurrent computation based on the Actor model [Agha 1986]. The aim of the Rosette architecture is to support the use of concurrent computers in solving computationally intensive problems whose structure is not statically determined. The architecture will support variable grain size, dynamic resource management, reflection, and heterogeneity. A number of concurrent language proposals have employed computational models that are limited in their applicability because of assumptions such as granularity of concurrency, static process topology, or inherent communications cost. Others, for example, functional programming, cannot be used to model shared, modifiable objects. The Actor model addresses these issues directly. However, the difficulties of using concurrent computers cannot be addressed solely through programming languages. Traditional operating systems treat each process as an independent entity for the purposes of resource management (i.e., for the run-time allocation of processor, storage, and communication resources.) In the context of concurrent applications, effective operation on a concurrent computer requires that communities of processes be managed together, taking into account the ways in which they interact, and providing for the application itself to guide resource management. For example, consider that programming systems often provide only limited support for the control of resource consumption in search problems in the face of combinatorial explosion; further, it is generally recognized that to optimize search performance, it is useful to vary the resources provided depending on how promising intermediate results of a given path are judged to be. The Rosette architecture will allow the programmer to integrate high-level algorithms within the application for dividing resources dynamically among the sub-computations that are spawned. These algorithms will provide an assessment of the progress of the sub-computations, and will be used to make the large number of low-level resource management decisions that are necessary in carrying out the computation. Thus, operating system functionality will be folded into the application. The Rosette architecture has two major components: an interface layer and a system environment. The interface layer provides mechanisms for the monitoring and control of concurrent applications. It supports a uniform view of the system resources and applications through the use of actors and message-passing semantics. The interface layer includes a set of actors that represent the processing, storage and communication resources across the hardware base. The system environment contains actor communities which implement resource management policies, and support for programming concurrent applications. The environment consists of an extensible set of actors that are organized via a class-based object model. These actors provide monitoring, debugging, resource management system simulation, and compilation/transformation facilities. To demonstrate the effectiveness of the Rosette architecture, as well as to drive its development, two classes of applications are being used. The first class is the Rosette system itself: all of the system components necessary for resource management, monitoring, debugging, and program development are being constructed in the Rosette language and will take full advantage of both concurrency and object-oriented programming support. The second category of applications is chosen to be somewhat independent of the Rosette system so as to ensure adequate feed-back concerning applicability to domains other than software engineering. These applications are in the general area of knowledge-based signal interpretation. The Rosette architecture is implemented via a concurrent object-oriented programming language that provides the following features: Inherent concurrency: A declarative approach is needed which allows fine-grained concurrency to arise naturally from the program. If the programmer is forced to express all of the details of the concurrent execution of an application, it becomes difficult to re-map a given program to different concurrent computers which have varying concurrency characteristics. Dynamic creation/modification of objects: This allows the system to be extensible and reconfigurable. Sharing: The language should support mechanisms such as inheritance so that code, structure, and values need not be replicated. Classes: Objects can be organized into classes to permit more effective management of resources, as for example in a very large database. Classes should be first-class objects and hence it should be possible to create classes dynamically. The Rosette language is a high-level language that is translated into a base language that directly expresses concurrent computations in terms of the semantics of the Actor model. The Rosette language extends the base language with data abstraction facilities and a library of classes, and is used to implement the non-built-in actors of the interface layer, components of the system environment, and applications. Using data abstraction extensions to the base language, the Rosette language organizes actors into classes according to common sets of behaviors and local state. Inheritance is used as a means of sharing code and structure that is common among classes. There is considerable evidence, for example [LaLonde 1986] and [Snyder 1987], that a robust class system should support separate hierarchies that represent what is modeled by a class and how some class of objects are actually implemented. Our approach is to use three different kinds of classes to organize the various kinds of actors in a system and information about these actors: abstract classes specify observable requests, responses, and actions; representation classes specify resource management characteristics of implementations; and behavior classes contain the actual implementations. Associated with an abstract class is the set of representations that are available to implement the particular abstraction. Each representation is associated with the behavior class that contains the corresponding implementation. The power of this separation is that each of the three kinds of class may be related to others in a class hierarchy. This means that the relationships between abstract classes are not forced to have the same structure as the relationships among implementations. Sharing via inheritance among behavior classes is related to engineering concerns; relations among abstract classes are dictated by external/observable behavior. As an example, an abstract class might specify the operations available over real-matrices. There are several ways of representing a matrix as a community of actors, and each of these would be specified with appropriate representation and behavior classes. There is a well-defined abstract hierarchy of matrices such as invertible, positive, etc. These abstract kinds of matrices are independent of the various implementations, which may be chosen according to application and hardware resource constraints. The Rosette language embodies a reflective model of the interface layer that is similar to that used in ABCL/R, [Watanabe and Yonezawa 1988]. This model is termed the execution model and provides an abstract implementation of an actor in terms of other resource actors. There are three classes of resource actors in the model: container, processor, and mailbox. The container class of resource actor models the storage local to an actor, and is very similar to a frame or unit in knowledge-based systems. A container is a set of slots, where each slot is an association of a key and a value. Both keys and values are just other actors. Slots can be added or deleted from a container. These actions model allocation and deallocation of storage. The basic operation performed by processor resource actors is the execution of a message, which defines how to determine the method for responding to a message. An evaluation context is then created and the method is applied to the context and the message. The third class of resource actors implements the communications interface to an actor. The main function of a mailbox is the buffering of incoming messages until they are requested by a processor. Mailboxes respond to requests that signify message arrivals at the actor and to requests which are used by processors to accept messages. Object-oriented interfaces for each of the three kinds of resource actors are defined and organized in a class hierarchy. For any actor, any combination of these three resource actors may be built-in or not. The possibility of defining new resource actors within the context of the execution model makes the Rosette architecture extensible allowing new forms of monitoring and control to be defined. Resource management policies are defined in terms of interactions among the resource actors of an application's actor community.