Chapter 10 The runtime systems (jcrun)
This chapter describes the usage of join-calculus runtimes. A runtime
is a command that executes bytecode files produced by the linking
phase of the jcc compiler. By default, the standard runtime jcrun
is used. In case additional external primitives and values are used in
the bytecode file, other runtimes are called for.
10.1 Overview
The runtime support for the join-calculus comes as a family of
Objective Caml executables (called runtimes in this chapter).
This variety comes from three reasons:
-
specific runtimes are needed for each machine
architecture.
- runtimes comes in two Objective Caml flavors: optimized
native-code (faster at run-time) or bytecode (faster at compile-time).
- external primitives and values used in join-calculus programs
must be statically compiled and linked to the runtime. As a result, a
custom runtime is generated and used for each set of externals.
All of these runtimes can work in concert as part of a distributed
computation, provided that the running join-calculus programs
(including mobile code) never use missing externals.
The ``jcrun'' command is the runtime that is used by default; it
provides all the externals of the standard library.
10.2 Usage
All runtimes have the same usage and options:
jcrun bytecode-executable options
The main argument is taken to be the name of the file
containing the executable bytecode.
As described in chapter 7, the bytecode executable files
produced by the jcc command are usually self-executable, and manage
to launch a compatible runtime on themselves automatically. That is,
assuming ``plain.out'' and ``fancy.out'' are bytecode executables built from
the commands
jcc plain.j -o plain.out
jcc fancy.j -jcrun myruntime -o fancy.out
the commands
plain.out options
fancy.out options
are respectively equivalent to
jcrun plain.out options
myruntime fancy.out options
Notice that in case of distributed computation, it may be necessary to
execute a bytecode file using another, richer runtime, such that it
may host incoming mobile code that require more external primitives.
10.3 Runtime options
The runtime can run locally or participate to a distributed
computation. In that case, it can run as a nameserver client or as a
nameserver server.
- -l (default)
- When set, the runtime executes its bytecode
locally and does not attempt to communicate with other runtimes. The
nameserver primitives are not available. The runtime terminates when
its runqueue become empty.
- -c
- When set, the runtime executes its bytecode, and also
initializes messaging in client-mode. The nameserver primitives are
available. The first time they are used, a connection is attempted to
another runtime in server-mode. Unless halted, the runtime never
terminates.
- -s
- When set, the runtime executes its bytecode, and also
initializes messaging in server-mode. The nameserver primitives are
locally available, and can be accessed from other runtime in
client-mode that request a connection. Unless halted, the runtime
never terminates.
The IP address and port number of the runtime in server-mode (used for
the initial connection) may be specified using the following options:
- -port <number>
- -host <address>
By default, these values are respectively taken from the environment variable
JCHOST and JCPORT when defined, or as the constants localhost and 12360.
The other options are for internal use only.
10.4 Runtime errors
This section describes and explains the error messages that can occur
at run-time. A typical error message is of the form
-
runtime program: description (from originator)
-
where runtime is the name of the running bytecode interpreter,
program is the name of the join-calculus bytecode supplied as
argument, description is the error report itself, and originator is the portion of the runtime code which raised the
error (which is mostly used for debugging it).
10.4.1 fatal errors
Once a particular runtime reports an error, the distributed
computation as a whole has failed. As it stands, only this runtime
actually terminates, while other runtimes that are involved in the
computation may continue. The subsequent behavior of these remaining
runtimes is not specified.
command-line and options
- runtime: no bytecode executable filename
-
When running a bytecode interpreter, an executable
bytecode file must be provided for local execution.
- runtime: filename: No such file or directory
-
When running a bytecode interpreter, the executable bytecode file filename given as argument does not exist.
- exec: filename: not found
-
When running a self-executable bytecode file, its default runtime
interpreter filename could not be found in the current path. In
case the program does not use external libraries, filename is
jcrun and this error indicates that the Join-Calculus has not been
property installed on this machine.
- runtime: filename is not a bytecode executable file
-
The file that the interpreter is trying to execute is not a valid
executable bytecode file. Probably it has been truncated or mangled
since created. Erase and rebuild it.
- runtime: cannot execute filename: external mismatch
-
The selected interpreter has not been linked with the external
libraries written in Objective Caml that are called from the
executable bytecode filename. This usually indicates the bad
choice of an interpreter on the command line. When running a
self-executable bytecode, this is probably because the default
interpreter is not up-to-date. Clear and recompile.
- runtime: too many command-line options
-
The options on the command line are not compatible; this may be due to
inconsistent mode flags -l -s -c, several bytecode file names, or
several values for -host and -port)
local errors
-
runtime: break
-
The runtime was terminated by an interruption signal.
- runtime: circular migration
-
A location attempted to migrate inside of one of own its sub-location.
Your program should not allow such things.
- runtime: failwith message
-
The runtime was terminated by a join-calculus message
failwith("message"). This may be a normal termination, for
instance as a result of using the shutdown module.
distributed support
-
runtime: could not start server
-
The runtime could not set-up its connection socket. Check its
address.
- runtime: cannot import mobile code segment ``segment-name'': external mismatch
-
The running interpreter has not been statically linked with the
external libraries that are required in the code of an incoming mobile
agent. Values defined in Objective Caml are not mobile; rather, their
local copy is used when available. When the interpreter does not
provide them, this is detected at the first attempt to migrate an
offending migration. Maybe the program was compiled without the
correct -jcrun option, or can cause unexpected migrations.
- runtime: cannot export this kind of external value
-
Due to a message or a migration, the interpreter must send an external
value to another runtime, but this value is not portable
(cf. 3.2).
- runtime: unknown host: address
-
- runtime: unknown service: port
-
The runtime tried to establish a connection, either to its name server
or to another runtime (e.g. to send messages on names that were
received from some third party). In the first case, this is probably
due to bad parameters address and port on the command
line. Otherwise, there is a problem with the network (connectivity,
DNS,...).
- runtime: bind: address already in use
-
The runtime tried to set-up the name-server on some port that is used
(or was recently used) by another process. Check for other runtimes on
the machine, or use another port number.
10.4.2 warnings
The following problems are reported on standard error , but do not
cause the runtime to terminate. This may change.
- Uncaught exception: exception-constructor
-
- runtime: exception raised during external call ``ocaml-expression''
-
The Join-Calculus program (or its libraries) has tried to evaluate an
external expression ocaml-expression defined in Objective Caml.
During this evaluation, the exception named exception-constructor has been raised at some point and was never
caught. This error is not fatal; it only causes this warning message
to be locally issued, and the faulty evaluation never to complete.
Beware, some bad exception such as Division_by_zero may not be
intercepted by the native interpreters and cause a fatal error.
Cf. documentation of Objective Caml for an explanation of particular
exceptions and a discussion of bad exceptions in native-code.
NB: as long as there are no exceptions in Join-Calculus, it may be
better to always consider external exceptions as a fatal errors.
- Could not establish connection to address:port (still trying): error-description
-
The runtime tried to establish a connection but its system calls
returned an error; this may be a transient problem (e.g. the server is
not running yet) or a more serious one. In doubt, the computation goes
on, and other connection attempts will occur later on.
- warning: name ``string'' not registered yet
- The name
server received a ns.lookup request with key string, but found
no entry in its table. This is usually due to a race-condition with
another process that registers this entry; in that case, the
computation will resume as soon as string gets registered. This
may also be due to an inconsistent use of the keys, leading to a
deadlock.
- warning: name ``string'' already registered (left unchanged)
- The name server received a ns.register request with key
string, and there is already a value in the table. This
deadlocks the call to ns.register and let the name table unchanged;
ns.lookup still returns the first value.
10.4.3 bugs
All other errors are bugs, either in the runtime system or in the
documentation. Please report them.