[comp.sources.amiga] v90i248: odin.library - linda-like interprocess communications library, Part01/01

amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (09/04/90)

Submitted-by: "Peter \rb{k" <poe@daimi.dk>
Posting-number: Volume 90, Issue 248
Archive-name: libraries/odinlib-1.11/part01

This is release 1 of odin.library, which provides for a Linda-like
way of interprocess-communication, plus some extended support for
multiprogramming on the Amiga. Included in the zoo-file are docs.
and example-programs for Aztec-C and PDC 3.33 along with glue-code
for the C-language interface. The gluecode should work with
Lattice as well.

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  Makefile PDCMakefile README odin.doc odin.h odin.i odin.uu
#   odin_lib.fd odindemo1.c odindemo2.c odinglue.asm odintest.c
# Wrapped by tadguy@abcfd20 on Mon Sep  3 18:54:37 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(664 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Aztec-makefile
X#
X
XCCFLAGS =
XLINKOBJS = odinglue.o
XLIBS = -lc
XTMPDIR = RAM:
X
X.c.o:
X	copy $*.c $(TMPDIR)
X	cc $(CCFLAGS) -o $(TMPDIR)$@ $(TMPDIR)$*.c
X
Xall:	odindemo1 odindemo2 odintest
X
Xodindemo1:	odindemo1.o odinglue.o
X	ln -o $(TMPDIR)$@ $(TMPDIR)$@.o $(LINKOBJS) $(LIBS)
X	copy $(TMPDIR)$@ $@
X
Xodindemo2:	odindemo2.o odinglue.o
X	ln -o $(TMPDIR)$@ $(TMPDIR)$@.o $(LINKOBJS) $(LIBS)
X	copy $(TMPDIR)$@ $@
X
Xodinglue.o:	odinglue.asm
X	as odinglue
X
X#fraktal:	fraktal.o odinglue.o
X#	ln -o $(TMPDIR)$@ $(TMPDIR)$@.o $(LINKOBJS) $(LIBS) -lm
X#	copy $(TMPDIR)$@ $@
X
Xodintest:	odintest.o odinglue.o
X	ln -o $(TMPDIR)$@ $(TMPDIR)$@.o $(LINKOBJS) $(LIBS)
X	copy $(TMPDIR)$@ $@
X
X
END_OF_FILE
if test 664 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'PDCMakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'PDCMakefile'\"
else
echo shar: Extracting \"'PDCMakefile'\" \(174 characters\)
sed "s/^X//" >'PDCMakefile' <<'END_OF_FILE'
X#
X# Makefile for PDC 3.33
X#
X
XCCFLAGS = -DANSI
X
Xodintest:	odintest.c odinglue.o
X	ccx $(CCFLAGS) -o $@ odintest.c odinglue.o
X
Xodinglue.o:	odinglue.asm
X	a68k -o$@ odinglue.asm
X
END_OF_FILE
if test 174 -ne `wc -c <'PDCMakefile'`; then
    echo shar: \"'PDCMakefile'\" unpacked with wrong size!
