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.