\input manualMacros.tex
\input manualMacros.tex
\manBegin
\manPageInfo{RCCL Reference Manual}{}{}
\manTitle{allocTrans}{3}
\manSection{NAME}
{\rightskip=0ptplus1fil
{\tt \manName{allocTrans}},
{\tt \manName{freeTrans}},
{\tt \manName{getTransByAddr}},
{\tt \manName{getTransByName}},
{\tt \manName{readTrans}},
{\tt \manName{writeTrans}},
{\tt \manName{getTransName}}
-- RCCL transform maintenance primitives.

}
\manSection{USAGE}
\cverbatim
#include <rccl.h>

TRSF *allocTrans (name, pool)
   const char *name;
   int pool;

freeTrans (tr)
   TRSF *tr;

TRSF *getTransByName (name)
   const char *name;

TRSF *getTransByAddr (tp)
   TRSF *tp;

TRSF *readTrans (tr, tbuf)
   TRSF *tr;
   TRSF *tbuf;

TRSF *writeTrans (tr, tbuf)
   TRSF *tr;
   TRSF *tbuf;

char *getTransName(tr)
   TRSF *tr; @endcverbatim
\manSection{ARGUMENTS}
\manItem{{\tt name} --}
Name of the transform (optional; can be specified as {\tt NULL} if not
required).
\manItem{{\tt pool} --}
Memory area from which to allocate the transform. Under the current
implementation, there is one memory area on each CPU, so {\tt pool} is
actually 
a CPU number. The idea is to allocate the transform on the CPU where
it will be accessed the most. If you don't care what memory pool is used
to allocate the transform, give this argument as {\tt UNDEF}.
\manItem{{\tt tr} --}
Pointer to the transform.
\manItem{{\tt tp} --}
Pointer to the transform which is valid in the planning task context.
\manItem{{\tt tbuf} --}
Buffer to copy the transform into or read it from.
\manSection{RESTRICTIONS}
At the moment, {\tt allocTrans()} and {\tt freeTrans()} must be called from
the planning level.
\manSection{DESCRIPTION}
These routines provide an RCCL program
with the ability to create transformation objects which
can be accessed globally from any part of an RCCL program.
These routines are implemented using the
RCI {\it allocMem()} package, which can also be used to create global data
objects other than transforms (see {\tt allocMem(3)}). 
The primitives described in this manual page
are analogous to the {\tt allocMem()} primitives. The reason for having
separate routines is that the transform objects are associated with additional
data fields (hidden from the programmer) that are used to provide special
functionality. In particular, transforms created with {\tt allocTrans()} may
be bound to real-time functions that update their values from the trajectory
level (see {\tt setTransConst(3)}).

{\tt allocTrans()} creates a transform with the given {\TT name}.
The argument {\tt pool} identifies a memory pool from
which to allocate the transform; under the current implementation, this is
simply a CPU number; i.e., giving {\tt pool} a value of N will cause the
transform to be allocated from memory on CPU N.
If {\tt pool} is given as {\tt UNDEF}, then the memory pool
is chosen by the system.
It is possible to specifiy a {\tt NULL} name, by setting
{\tt name} to be either {\tt NULL}, or a pointer to an empty string. This
can be useful for allocating internal transforms without the risk of
causing name-space collisions. 
Under the current implementation, {\tt allocTrans()} must be called from the
planning task.

{\tt freeTrans()} frees the allocated transform. This routine must also
be called from the planning task.

{\tt getTransByName()} locates a transform, using its name as a key,
and returns a pointer to
it. It is necessary to use such a routine when 
accessing a transform from the control
level (e.g., from within a monitor or transform function). This is because
the control level memory context may be different from the planning level
memory context (particularly if the control level is executing on a
different CPU) and so a transform pointer which is valid in the planning
level context may not be valid at the control level.
(Remember that different virtual addresses can point to the same
physical address.)

{\tt getTransByAddr()} is similar to {\tt getTransByName()}, except
that it locates a transform using its planning level {\it address} as
a key. This is useful in cases where it is desirable to not
name a transform (in order to avoid name-space collisions, as described
above). The routine is 
also faster than {\tt getTransByName()}.

A couple of routines are also provided for accessing the value of
a transform atomically:

{\tt readTrans()} copies the contents of a transform into a buffer.
The operation is atomic, in that it will lock out other
{\tt readTrans()} or {\tt writeTrans()} operations on the same transform. The
routine returns the pointer {\tt tr}.

{\tt writeTrans()} copies the contents of a buffer
into the indicated transform.
The operation is atomic, in that it will lock out other
{\tt readTrans()} or {\tt writeTrans()} operations on the same transform. The
routine returns the pointer {\tt tr}.
 
\manInset{
{\bf NOTE}: only the transform itself, i.e., the leftmost argument, is
accessed atomically by {\tt readTrans()} and {\tt writeTrans()}.
The righthand argument is not accessed atomically.}

{\tt getTransName()} returns the name of a transform.

\manSection{DIAGNOSTICS}
{\tt allocTrans()} returns {\tt NULL} in the event of an error.
It will automatically abort the program if the option {\tt RCCL_ERROR_EXIT} is
set (see {\tt rcclSetOptions(3)}).
Error codes and messages are placed on the {\it errorStack} (q.v.). 
The following error codes may be set:

\manItem{{\tt EMemory} --}
Not enough memory left in the shared memory pool.
\manItem{{\tt EDuplicate} --}
Attempt was made to create a transform with the same name as
one already allocated.

{\tt getTransByName()} and {\tt getTransByAddr()} return {\tt NULL} if they
cannot find the indicated transform.

{\tt allocTrans()} and {\tt freeTrans()} will abort the program if
called from the control level.
\manSection{SEE ALSO}
{\raggedright
{\tt allocMem(3)},
{\tt setTransVarb(3)},
{\tt errorStack(3)}.

}
\manEnd
\end