fi
# end of 'PDCMakefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1914 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XREADME for odin.library V1.11, 13-jul-90, Release 1
X
XAUTHOR: Peter Oerbaek.
XCOPYRIGHT: Peter Oerbaek 1990, All rights reserved.
X
X   Odin.library provides yet another way of interprocess-communication and
Xmultitasking support for the Amiga. The functions are inspired by Linda,
Xan add-on language for C and other languages, which provides a simple
Xand powerful support for IPC.
X
X   Odin.library is FreeWare. That is, permission is granted to freely
Xdistribute and copy it, put it on FishDisks and other PD disks.
XNo charge larger than US $6.00 must be taken for this piece of sotware.
XYou can also legally include it with commercial software, as long as this 
Xnotice is included along with it.
X
XThe contents of Release 1:
X
Xodin.library   The AmigaDos library binary. Put this in your LIBS:
X               directory.
X
Xodin.doc       Documentation and function description.
X
Xodin_lib.fd    Standard .fd file, to generate eg. AmigaBASIC interface
X               Could be used to generate Lattice #pragma's too, I think.
X
Xodinglue.asm   Gluecode to interface with Aztec-C, and PDC 3.33
X               Assembles OK under Aztec 'as' and A68K 2.6
X               Assemble with A68K for use with Lattice and Blink
X
Xodin.h         C header with function prototypes for Aztec and ANSI stuff
X
Xodin.i         Includefile for Assem/A68K
X
XMakefile       For generating the examples with Aztec C 3.40A
X
XPDCMakefile    Makefile for odintest.c for PDC 3.33
X
XNB. the examples below expect odin.library to be in RAM:
X
Xodintest.c     Test of all functions in odin.library
X
Xodindemo1.c    Simple demo
X
Xodindemo2.c    Another simple demo
X
X
X   Questions, bug reports, comments etc. should be e-mailed to me at the 
Xaddress below. Enjoy.
X
XPS. I would like to know if this works correctly on the A3000, so please
X    report if you are so lucky to have one.
X
XInternet: poe@daimi.dk
XUUCP:     ...!uunet!mcsun!sunic!dkuug!daimi!poe
X
X  - Peter.
END_OF_FILE
if test 1914 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'odin.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odin.doc'\"
else
echo shar: Extracting \"'odin.doc'\" \(11403 characters\)
sed "s/^X//" >'odin.doc' <<'END_OF_FILE'
Xodin.doc, version 1.11, 13-Jul-90, Release 1
XCreated 3-Jul-90 by Peter Oerbaek
X
X                      Documentation for odin.library.
X
X
X   The main intention of this library is to provide an easier and more
Xelaborate support for the multitasking capabilities of the Amiga. The func-
Xtions are inspired by Linda, an extension-language to C and other
Xlanguages, which provides a simple yet efficient multitasking/
Xmultiprocessing API.
X
X   The central concept in odin.library is that of the envelope. An envelope
Xis used to pass information between processes, and they are used to hold
Xinformation residing in e-space. In C an envelope is a structure that
Xbegins with the Envelope structure defined in odin.h.
X
X   There's no restrictions on the contents of an envelope, the contents being
Xwhatever comes after the Envelope-structure. The contents need not be
Xcontigous in memory. You can specify a C-function to serve as a copying-
Xroutine for each envelope.
X
X   The e-space is an abstact storage containing envelopes and their contents.
XEnvelopes are identified by a name, ie. a null-terminated ASCII string.
XEnvelopes can be put into and retrieved from e-space via the name.
XE-space can contain many envelopes with the same name. Envelopes with the
Xsame name will be retrieved in the same order as they have been inserted
Xinto e-space, forming a queue.
X
X   Two envelopes match if their names are equal.
X
X   To prevent two different programs from unintentional interference with
Xeach others envelopes a naming convention should be applied. My suggestion
Xis to name envelopes intended for private use within some internal task
Xlike this: "<ProgramName>:<envelopename>" (this is not used in my
Xexamples...). 
X
X   Functions for general envelope-management are: CreateEnvelope(),
XInitEnvelope() and DisposeEnvelope(). To put envelopes into e-space use:
XOut(),CopyOut() or OutEmptyEnvelope(). You can wait for an envelope to
Xappear in e-space with: In(), Rd() and AwaitNamedEnvelope(). You can also
Xpoll for the existence of envelopes in e-space with: Inp(), Rdp() and
XPollNamedEnvelope().
X
X   New tasks and processes can be launched by the Eval() function. Eval()
Xprovides a simple, yet powerful way to transfer arguments to the new task/
Xprocess, and a way to determine when the new task/process is finished.
X
X   There are also two lower-level functions for creating tasks/processes:
XStartTask() and StartProcess().
X
X------------------------------------------------------------------------
X                             Function summary
X                             -----------------
X------------------------------------------------------------------------
X
XEnvelope *InitEnvelope(env,name,len,copyfunc)
X   D0                   A1  A0   D0   A2
XEnvelope *env;
Xchar     *name;
XULONG    len;
XEnvelope *(*copyfunc)();
X
X   Initializes env with the name 'name', length of envelope+contents in bytes:
X   'len', and sets the copyfunc for the envelope to copyfunc.
X   The Eval() function (e_proc) is not touched.
X   Returns the newly initialized envelope.
X   Use the macro NoCopyFunc to specify that the e_copyfunc should be init-
X   ialized to NULL.
X
X   SEE ALSO
X      CreateEnvelope(), Rd().
X
X------------------------------------------------------------------------
X
XEnvelope *In(env)
X   D0         A1
XEnvelope *env;
X
X   Tries to extract an envelope from e-space with a matching name. If no
X   envelopes in e-space matches, the caller is put to sleep until a
X   matching envelope is entered into e-space. The matching envelope is
X   taken out of e-space and returned. No copying is done.
X
X   SEE ALSO
X      Rd(), Inp(), AwaitNamedEnvelope().
X
X------------------------------------------------------------------------
X
XEnvelope *Rd(env)
X   D0         A1
XEnvelope *env;
X
X   Works like In(), but copies the envelope from e-space to env. If 
X   e_copyfunc of the envelope to be extracted is non-NULL, that function
X   is used to copy envelope and contents. If copyfunc is NULL the envelope
X   and contents just after it are copied byte for byte to the location
X   given by env. No envelope is taken out of e-space.
X   The copyfunc feature allows complex structures to be copied (eg. binary
X   trees). A copyfunc should have the following declaration:
X
X   Envelope *copy_func(source,target)
X   Envelope *source,*target;
X   {  ....
X      return target;
X   }
X
X   The target-pointer should be returned.
X   The copyfunc should be made very fast because e-space is locked while
X   the copying is being done, preventing other tasks from altering e-space.
X   Rd() returns a pointer to the copy.
X
X   SEE ALSO
X      In(), Rdp().
X
X------------------------------------------------------------------------
X
Xvoid Out(env)
X         A1
XEnvelope *env;
X
X   Puts env into e-space. This is a non-copying operation, so it is
X   possible, although NOT recommended, to alter the contents of the
X   envelope while it is in e-space.
X
X   SEE ALSO
X      CopyOut(), OutEmptyEnvelope().
X
X------------------------------------------------------------------------
X
Xvoid CopyOut(env)
X              A1
XEnvelope *env;
X
X   Puts a copy of env into e-space. If env->e_copyfunc is non-NULL this
X   is used to copy the envelope and contents to a newly created envelope
X   of the same size as env. If e_copyfunc is NULL the envelope is copied
X   byte for byte.
X   Use this to put multiple copies of an envelope into e-space.
X
X   SEE ALSO
X      Rd(), Out(), OutEmptyEnvelope().
X
X------------------------------------------------------------------------
X
Xstruct Task *Eval(env,pri,stacksize,et)
X        D0         A1  D0    D1     D2
XEnvelope *env;
Xlong pri,et;
XULONG stacksize;
X
X   Eval() creates a new Process or Task (by StartProcess() or StartTask()),
X   determined by the 'et' parameter. If this parameter is EVAL_PROCESS
X   a process is started, and if it is EVAL_TASK a task is started.
X   Eval() passes the envelope 'env' to the new process/task without any
X   copying. The body of the process is the C-function in env->e_proc.
X   This should have the following declaration:
X
X   Envelope *new_process(passed_env)
X   Envelope *passed_env;
X   { ... }
X
X   The stacksize of the new process/task is set to 'stacksize' bytes, and
X   the process/task gets the priority 'pri'.
X   The name of the new process becomes the name of the passed envelope.
X
X   When the body-function returns an envelope, this envelope is put into
X   e-space with an Out()-call just before the task/process dies. This can
X   be used for syncronization between tasks. Be warned though! The system
X   will panic if the function does in fact NOT return an envelope.
X   If NULL is returned from the body-function, the process/task just dies,
X   and nothing is added to e-space.
X
X   Eval() carries all registers over to the new task/process except
X   A7 and A2!.
X
X   Eval() returns a pointer to the Task structure of the new process/task,
X   or NULL if something goes wrong.
X
X   SEE ALSO
X      CreateProcess(), Out(), CreateTask().
X
X------------------------------------------------------------------------
X
XEnvelope *Inp(env)
X   D0          A1
XEnvelope *env;
X
X   Works like In(), but instead of waiting when no matching envelope exists
X   in e-space, NULL is returned immediately. This corresponds to a kind of
X   polling.
X
X   SEE ALSO
X      In(), Rdp(), PollNamedEnvelope().
X
X------------------------------------------------------------------------
X
XEnvelope *Rdp(env)
X   D0         A1
XEnvelope *env;
X
X   Works like Rd(), but doesn't wait for a matching envelope, instead NULL
X   is returned.
X
X   SEE ALSO
X      Inp(), Rd().
X
X------------------------------------------------------------------------
X
Xstruct Task *StartTask(proc,name,pri,stacksize)
X     D0                 A0   A1   D0   D1
Xvoid (*proc)();
Xchar *name;
Xlong pri;
XULONG stacksize;  /* stack size in bytes, must be even */
X
X   This allocates a stack, and a Task structure, and starts a new task to 
X   execute proc. All registers except the stackpointer are carried over to
X   the new task. This is necessary since many compilers use register- 
X   relative addressing to access global variables.
X   When the procedure returns, the task dies.
X   A pointer to the newly created Task is returned, or NULL if something
X   goes wrong.
X
X   SEE ALSO
X      StartProcess(), Eval().
X
X------------------------------------------------------------------------
X
Xstruct Process *StartProcess(proc,name,pri,stacksize)
X          D0                  A0   A1  D0     D1
Xvoid (*proc)();
Xchar *name;
Xlong pri;
XULONG stacksize;  /* size is in bytes */
X
X   As above, just creates a Process instead.
X   Proc does not have to be at the start of a segment or lie on a 4-byte
X   boundary.
X   The process structure and stack are automatically freed when the process
X   dies by returning or calling Exit(). The code is NOT unloaded.
X   NB. Returns a pointer to the real Process-struct ie. not the messageport
X       in it.
X
X   SEE ALSO
X      StartTask(), Eval().
X
X------------------------------------------------------------------------
X
XEnvelope *AwaitNamedEnvelope(name)
X  D0                          A0
Xchar *name;
X
X   AwaitNamedEnvelope creates a temporary envelope with the name 'name',
X   and waits for a matching envelope to appear in e-space. When and if a
X   matching envelope appears, it is taken out of e-space and returned.
X   The temporary envelope is disposed of.
X   Use this instead of In().
X
X   SEE ALSO
X      In().
X
X------------------------------------------------------------------------
X
XEnvelope *PollNamedEnvelope(name)
X  D0                         A0
Xchar *name;
X
X   PollNamedEnvelope() checks if an envelope with the given name exists
X   in e-space, and if so, it takes it out of e-space and returns it. If
X   no envelope with the given name exists in e-space NULL is returned 
X   immediately.
X   This is actually a combination of InitEnvelope() and Inp().
X
X   SEE ALSO
X      Inp().
X
X------------------------------------------------------------------------
X
Xvoid OutEmptyEnvelope(name)
X                       A0
Xchar *name;
X
X   OutEmptyEnvelope() creates an empty envelope, with CreateEnvelope(),
X   gives it the name 'name' and puts it into e-space with Out().
X   This could be used for simple synchronization.
X
X   SEE ALSO
X      Out().
X
X------------------------------------------------------------------------
X
XEnvelope *CreateEnvelope(name,size)
X   D0                     A0   D0
Xchar *name;
XULONG size;
X
X   CreateEnvelope() creates a new envelope using AllocMem(). Size is the
X   byte-size of the envelope+contents. Eg.
X
X   struct FilledEnv {
X      Envelope env;
X      struct Image img;
X   };
X   struct FilledEnv *fe;
X   ....
X   fe = (struct FilledEnv *)CreateEnvelope("imageenvelope",
X                                           (long)sizeof(struct FilledEnv));
X
X   The new envelope is initialized with InitEnvelope() to have the given
X   length, and no copyfunc or proc.
X   If there is not enough memory for the creation, NULL is returned.
X
X   SEE ALSO
X      DisposeEnvelope(), InitEnvelope().
X
X------------------------------------------------------------------------
X
Xvoid DisposeEnvelope(env)
X                      A1
XEnvelope *env;
X
X   DisposeEnvelope() frees the space taken up by the envelope, by using
X   FreeMem().
X   If NULL is passed to this routine nothing is done. This can be used
X   eg. like this:
X
X   ....
X   do { DisposeEnvelope(p = PollNamedEnvelope(name)) } while(p);
X   ....
X
X   SEE ALSO
X      CreateEnvelope().
X
END_OF_FILE
if test 11403 -ne `wc -c <'odin.doc'`; then
    echo shar: \"'odin.doc'\" unpacked with wrong size!
