ChorusOS 5.0 Application Developer's Guide

Spawning an Actor

The ChorusOS operating system enables an actor to spawn another actor dynamically from a binary file. This spawned actor may be either a supervisor or a user actor. This service is similar to the exec() UNIX system call:

#include <cx/afexec.h>
int afexecve (const char* path,
              KnCap* actorCap,
              const AcParam* param,
              char* const* argv,
              char* const* envp); 

This service creates a new actor whose capability is returned by the system at the location pointed to by the actorCap argument. The actor created executes the binary file stored in the file named path. If the file named path does not exist, afexec() will attempt to find path.gz. The main thread of this actor runs the main routine of the program. This thread has the same scheduling attributes and stack size as an actor loaded using the arun command.

argv and envp are pointers to the array of arguments and environments that will be received by the newly created actor.

There are several variants of the afexec(2K) service that are similar to the UNIX exec() call variants. If successful, all afexec(2K) routines return the actor identifier of the newly created actor. Otherwise, they return -1, and the error code is returned in the errno variable.

In most instances, you do not need to use the afexec(2K) service. Instead, simply execute the actor manually, or include the actor as part of the system image. However, for convenience, some examples within this chapter do use this service.

The following example illustrates the use of the afexecve(2K) service call. In this example:


Note -

This example assumes that argv[0] is valid, and that the actor is linked with the os/lib/libc.a library because the library is common to both user and supervisor actors. Referencing argv[0] without checking if argc is greater than zero can cause the actor to create an exception and be deleted.



Example 3-4 Spawning an Actor

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <cx/afexec.h>

AcParam param;
char*   spawnedArgs[3];
char*   tagPtr = "Welcome newly created actor!";

int main(int argc, char** argv, char**envp)
{
  KnCap        spawnedCap;
  int          res;

  if (argc == 1) {
        /*
         * This is the first actor (or spawning actor):
         *   Binary file used to load this actor is passed
         *   by "arun" as argv[0],
         * 
         *   Set an argument in order to enable the second
         *   actor to know it is the second one.
         */

    param.acFlags = AFX_ANY_SPACE;

    spawnedArgs[0] = argv[0];
    spawnedArgs[1] = tagPtr;
    spawnedArgs[2] = NULL;
 
        /*
         * Other fields are implicitly set to NULL, as 
         * param is allocated within the bss of the program.
         */
    res = afexecve(argv[0], &spawnedCap, &param, spawnedArgs, envp);

    if (res == -1) {
      printf("Cannot spawn second actor, error %d\n", errno);
      exit(1);
    }
    printf("I succeeded creating actor whose pid is %d\n", res);

  } else {

        /*
         * This is the spawned actor:
         * Check the number of args,
         * Print args,
         * Exit
         */
    if ((argc == 2) && (strcmp(tagPtr, argv[1]) == 0)) {

        /*
				* This is really the spawned actor.
         */
	printf("My spawning actor passed me this argument: %s\n", argv[1]);
    } else {
	    printf("You ran %s with an argument, you should not!\n", argv[0]);
	    exit(1);
    }

  }
  return 0; 
}