HELP ACTOR J L Cunningham 1982
Revised John Gibson Aug 93
------------------------------ NOTE ------------------------------------
From Version 14.5, a change has been made to LIB * ACTOR which makes
it incompatible with previous versions: the new version has all the
exported (i.e. top-level) identifiers prefixed by "actor_". In
addition, LIB EVENT has been replaced by LIB * ACTOR_EVENT, with
a similar renaming of identifiers.
Thus you should load these facilities with 'uses actor;' or 'uses
actor_event;'.
------------------------------------------------------------------------
The library ACTOR uses the Pop-11 *PROCESS facility to implement basic
procedures for a discrete event simulation package. This can be used for
multi-tasking.
In addition, LIB * ACTOR_EVENT provides an event-handler and associated
procedures, which are described in this help file.
The main user procedures and variables and the terminology used are
described now; the end of this file contains a list of all the other
important global variables and procedures, with a brief description of
what they do.
ACTIVE At any one moment of real time, only one ACTOR program can
actually be running (since Pop is a serial language.) Here,
though, all ACTORs which may become CURRENT without the
intervention of another ACTOR are referred to as ACTIVE
(this is not quite standard usage). Basically the ACTIVE
ACTORs are those that are WAITING plus the CURRENT ACTOR.
The other actors (those SLEEPING or waiting for an EVENT
(see ACTOR_WAITEVENT) or waiting to ACTOR_RECEIVE a MESSAGE,
are not ACTIVE.
ACTOR When a simulation is started, there will be a number of
independent (but possibly communicating) "programs" running,
and possibly multiple copies of the same program. These
entities are referred to as ACTORS. (An actor is actually
represented as a RECORD (see HELP *DEFCLASS), one of whose
components is a pop PROCESS.) In order for actors to
interact, they each have a name, (see ACTOR_MYNAME) which
should be unique to that actor.
actor_apocalypse();
This procedure is run as the final EVENT of a simulation at
time ACTOR_AEONS. It can be redefined, but there is not much
point unless you don't like the message it prints.
actor_askactor(<name>,<question>) -> <answer>;
Runs the named actor's ACTOR_ANSWER procedure, to obtain the
answer to <question>, but in the context of the <name>d
actor. So, e.g., it is possible to ask for the values of
variables local to the <name>d actor.
actor_answer(<question>) -> <answer>;
This procedure, which should normally be local to individual
actors, will be run if the actor is asked a <question> by
another actor. It should NOT call ACTOR_DIE, ACTOR_WAIT or
ACTOR_SLEEP and it will be unable to ACTOR_ASKACTOR,
ACTOR_SEND or ACTOR_KILL the actor asking the <question>.
Since ACTOR_RECEIVE may call ACTOR_SLEEP, it should not call
ACTOR_RECEIVE unless it knows that there will be a message
available (see ACTOR_MYMESSAGEQUEUE). The default value of
this procedure is in the global value of ACTOR_ANSWER and
always returns the answer 'Dont know', unless the QUESTION
is a list whose first element is the word "popval", in which
case the rest of the list is *POPVALed to obtain the answer
(this is very useful for debugging, see DEBUG.) While
running ACTOR_ANSWER, all local variables will be as they
were when the actor answering the question became
non-CURRENT. Also, CURRENT temporarily becomes the answerer.
actor_aeons
This constant corresponds to the end of time. It is a large
number. If an ACTOR does
actor_wait(actor_aeons);
it is likely not to be resumed. This is much like
ACTOR_SLEEP, but it cannot be woken (but it can still
ACTOR_ANSWER questions, cf ACTOR_DIE).
CURRENT The actor currently running is described as CURRENT.
DEBUG If the pop procedure *POPREADY is included as one of the
actors at ACTOR_GENESIS, then it can be used for debugging
purposes. When the POPREADY becomes CURRENT it will prompt
the terminal as normal. A call of ACTOR_WAIT at this time
will cause the POPREADY to wait the appropriate amount of
simulated time before prompting again. Calls of
ACTOR_ASKACTOR, ACTOR_KILL, ACTOR_NEWACTOR etc. can be used.
actor_die();
The current actor dies. An actor also dies if the procedure
which is called when the actor starts returns normally. (If
ACTOR_DIE is used the actor could be reincarnated if it had
been saved somewhere; however if the current actor's
procedure returns normally, it is very dead and cannot be
reincarnated.)
actor_diewhen(<event>);
This procedure is in LIB ACTOR_EVENT, and can only be used
when there is an ACTOR_EVENTHANDLER. It causes the actor
which calls it to be KILLed when the named <event> (or one
of the events in the list - cf ACTOR_WAITEVENT) occurs.
EVENT This word has two meanings. Firstly, every time anything
occurs, that is an event. Thus, if an actor has WAITed for a
period (of simulated time), and then it does something, that
something is an event (cf APOCALYPSE). However, there is a
more restricted meaning, reserved for particular events
notified to the ACTOR_EVENTHANDLER.
actor_event(<eventname>,<message>);
This procedure is in LIB ACTOR_EVENT. If the event
<eventname> has occurred then this procedure should be
called, and the ACTOR_EVENTHANDLER will send the <message>
to any other actors waiting for the event <eventname> (see
ACTOR_WAITEVENT).
actor_eventhandler();
This procedure is in LIB ACTOR_EVENT. If the procedures
ACTOR_EVENT and ACTOR_WAITEVENT are to be used, then the
word "actor_eventhandler" should be included in the
ACTOR_GENESIS argument, so that it will be used for an actor
called "eventhandler1".
actor_exists(<name>);
Returns true if <name> is NAMEOF an existing actor,
excluding the current actor. (i.e. in WAITING or SLEEPING).
actor_genesis(<initial>);
This procedure is used to start a simulation. <initial>
should be a list of argument lists for ACTOR_NEWACTOR, but
if the simplest form of call to ACTOR_NEWACTOR is used (i.e.
with a single argument, a procedure), then the name of the
procedure (i.e. a Pop variable whose VALOF is the procedure)
not enclosed in list brackets may be used, and may also be
preceded by an integer repetition count. (In this case,
*GENSYM is reset to 1 for that sequence of
names.) Integers occurring elsewhere in the INITIAL list are
ignored.
actor_gpo(<name>,<message>,<delay>);
Defined as
actor_newactor(send,[%name,message%],delay)
This clones the ACTOR_SEND procedure to send the message
after a delay. The result when the ACTOR_SEND clone returns
will be erased as it dies irrevocably.
actor_kill(<name>);
Removes an actor whose NAMEOF is <name> from WAITING or
SLEEPING; the actor could be reincarnated (cf ACTOR_DIE).
MESSAGE A MESSAGE can be any Pop data structure. See ACTOR_SEND,
ACTOR_RECEIVE, ACTOR_GPO, ACTOR_EVENT and ACTOR_WAITEVENT.
Cf also ACTOR_ASKACTOR and ACTOR_ANSWER.
actor_mymessagequeue
This is a queue (local to each actor) of messages for the
current actor to ACTOR_RECEIVE (see HELP *NEWQUEUE). The
number of messages waiting for the current actor can be
found by
queuelength(actor_mymessagequeue) -> <length>;
The MESSAGEQUEUE is not accessed via this variable name by
the simulation package, so altering it will have no effect
(although altering the queue which is its initial value
will have an effect).
actor_myname
This is a variable which is local to each actor. Its initial
value for any actor is the name of that actor. It is useful
to know this when there are many actors which are copies of
the same procedure, so that MESSAGES may include a NAME to
reply to.
actor_myparent
This is a variable which is local to each actor. It's intial
value for each actor is the NAME of the actor which created
that actor, or "eldest" if the actor has no parent (i.e. was
created at ACTOR_GENESIS).
NAME To distinguish ACTORs, they each have a name, which should
be unique. See ACTOR_MYNAME.
actor_newactor(<procedure>[,<actorname>][,<arglist>][,<delay>]);
ACTOR_NEWACTOR creates a new actor. There are a variety of
calling formats, summarised above; the arguments in square
brackets are optional, but if present must appear in the
order illustrated. <procedure> is the procedure to be run
for that actor. The first optional argument is the name of
the actor (a word). If this is omitted, a new name will be
generated from the *PDPROPS of the procedure, using
*GENSYM). The second optional argument is a list
of arguments for the procedure, and the third an optional
simulation delay before the new actor starts. The list of
arguments must be a Pop list if present. For an example, see
ACTOR_GPO.
actor_receive() -> <message>;
Gets the next message for the current actor. Messages are
kept in a queue (see HELP *NEWQUEUE). Messages may be put in
the queue by being SENDed. If the queue is empty, then the
current actor becomes SLEEPING until there is something in
the queue. See also ACTOR_SEND, ACTOR_GPO,
ACTOR_MYMESSAGEQUEUE.
actor_say(<something>);
Prints <something> on a new line, preceded by the NAMEOF the
CURRENT actor, and also the time if ACTOR_SAYTIME is TRUE.
actor_saytime
Global variable. If non-false then ACTOR_SAY will print the
simulated time.
actor_send(<name>,<message>) -> <boolean>;
Adds <message> to <name>d actor's queue of messages, and
WAKEs actor. ACTOR_SEND returns TRUE if <message> has been
sent successfully, otherwise FALSE (e.g. if no actor exists
with the specified <name>). An actor cannot ACTOR_SEND a
message to itself. See also ACTOR_RECEIVE,
ACTOR_MYMESSAGEQUEUE, ACTOR_GPO.
actor_simtime
The value of this variable is the current simulation time;
it should not be explicitly altered by actors. (Really, I
should make it a procedure without an updater, but I trust
you.)
actor_sleep();
The current actor falls asleep, i.e. it becomes inactive. It
can become active again if WAKEd - cf ACTOR_DIE. Actors
which are asleep are stored in a variable called SLEEPING.
actor_wait(<duration>);
The current ACTOR waits, i.e. is suspended, for simulated
delay given by <duration>. Such actors are stored in a
variable called WAITING.
actor_wait(0);
will not change the simulated time, but if any other ACTORs
are WAITING to run at this simulated time, then the current
actor will be suspended. If more than one ACTOR is due to
become CURRENT at the same simulated time, then the one that
began waiting at the earliest real time becomes CURRENT.
actor_wake(<name>);
Wake, i.e. make ACTIVE, the actor whose name is <name> (it
will become CURRENT at the present simulated time, after any
other ACTORs at this time). ACTOR_WAKE has no effect if
there is no such actor in SLEEPING.
actor_waitevent(<event>) -> <message>;
This procedure is in LIB ACTOR_EVENT. When it is called, it
tells the ACTOR_EVENTHANDLER that the current actor is now
waiting for the <event> (a word) or alternatively any of the
events in <event> (a list of words). The procedure returns
with the <message> associated with the <event> when it
occurs.
-----------------------------------------------------------------------
Some procedures and variables used internally to the simulation package,
but which might be useful to hackers. They are in section $-actor.
current current actor
waiting the actors active but not current
sleeping the actors sleeping
find(<name>,<chain>);
might be useful to a hacker, but look at the source code
nameof(<actor>);
waketime(<actor>);
the time a waiting actor is due to become current
nextactor(<actor>);
link to next actor when in a chain
processof(<actor>);
might be useful to resume simulation, e.g. by
resume(0,processof(<current>))
practor(<actor>);
used to print an actor or chain of actors
schedule(<time>,<actor>);
adds <actor> to WAITING with <time> as its waketime
parentof(<actor>);
the NAMEOF the actor which created the <actor> (which is
the argument to PARENTOF), or else "eldest" for actors
created at ACTOR_GENESIS
messagequeue(<actor>);
The queue used for storing <actor>'s unprocessed messages
returnanswer(<question>);
This procedure is part of the question answering
mechanism, and should not be called by actors.
See also
HELP *AUTOLOAD - on the automatic compilation of library files
HELP *NEWQUEUE - library procedure for creating queues
HELP *PROCESS - summary of the Pop-11 PROCESS facility
HELP *POPVAL - evaluates list items as Pop-11 code
HELP *POPREADY - invokes compiler recursively. Useful for interrupts
SHOWLIB *ACTOR - for the program code
--- C.all/help/actor
--- Copyright University of Sussex 1992. All rights reserved. ----------Author: J L Cunningham 1982