fi
# end of 'odin.doc'
fi
if test -f 'odin.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odin.h'\"
else
echo shar: Extracting \"'odin.h'\" \(2796 characters\)
sed "s/^X//" >'odin.h' <<'END_OF_FILE'
X/* odin.h */
X/* headerfile for odin.library. V1.11 13-jun-90 */
X
X#ifndef ODIN_H
X#define ODIN_H 1
X
X#ifndef EXEC_NODES_H
X#include "exec/nodes.h"
X#endif
X#ifndef EXEC_LISTS_H
X#include "exec/lists.h"
X#endif
X#ifndef EXEC_SEMAPHORES_H
X#include "exec/semaphores.h"
X#endif
X#ifndef EXEC_LIBRARIES_H
X#include "exec/libraries.h"
X#endif
X#ifndef EXEC_TASKS_H
X#include "exec/tasks.h"
X#endif
X#ifndef LIBRARIES_DOSEXTENS_H
X#include "libraries/dosextens.h"
X#endif
X
X#define ODINNAME "odin.library"
X
Xstruct OdinBase {
X	struct Library		odin_LibNode;
X	BPTR			odin_SegList;
X	UBYTE			odin_Flags;
X	/* You MUST ObtainSemaphore() this before using 
X	 * the WaitList!
X	 */ 
X	struct SignalSemaphore	odin_Sem;	/* signal semaphore */
X	struct MinList		odin_WaitList;
X};
X
X#define odin_Sizeof sizeof(struct OdinBase)
X
X/* prefix for envelopes */
X
Xtypedef struct _Env {
X	struct MinNode	e_link;		/* first a link for use in e-space */
X	STRPTR		e_name;		/* the name of this envelope */
X	ULONG		e_len;		/* bytelength of whole envelope */
X	struct _Env *	(*e_copyfunc)();/* opt. C-function for copying */
X	struct _Env *	(*e_proc)();	/* C-func. to call in Eval() */
X} Envelope;
X
X#define e_sizeof (ULONG)sizeof(Envelope)
X
X/* wait-structure used in WaitList. Used internally */
X
Xstruct WaitStruct {
X	struct MinNode	ow_link;
X	Envelope	*ow_envelope;
X	struct Task	*ow_waittask;
X	UBYTE		ow_sigbit;
X	BYTE		ow_type;
X};
X
X#define ow_sizeof (ULONG)sizeof(struct WaitStruct)
X
X/* ow_types */
X
X#define RD_REQUEST 0
X#define IN_REQUEST 1
X
X/* the et parameter to Eval() */
X
X#define EVAL_PROCESS (long)0
X#define EVAL_TASK    (long)1
X
X#ifndef ANSI
X/* function returntypes */
X#define NoCopyFunc 0L
Xextern Envelope *In(),*Rd(),*Rdp(),*Inp();
Xextern void Out(),CopyOut();
Xextern struct Task *Eval();
Xextern struct Task *StartTask();
Xextern struct Process *StartProcess();
Xextern Envelope *AwaitNamedEnvelope();
Xextern Envelope *PollNamedEnvelope();
Xextern void OutEmptyEnvelope();
Xextern Envelope *CreateEnvelope(),*InitEnvelope();
Xextern void DisposeEnvelope();
X
X#else
X/* ANSI function-prototypes, worked with PDC 3.33 */
X#define NoCopyFunc (Envelope *(*cf)())0L
Xextern Envelope *In(Envelope *);
Xextern Envelope *Rd(Envelope *);
Xextern Envelope *Rdp(Envelope *);
Xextern Envelope *Inp(Envelope *);
Xextern void Out(Envelope *);
Xextern CopyOut(Envelope *);
Xextern struct Task *Eval(Envelope *,long,ULONG,long);
Xextern struct Task *StartTask(void(),char *,long,long);
Xextern struct Process *StartProcess(void(),char *,long,long);
Xextern Envelope *AwaitNamedEnvelope(char *);
Xextern Envelope *PollNamedEnvelope(char *);
Xextern void OutEmptyEnvelope(char *);
Xextern Envelope *CreateEnvelope(char *,ULONG);
Xextern Envelope *InitEnvelope(Envelope *,char *,ULONG,Envelope *(*copyfunc)());
Xextern void DisposeEnvelope(Envelope *);
X#endif /* ANSI */
X
X#endif /* ODIN_H */
END_OF_FILE
if test 2796 -ne `wc -c <'odin.h'`; then
    echo shar: \"'odin.h'\" unpacked with wrong size!
fi
# end of 'odin.h'
fi
if test -f 'odin.i' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odin.i'\"
else
echo shar: Extracting \"'odin.i'\" \(1098 characters\)
sed "s/^X//" >'odin.i' <<'END_OF_FILE'
X;odin2.i
X;includefile for odin.library.
X;using semaphore instead of spacemanager
X;Last updated 10-jul-90
X;Version = 1.11
X
X	IFND	ODIN_I
XODIN_I	EQU	1
X
XodinNAME	MACRO
X	DC.B	'odin.library',0
X	CNOP	0,2
X	ENDM
X
X	STRUCTURE odin,LIB_SIZE
X	APTR	odin_SegList
X	UBYTE	odin_Flags
X	UBYTE	odin_pad
X	;------------------------------------------------
X	;- You must ObtainSemaphore() this before using
X	;- WaitList!
X	;------------------------------------------------
X	STRUCT	odin_Sem,SS_SIZE		;signal semaphore
X	STRUCT	odin_WaitList,MLH_SIZE
X	LABEL	odin_Sizeof
X
X;--- prefix for envelopes
X
X	STRUCTURE	Envelope,MLN_SIZE	;first a link for use in e-space
X	APTR	e_name		;ptr to ASCIIZ string
X	ULONG	e_len		;bytelength of contents
X	APTR	e_copyfunc	;opt. C-function for copying
X	APTR	e_proc		;C-function to call in Eval
X	LABEL	e_sizeof
X
X;--- wait-structure used in WaitList
X
X	STRUCTURE	WaitStruct,MLN_SIZE
X	APTR	ow_envelope
X	APTR	ow_waittask
X	UBYTE	ow_sigbit
X	BYTE	ow_type
X	LABEL	ow_sizeof
X
X;--- ow_types
X
XRD_REQUEST	EQU	0
XIN_REQUEST	EQU	1
X
X;--- the et parameter to Eval()
X
XEVAL_PROCESS	EQU	0
XEVAL_TASK		EQU	1
X
X	ENDC	!ODIN_I
END_OF_FILE
if test 1098 -ne `wc -c <'odin.i'`; then
    echo shar: \"'odin.i'\" unpacked with wrong size!
fi
# end of 'odin.i'
fi
if test -f 'odin.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odin.uu'\"
else
echo shar: Extracting \"'odin.uu'\" \(3501 characters\)
sed "s/^X//" >'odin.uu' <<'END_OF_FILE'
Xbegin 644 odin.library
XM```#\P`````````$``````````,```'A````%0````L```#B```#Z0```>%P?
XM"DYU2OP````$```'A(`!"0`````>````+````$QO9&EN+FQI8G)A<GD``&]DB
XM:6XN;&EB<F%R>2`Q+C$Q("@Q,2!*=6P@.3`I#0H`````8@```%P```"L````#
XMV````7````%^```!D````=@```:2```!W```!L(```2P```%I````>P```*$_
XM```#/@``!M@```/L```$*@``!&(```9$```&8@``!H#_____X```#`D`P```+
XM"@```![@```.!@#0```4``'0```6``O````8````+``````O#2I`(\`````$#
XM*T@`(D/Y`````'``3J[]V"/``````&8*+CR``X`'3J[_E$'M`"A.KOW20>T`W
XM*$(H``D1?``/``A"J``*0>T`5B"(6)!"J``$(4@`"$'Y````"#`\`#\@B%B0C
XM0J@`!"%(``A!Z``,4<C_[D'Y```#"$ZN_=)!^0```PA"*``)$7P`#P`(0J@`P
XM"B`-*E].=0BN``,`)E)N`"`@#DYU<`!3;@`@9@@(+@`#`"9A`DYU2.<@!BI.$
XM+'@`!$IM`"!G"@CM``,`)G``8"@D+0`B(DU.KO\$(GD`````3J[^8G``(DTPM
XM+0`0DL#0;0`23J[_+B`"3-]@!$YU<`!.=2-(``@C0``,(TH`$"`)3G5(YP`F.
XM*DXD22QX``1![0`H3J[]S"!*80`%%$J`9Q9A``5$)$!![0`H3J[]QB`*3-]DO
XM`$YU3^__[B!/(4H`""%N`10`#!%\``$`$7#_3J[^MB)/$T``$$'M`%9!Z``$#
XM("@`!"%)``0BB"-```0@0"")0>T`*$ZN_<82+P`0<``#P$ZN_L)P`!`O`!!.V
XMKOZP("\`"$_O`!)@EDCG`"8J3B1)+'@`!$'M`"A.KOW,($IA``1\2H!G+"!`^
XM(DI,WV0`80`$M$CG``8J>0````0L>``$0>T`*"\`3J[]QB`?3-]@`$YU3^__F
XM[B!/(4H`""%N`10`#!%\````$7#_3J[^MB)/$T``$$'M`%9!Z``$("@`!"%)X
XM``0BB"-```0@0"")0>T`*$ZN_<82+P`0<`'CJ$ZN_L)P`!`O`!!.KOZP0>T`3
XM*$ZN_<P@;P`(3^\`$B)*8`#_:DCG`#8J3B1)+'@`!$'M`"A.KOW,($HB:``(2
XM80`#H"!)(DI!Z``$("@`!"%)``0BB"-```0@0"")0>T`5K'H``AG7B90(&L`%
XM""!H``@B:@`(LPAF1DHH__]F]B)+(%$B:0`$(H@A20`$)TH`"$HK`!%G&"`*,
XM80`#G!(K`!!P`>.H(FL`#$ZN_KQ@%A(K`!!P`>.H(FL`#$ZN_KPF4TJ39J1!'
XM[0`H3J[]QDS?;`!.=2\*)$DB:@`(0?H`%$J"9@9.KO_*8`1.KO_0)%].=2\*B
XM2'H`""\J`!1.=5B/(D!*@&<*+'D````$3N[_N$YU2.<`)BI.)$DL>``$0>T`M
XM*$ZN_<P@2F$``M9*@&<680`#!B1`0>T`*$ZN_<8@"DS?9`!.=7``8.I(YP`F%
XM*DXD22QX``1![0`H3J[]S"!*80`"GDJ`9RP@0")*3-]D`&$``M9(YP`F+'@`]
XM!"IY````!$'M`"@D0$ZN_<8@"DS?9`!.=7``8.I(Y\#"+'@`!$'Y```#"$ZNT
XM_<Q,WT,#2/E__P```SA(YS@Z(\@```-X)DDH`"8!+'@`!$'Y````#"%#`!1.M
XMKO\B"(``'V8``)HCP````X`D0"0J`!`D:@`8%7P``0`(%40`"25+``HE0@`Z;
XMU(,E0@`^58(E0@`V0>H`2B"(6)!"J``$(4@`"!%\``H`#'#_3J[^MA/````#L
XM-FL\(^X!%````WPS_``!```#A")**$I%^0````"7RTZN_N82.0```S9P`>.H7
XM3J[^PG``$#D```,V3J[^L&`,('D```.`3J[_')G,0?D```,(3J[]QB`,3-]<3
XM'$YU2.?`PBQX``1!^0```PA.KOW,3-]#`TCY?_\```,X2.<\`B/(```#>"@!I
XM*@DD`"QX``1P_TZN_K83P````S9K7"/N`10```-\0GD```.$)CS____\Y(LL.
XM>0`````B!4ZN_W8D`&<D!((```!<+'@`!!(Y```#-G```\!.KO["<``0.0``V
XM`S9.KOZP0?D```,(3J[]QB`"3-]`/$YU=`!@ZB\*3^__Z")/<!B5RDZN_]PB@
XM0$ZN_\1/[P`8)%].=2\*3^__Z")/<!B5RDZN_]PB0$ZN_Z9/[P`8)%].=7`8/
XM3J[_XB)`2H!G!$ZN_[A.=2\*2.>`@BQX``0B/``!``%.KO\Z(D!*@&<.3-]!>
XM`97*3J[_W"1?3G5,WT$!<`!@]"`)9Q`@*0`,+PXL>``$3J[_+BQ?3G4O"2!I`
XM``@@*0`,3J[_XB)?2H!G#"!)(D!A;B)`3J[_N$YU<`!R`!(99P30`6#X`D``-
XM/\#\``Q#^0````C3P$YU2.<`,"1((FH`"&'6L^D`"&<>(E$@:0`()FH`"+<([
XM9@I**/__9O8@"6`((E%*D6;D<`!,WPP`3G4B0"!1(FD`!"*((4D`!$YU2J@`^
XM$&80("@`#"()$MA3@&;Z(`%.=2\)+P@@:``03I!0CTYU```#[````!T`````9
XM````!@````H````2````%@```!H```!0````5````%@```!<````8````&0`N
XM``!H````;````'````!T````>````'P```"`````A````(@```",````D```4
XM`)0```"8````G````*````"D````M@```-`````"`````0``!6````7T````S
XM`@````(```#H```$Y````!\````#````W@```/0```$P```!3@```5@```&V8
XM```"M```!"````26```$N@``!,H```34```$^@``!40```5.```%5@``!6P`^
XM``5\```%B```!90```6N```%O@``!<@```7>```%Z```!>X```7\```&%@``*
XM!B8```8P```'$`````````/R```#Z0```!4L>``$2GD```.$9R0@;@$40>@`X
XM2B)Y```#@$'H``0@*``$(4D`!"*((T``!"!`((DO.0```W@2.0```S9P`>.H,
XM(GD```-\3J[^O$SY?_\```,X3G4```/L````!@````,````&````%@```#(`7
XM```X````0@```$X````````#\@```^H````+9&]S+FQI8G)A<GD`````````>
XJ```*`````````@````$```````$``0```%P```/R```#ZP```.(```/RE
X``
Xend
Xsize 2472
END_OF_FILE
if test 3501 -ne `wc -c <'odin.uu'`; then
    echo shar: \"'odin.uu'\" unpacked with wrong size!
fi
# end of 'odin.uu'
fi
if test -f 'odin_lib.fd' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odin_lib.fd'\"
else
echo shar: Extracting \"'odin_lib.fd'\" \(683 characters\)
sed "s/^X//" >'odin_lib.fd' <<'END_OF_FILE'
X*---- odin_lib.fd 
X*---- version.revision = 1.11
X##base _OdinBase
X##bias 30
X##public
X*---- basic functions
XCreateEnvelope(name,size)(A0,D0)
XInitEnvelope(envelope,name,len,copyfunc)(A1,A0,D0,A2)
XDisposeEnvelope(envelope)(A1)
X*---- creation of tasks/processes from procedures
XStartTask(procedure,name,pri,stacksize)(A0/A1,D0/D1)
XStartProcess(procedure,name,pri,stacksize)(A0/A1,D0/D1)
X*---- Linda-like functions
XIn(envelope)(A1)
XRd(envelope)(A1)
XOut(envelope)(A1)
XCopyOut(envelope)(A1)
XEval(envelope,pri,stacksize,et)(A1,D0/D1/D2)
XInp(envelope)(A1)
XRdp(envelope)(A1)
X*---- ease-of-use functions
XAwaitNamedEnvelope(name)(A0)
XPollNamedEnvelope(name)(A0)
XOutEmptyEnvelope(name)(A0)
X##end
END_OF_FILE
if test 683 -ne `wc -c <'odin_lib.fd'`; then
    echo shar: \"'odin_lib.fd'\" unpacked with wrong size!
fi
# end of 'odin_lib.fd'
fi
if test -f 'odindemo1.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odindemo1.c'\"
else
echo shar: Extracting \"'odindemo1.c'\" \(3331 characters\)
sed "s/^X//" >'odindemo1.c' <<'END_OF_FILE'
X/***********************************************/
X/* odindemo1.c                                 */
X/* demo of odin.library                        */
X/* starts 2 new processes and sends envelopes  */
X/* back and forth.                             */
X/* Created 7-Jul-90 by Peter Oerbaek           */
X/* This code is in the public domain.          */
X/* Link with odinglue.o                        */
X/***********************************************/
X
X/**********************************************************************
X  A lot of checking is ommited in the code to make it smaller and
X  easier to read.
X**********************************************************************/
X
X#include	"exec/types.h"
X#include	"exec/semaphores.h"
X#include	"stdio.h"
X#include	"odin.h"
X
Xstruct OdinBase *OpenLibrary();
Xstruct OdinBase *OdinBase;	/* global base pointer */
X
Xtypedef struct {
X	Envelope	env;	/* envelope-prefix used by odin routines */
X	int		num;	/* package number */
X	int		stop;	/* flag to stop consumers */
X} Pack;
X
X#define p_sizeof (long)sizeof(Pack)
X
Xtypedef struct {
X	Envelope	e;		/* envelope-prefix */
X	char		*windowname;	/* name of windowfile to open */
X} StartEnv;
X
X#define se_sizeof (long)sizeof(StartEnv)
X
X/*** for use around C routines that are not re-entrant ***/
X
Xstruct SignalSemaphore	ss;
X#define CRIT_REG(s) ObtainSemaphore(&ss); { s } ReleaseSemaphore(&ss);
X
X/**** the body for the processes ************/
X
XEnvelope *processbody(se)
XStartEnv *se;
X{
X	FILE *f;
X	int i,stop;
X	Pack *p;
X
X	CRIT_REG(f = fopen(se->windowname,"w");)
X	CRIT_REG(fprintf(f,"Hello world\n");)
X	do {
X		p = (Pack *)AwaitNamedEnvelope("a packet");
X		stop = p->stop;
X		CRIT_REG(fprintf(f,"Packet #%d received.\n",p->num);)
X		DisposeEnvelope(p);
X	} while(stop == 0);
X	CRIT_REG(fprintf(f,"Bye, bye...\n");)
X	Delay(100L);
X	CRIT_REG(fclose(f);)
X	return (Envelope *)se;
X}
X
Xmain()
X{
X	StartEnv *env;
X	Pack *pack;
X	int i;
X
X	printf("opening library\n");
X	if(!(OdinBase = OpenLibrary("ram:odin.library",0L))) {
X		printf("Couldn't open odin.library\n");
X		exit(20);
X	}
X
X	/* set up semaphore */
X	InitSemaphore(&ss);
X
X	/* Ought to do an AddSemaphore() here, but that doesn't work
X	 * in my ROM (KS 33.180)
X	 */
X
X	printf("creating new processes\n");
X	/* start first process */
X	env = (StartEnv *)CreateEnvelope("newprocess1",se_sizeof);
X	env->e.e_proc = processbody;
X	env->windowname = "CON:10/10/300/100/Proc1";
X	Eval(env,1L,4000L,EVAL_PROCESS);
X
X	/* start next process */
X	env = (StartEnv *)CreateEnvelope("newprocess2",se_sizeof);
X	env->e.e_proc = processbody;
X	env->windowname = "CON:310/20/300/100/Proc2";
X	Eval(env,0L,4000L,EVAL_PROCESS);
X
X	/* send some packages */
X	for(i = 0; i < 10; i++) {
X		pack = (Pack *)CreateEnvelope("a packet",p_sizeof);
X		pack->num = i;
X		pack->stop = 0;
X		Out(pack);
X		CRIT_REG(printf("packet #%d sent.\n",i);)
X	}
X
X	/* send the stop-packages */
X	CRIT_REG(printf("sending stop-packets.\n");)
X	pack = (Pack *)CreateEnvelope("a packet",p_sizeof);
X	pack->stop = 1;
X	Out(pack);
X
X	pack = (Pack *)CreateEnvelope("a packet",p_sizeof);
X	pack->stop = 1;
X	Out(pack);
X
X	CRIT_REG(printf("waiting for process1 to terminate\n");)
X	DisposeEnvelope(AwaitNamedEnvelope("newprocess1"));
X	CRIT_REG(printf("waiting for process2 to terminate\n");)
X	DisposeEnvelope(AwaitNamedEnvelope("newprocess2"));
X
X	printf("closing\n");
X	CloseLibrary(OdinBase);
X}
X
END_OF_FILE
if test 3331 -ne `wc -c <'odindemo1.c'`; then
    echo shar: \"'odindemo1.c'\" unpacked with wrong size!
fi
# end of 'odindemo1.c'
fi
if test -f 'odindemo2.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odindemo2.c'\"
else
echo shar: Extracting \"'odindemo2.c'\" \(1754 characters\)
sed "s/^X//" >'odindemo2.c' <<'END_OF_FILE'
X/****************************************************************
X  odindemo2.c
X  Created 11-jul-90 by Peter Oerbak
X  Shows off some features of the odin.library V1.11
X  This is in the public domain.
X*****************************************************************/
X
X#include	"exec/types.h"
X#include	"exec/semaphores.h"
X#include	"exec/tasks.h"
X#include	"stdio.h"
X#include	"odin.h"
X
Xstruct OdinBase	*OpenLibrary();
X
Xstruct SignalSemaphore	ss;
X
X#define CR(s) ObtainSemaphore(&ss); { s } ReleaseSemaphore(&ss);
X
Xtypedef struct {
X	Envelope	e;
X	char		*windowname;
X	int		num;
X} Packet;
X
X#define p_sizeof (long)sizeof(Packet)
X#define PACKNAME "A packet"
X
Xstruct OdinBase *OdinBase;
X
XEnvelope *new_process(p)
XPacket *p;
X{
X	FILE	*f;
X
X	CR(
X		f = fopen(p->windowname,"w");
X		fprintf(f,"Hello there.\n");
X	)
X
X	Delay(100L);
X	CR(fprintf(f,"bye,bye\n");)
X	CR(fclose(f);)
X	return (Envelope *)p;
X}
X
Xmain()
X{
X	Packet		*p;
X	struct Task	*t;
X	Envelope	*env;
X
X	if(!(OdinBase = OpenLibrary("ram:odin.library",0L))) {
X		printf("No odin library!\n");
X		exit(20);
X	}
X	printf("odin.library open\n");
X	InitSemaphore(&ss);
X	printf("semaphore inited\n");
X	p = (Packet *)CreateEnvelope(PACKNAME,p_sizeof);
X	if(!p) {
X		printf("no memory for packet\n");
X		CloseLibrary(OdinBase);
X		exit(20);
X	}
X	printf("packet created\n");
X	p->e.e_proc   = new_process;
X	p->num        = 0;
X	p->windowname = "CON:10/10/300/200/Process";
X	t = Eval(p,0L,4000L,EVAL_PROCESS);
X	if(!t) {
X		printf("couldn't start new process with Eval()\n");
X		DisposeEnvelope(p);
X		CloseLibrary(OdinBase);
X		exit(20);
X	}
X	CR(printf("new process started\n");)
X	do {
X		CR(printf("polling.\n");)
X		env = PollNamedEnvelope(PACKNAME);
X	} while(!env);
X	printf("got envelope\n");
X	DisposeEnvelope(env);
X	CloseLibrary(OdinBase);
X}
X
END_OF_FILE
if test 1754 -ne `wc -c <'odindemo2.c'`; then
    echo shar: \"'odindemo2.c'\" unpacked with wrong size!
fi
# end of 'odindemo2.c'
fi
if test -f 'odinglue.asm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odinglue.asm'\"
else
echo shar: Extracting \"'odinglue.asm'\" \(3006 characters\)
sed "s/^X//" >'odinglue.asm' <<'END_OF_FILE'
X;odinglue.asm 
X;Created 4-Jul-90 by Peter Oerbaek
X;Last updated 11-Jul-90 by Peter Oerbaek
X;This is in the public domain.
X;C-interface gluecode for odin.library V1.11
X;Assemble with 'as' for Aztec-C 3.40a or later
X;Assemble with Assem/A68K for Lattice / DICE / PDC
X;Assembles OK as is with A68K 2.6!!!!
X
X;public	macro		;de-comment this for use with Assem
X;	XDEF	\1
X;	endm
X
X__CreateEnvelope	equ	-30
X__InitEnvelope	equ	-36
X__DisposeEnvelope	equ	-42
X__StartTask	equ	-48
X__StartProcess	equ	-54
X__In		equ	-60
X__Rd		equ	-66
X__Out		equ	-72
X__CopyOut		equ	-78
X__Eval		equ	-84
X__Inp		equ	-90
X__Rdp		equ	-96
X__AwaitNamedEnvelope equ	-102
X__PollNamedEnvelope	equ	-108
X__OutEmptyEnvelope	equ	-114
X
X	public	_OdinBase		;for use with Manx 'as'
X;	XREF	_OdinBase		;for use with Assem
X
X_InitEnvelope:
X	movem.l	a2/a6,-(sp)	;a6,a2,pc,env,name,len,copyfunc
X	move.l	12(sp),a1
X	move.l	16(sp),a0
X	move.l	20(sp),d0
X	move.l	24(sp),a2
X	move.l	_OdinBase,a6
X	jsr	__InitEnvelope(a6)
X	movem.l	(sp)+,a2/a6
X	rts
X	public _InitEnvelope
X
X_In:
X	move.l	a6,-(sp)		;a6,pc,env
X	move.l	8(sp),a1
X	move.l	_OdinBase,a6
X	jsr	__In(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_In
X
X_Out:
X	move.l	a6,-(sp)
X	move.l	8(sp),a1
X	move.l	_OdinBase,a6
X	jsr	__Out(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_Out
X
X_CopyOut:
X	move.l	a6,-(sp)
X	move.l	8(sp),a1
X	move.l	_OdinBase,a6
X	jsr	__CopyOut(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_CopyOut
X
X_Rd:
X	move.l	a6,-(sp)
X	move.l	8(sp),a1
X	move.l	_OdinBase,a6
X	jsr	__Rd(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_Rd
X
X_Eval:
X	movem.l	d2/a6,-(sp)	;a6,d2,pc,a1,d0,d1,d2
X	move.l	12(sp),a1
X	movem.l	16(sp),d0-d2
X	move.l	_OdinBase,a6
X	jsr	__Eval(a6)
X	movem.l	(sp)+,d2/a6
X	rts
X	public	_Eval
X
X_Inp:
X	move.l	a6,-(sp)
X	move.l	8(sp),a1
X	move.l	_OdinBase,a6
X	jsr	__Inp(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_Inp
X
X_Rdp:
X	move.l	a6,-(sp)
X	move.l	8(sp),a1
X	move.l	_OdinBase,a6
X	jsr	__Rdp(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_Rdp
X
X_StartTask:
X	move.l	a6,-(sp)		;a6,pc,proc,name,pri,stack
X	movem.l	8(sp),a0/a1
X	movem.l	16(sp),d0/d1
X	move.l	_OdinBase,a6
X	jsr	__StartTask(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_StartTask
X
X_StartProcess:
X	move.l	a6,-(sp)
X	movem.l	8(sp),a0/a1
X	movem.l	16(sp),d0/d1
X	move.l	_OdinBase,a6
X	jsr	__StartProcess(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_StartProcess
X
X_AwaitNamedEnvelope:
X	move.l	a6,-(sp)
X	move.l	8(sp),a0
X	move.l	_OdinBase,a6
X	jsr	__AwaitNamedEnvelope(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_AwaitNamedEnvelope
X
X_PollNamedEnvelope:
X	move.l	a6,-(sp)
X	move.l	8(sp),a0
X	move.l	_OdinBase,a6
X	jsr	__PollNamedEnvelope(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_PollNamedEnvelope
X
X_OutEmptyEnvelope:
X	move.l	a6,-(sp)
X	move.l	8(sp),a0
X	move.l	_OdinBase,a6
X	jsr	__OutEmptyEnvelope(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_OutEmptyEnvelope
X
X_CreateEnvelope:
X	move.l	a6,-(sp)		;a6,pc,name,size
X	move.l	8(sp),a0
X	move.l	12(sp),d0
X	move.l	_OdinBase,a6
X	jsr	__CreateEnvelope(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_CreateEnvelope
X
X_DisposeEnvelope:
X	move.l	a6,-(sp)
X	move.l	8(sp),a1
X	move.l	_OdinBase,a6
X	jsr	__DisposeEnvelope(a6)
X	move.l	(sp)+,a6
X	rts
X	public	_DisposeEnvelope
X
X	end
X
END_OF_FILE
if test 3006 -ne `wc -c <'odinglue.asm'`; then
    echo shar: \"'odinglue.asm'\" unpacked with wrong size!
fi
# end of 'odinglue.asm'
fi
if test -f 'odintest.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'odintest.c'\"
else
echo shar: Extracting \"'odintest.c'\" \(4890 characters\)
sed "s/^X//" >'odintest.c' <<'END_OF_FILE'
X/***********************************************************
X* odintest.c                                               *
X* Created 12-jul-90 by Peter Oerbaek                       *
X* This is supposed to be a complete test-suite of the      *
X* functions in odin.library                                *
X* Modified 13-jul-90 for ANSI compatibility                *
X* Compiles and runs under both Aztec C 3.40a and PDC 3.33  *
X************************************************************/
X
X#include	"exec/types.h"
X#include	"exec/tasks.h"
X#include	"exec/semaphores.h"
X#include	"exec/execbase.h"
X#include	"odin.h"
X#include	"stdio.h"
X
Xvoid *OpenLibrary();
Xstruct Task *FindTask();
X
Xstruct OdinBase *OdinBase;
Xstruct SignalSemaphore ss;
X#define CR(s) ObtainSemaphore(&ss); { s } ReleaseSemaphore(&ss);
X#define debug(str) CR(printf(str);)
X
XEnvelope e1,e2;
X
XEnvelope *my_copyfunc(src,tar)
XEnvelope *src,*tar;
X{
X	int i;
X	register char *a,*b;
X
X	a = (char *)src; b = (char *)tar;
X	for(i = 0; i < e_sizeof; i++) {
X		*a++ = *b++;
X	}
X
X	return tar;
X}
X
XEnvelope *process1(e)
XEnvelope *e;
X{
X	struct Task *tsk;
X	Envelope *env;
X
X	debug("process1 started\n");
X	CR(printf("lenght = %ld\n",e->e_len);)
X
X	tsk = FindTask(NULL);
X	
X	CR(printf("stacksize = %d\n",(int)(tsk->tc_SPUpper - tsk->tc_SPLower));)
X	CR(printf("pri = %d\n",(int)tsk->tc_Node.ln_Pri);)
X	CR(printf("taskname=%s\n",tsk->tc_Node.ln_Name);)
X
X	debug("creating envelope\n");
X	env = CreateEnvelope("Env2",e_sizeof);
X	if(env == NULL) { debug("create returned NULL\n"); return e; }
X
X	debug("envelope created\n");
X
X	Delay(100L);
X	debug("copyouting\n");
X	CopyOut(env);
X
X	Delay(199L);
X	debug("copy outing with copyfunc\n");
X	env->e_copyfunc = my_copyfunc;
X	CopyOut(env);
X
X	debug("normal out\n");
X	Out(env);
X
X	debug("wait for V3\n");
X	while(!(env = PollNamedEnvelope("V3"))) { 
X		debug("waiting with poll.\n");
X	}
X
X	debug("got V3 dispose\n");
X	DisposeEnvelope(env);
X
X	debug("wait for V4 and dispose\n");
X	DisposeEnvelope(AwaitNamedEnvelope("V4"));
X
X	debug("wait for task1\n");
X	DisposeEnvelope(AwaitNamedEnvelope("V5"));
X	debug("shake hands\n");
X	OutEmptyEnvelope("R1");
X
X	Delay(100L);
X	return e;
X}
X
Xvoid task1()
X{
X	OutEmptyEnvelope("V5");	/* shake hands with process */
X	DisposeEnvelope(AwaitNamedEnvelope("R1"));
X}
X
Xmain()
X{
X	Envelope *ptr;
X	struct Task *tsk;
X
X	if(!(OdinBase = (struct OdinBase *)OpenLibrary("RAM:odin.library",0L)))
X	{
X		printf("couldn't find odin.library.\n");
X		exit(20);
X	}
X
X	InitSemaphore(&ss);
X
X	debug("begin\n");
X
X	debug("test InitEnvelope():\n");
X	ptr = InitEnvelope(&e1,"Test",e_sizeof,NoCopyFunc);
X	debug("init envelope finished\n");
X	if(ptr == &e1) {
X		debug("returnvalue ok.\n");
X		if(strcmp(ptr->e_name,"Test") == 0) {
X			debug("name inited ok\n");
X		} else {
X			debug("name wrong\n");
X		}
X		if(ptr->e_len == e_sizeof && ptr->e_copyfunc == NULL) {
X			debug("inited ok\n");
X		} else {
X			debug("wrong init\n");
X		}
X	} else {
X		debug("returned wrong value.\n");
X	}
X
X
X	debug("test Eval():\n");
X	e1.e_proc = process1;
X	(void)Eval(&e1,(long)0,(ULONG)4000,EVAL_PROCESS);
X	debug("eval finished\n");
X
X	debug("test rdp\n");
X	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
X	while(!(ptr = Rdp(&e2))) { debug("waiting in rdp\n"); }
X	if(ptr == &e2) {
X		debug("rdp returned ok\n");
X	} else {
X		debug("rdp returned wrong\n");
X	}
X	CR(printf("name returned by rdp: %s\n",e2.e_name);)
X
X	debug("test rd\n");
X	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
X	ptr = Rd(&e2);
X	if(ptr == &e2) {
X		debug("rd returned ok\n");
X	} else {
X		debug("rd returned wrong\n");
X	}
X	CR(printf("name returned by rd: %s\n",ptr->e_name);)
X
X	debug("test In()\n");
X	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
X	ptr = In(&e2);
X	if(ptr != &e2) {
X		debug("in returned ok\n");
X	} else {
X		debug("in returned wrong\n");
X	}
X	CR(printf("name returned by in: %s\n",ptr->e_name);)
X	DisposeEnvelope(ptr);
X
X	debug("test AwaitNamedEnvelope()\n");
X	ptr = AwaitNamedEnvelope("Env2");
X	CR(printf("name returned by Await..: %s\n",ptr->e_name);)
X	DisposeEnvelope(ptr);
X
X	debug("test rdp with copyfunc\n");
X	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
X	while(!(ptr = Rdp(&e2))) { debug("waiting in rdp2\n"); }
X	if(ptr == &e2) {
X		debug("rdp2 returned ok\n");
X	} else {
X		debug("rdp2 returned wrong\n");
X	}
X	CR(printf("name returned by rdp2: %s\n",e2.e_name);)
X
X	debug("rd with copyfunc\n");
X	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
X	ptr = Rd(&e2);
X	if(ptr == &e2) {
X		debug("rd2 returned ok\n");
X	} else {
X		debug("rd2 returned wrong\n");
X	}
X	CR(printf("name returned by rd2: %s\n",e2.e_name);)
X
X	DisposeEnvelope(AwaitNamedEnvelope("Env2"));
X
X	Delay(100L);
X	Out(CreateEnvelope("V3",e_sizeof));
X
X	OutEmptyEnvelope("V4");
X
X	tsk = StartTask(task1,"TAsk1",0L,4000L);
X	if(tsk == NULL) { debug("couldn't start task\n"); }
X	debug("task started\n");
X
X	debug("wait for process to die\n");
X	(void)AwaitNamedEnvelope("Test");	
X
X	CloseLibrary(OdinBase);
X}
X
END_OF_FILE
if test 4890 -ne `wc -c <'odintest.c'`; then
    echo shar: \"'odintest.c'\" unpacked with wrong size!
fi
# end of 'odintest.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.