ChorusOS 4.0 Introduction

Actor Definition

An actor is the unit of loading for an application. It serves also as the encapsulation unit to associate all system resources used by the application and the threads running within the actor. Threads, memory regions and communication end-points are some examples of these resources. They will be covered in more detail throughout this chapter. All system resources used by an actor are freed upon actor termination.

Some resources, known as anonymous resources, are not bound to a given actor. They must be freed explicitly when they are no longer required. Examples of anonymous resources are physical memory, reserved ranges of virtual memory, and interrupt vectors.

The ChorusOS operating system is dedicated to the development and execution of applications in a host-target environment where applications are developed, compiled, linked and stored on a host system and then executed on a target machine where the ChorusOS operating system is running. When properly configured, the ChorusOS operating system offers convenient support for writing and running distributed applications.

Within the ChorusOS operating system environment, an application is a program or a set of programs usually written in C or C++. In order to run, an application must be loaded on the ChorusOS runtime system. The normal unit of loading is called an actor and is loaded from a binary file located on the host machine. As with any program written in C or C++, an actor has a standard entry point:

int main()
 {
     /* A rather familiar starting point, isn't it? */
 }

The code of this type of application will be executed by a main thread which is automatically created at load time by the system. The ChorusOS operating system provides means to dynamically create and run more than one thread in an actor. It also offers services which enable these actors, whether single-threaded or multithreaded, to cooperate, synchronize, exchange data either locally or remotely, or get control of hardware events, for example. These topics will be covered step by step throughout this chapter.

An actor may be of two types: it may be either a supervisor actor or a user actor. This information defines the nature of the actor address space. User actors have separate and protected address spaces so that they cannot overwrite each other's address spaces. Supervisor actors use a common but partitioned address space. Depending on the underlying hardware, a supervisor actor can execute privileged hardware instructions (such as initiating an I/O), while a user actor cannot.


Note -

In flat memory, supervisor and user actors share the same address space and there is no address protection mechanism.


Binary files from which actors are loaded may also be of two kinds: either absolute or relocatable. An absolute binary is a binary where all addresses have been resolved and computed from a well-known and fixed basis which may not be changed. A relocatable file is a binary which may be loaded or relocated at any address.

Both user and supervisor actors can be loaded either from absolute or relocatable binary files. However, common practice is to load them from relocatable files to avoid a static partitioning of the common supervisor address space, and to allow the loading of user actors into this space in the flat memory model. This is covered in more detail in "User and Supervisor Actors".

Naming Actors

Every actor, whether it is a boot actor or a dynamically loaded actor, is uniquely identified by an actor capability. When several ChorusOS operating systems are cooperating together over a network in a distributed system, these capabilities are always unique through space and time. An actor may identify itself with a predefined capability:

K_MYACTOR.

In addition, an actor created from the POSIX personality is identified by a local actor identifier. This actor identifier is displayed on the console as the result of the arun command. It may be used from the console as a parameter of the akill command.


% rsh target arun hello
Started aid = 13

% 

In this example, target is the name of your target.

User and Supervisor Actors

There are two main kinds of actors which may be run within the ChorusOS operating system environment: user actors and supervisor actors. A user actor runs in its own private address space so that if it attempts to reference a memory address which is not valid in its address space, it will encounter a fault and, by default, will be automatically deleted by the ChorusOS operating system.

Supervisor actors do not have their own fully contained private address space. Instead, they share a common supervisor address space, which means that an ill-behaved supervisor actor can access, and potentially corrupt, memory belonging to another supervisor actor. The common supervisor address space is partitioned between the ChorusOS operating system components and all supervisor actors.

As supervisor actors reside in the same address space, there is no memory context switch to perform when execution switches from one supervisor actor to another. Thus, supervisor actors provide a trade-off between protection and performance. Moreover, they allow execution of privileged hardware instructions and so enable device drivers, for example, to be loaded and run as supervisor actors.

On most platforms, the address space is split into two ranges: one reserved for user actors and one for supervisor actors (see Figure 5-1). As user actor address spaces are independent and overlap each other, the address where these actors run is usually the same, even if the actors are loaded from relocatable binaries. On the other hand, available address ranges in supervisor address space may vary depending on how many and which supervisor actors are currently running. Since the ChorusOS operating system is able to find a slot dynamically within the supervisor address space to load the actor, the user does not need to be aware of the partitioning of the supervisor address space: using relocatable binary files will suffice.

Figure 5-1 User and Supervisor Address Spaces

Graphic

The ChorusOS operating system offers a way to determine dynamically whether a program is currently running as a user or a supervisor actor:

#include <chorus.h> 

int actorPrivilege(KnCap* actorCap,   
        KnActorPrivilege* old,
        KnActorPrivilege* new);

If actorCap is set to the name of an actor, you can use this API to obtain the privilege of the named actor. If actorCap is set to the predefined value K_MYACTOR, you can obtain the privilege of the current actor. This call may also be used to dynamically change the privilege of an actor from user to supervisor or vice versa.

The following example illustrates a usage of the actorPrivilege() service. It is a small program that retrieves its privilege, without trying to modify it. It prints one message if the actor is running as a user actor, and another if it is running as a supervisor actor.


Example 5-1 Getting Actor Privilege

#include <stdio.h>
#include <chorus.h>

int main(int argc, char** argv, char** envp)
{
   KnActorPrivilege    actorP;
   int                 res;

       /* Get actor's privilege */
   res = actorPrivilege(K_MYACTOR, &actorP, NULL);
   if (res != K_OK) {
      printf("Cannot get the privilege of the actor, error %d\n", res);
      exit(1);
   }

   if (actorP == K_SUPACTOR) {
      printf("This actor is running as a supervisor actor\n");
   } else {
      printf("This actor is running as a user actor\n");
   }

   exit(0);
}


KnActorPrivilege is the type defined by the ChorusOS operating system to handle the type of an actor. The defined values for the actor type are: