\hypertarget{RNG_8c}{
\section{RNG.c File Reference}
\label{RNG_8c}\index{RNG.c@{RNG.c}}
}
Utility for configuring a pool of memory as a ring buffer. 

{\tt \#include \char`\"{}PBS/BUG.h\char`\"{}}\par
{\tt \#include \char`\"{}PBS/RNG.h\char`\"{}}\par
{\tt \#include \char`\"{}PBS/TOC.ih\char`\"{}}\par
{\tt \#include \char`\"{}RW\_\-tmr.ih\char`\"{}}\par


Include dependency graph for RNG.c:\begin{figure}[H]
\begin{center}
\leavevmode
\includegraphics[width=354pt]{RNG_8c__incl}
\end{center}
\end{figure}
\subsection*{Data Structures}
\begin{CompactItemize}
\item 
struct \hyperlink{struct__RNG__dyn}{\_\-RNG\_\-dyn}
\begin{CompactList}\small\item\em The dynamic component of the ring buffer. \item\end{CompactList}\item 
struct \hyperlink{struct__RNG__rcb}{\_\-RNG\_\-rcb}
\begin{CompactList}\small\item\em Ring buffer control block. \item\end{CompactList}\end{CompactItemize}
\subsection*{Defines}
\begin{CompactItemize}
\item 
\#define \hyperlink{RNG_8c_a0}{ROUND\_\-TO}(\_\-ptr, \_\-msk)~(((unsigned int)(\_\-ptr) + \_\-msk) \& $\sim$\_\-msk)
\begin{CompactList}\small\item\em Rounds the specified pointer up to the specified binary boundary. \item\end{CompactList}\end{CompactItemize}
\subsection*{Typedefs}
\begin{CompactItemize}
\item 
typedef \hyperlink{struct__RNG__dyn}{\_\-RNG\_\-dyn} \hyperlink{RNG_8c_a1}{RNG\_\-dyn}
\begin{CompactList}\small\item\em Typedef for \hyperlink{struct__RNG__dyn}{\_\-RNG\_\-dyn}. \item\end{CompactList}\item 
typedef \hyperlink{struct__RNG__rcb}{\_\-RNG\_\-rcb} \hyperlink{RNG_8c_a2}{RNG\_\-rcb}
\begin{CompactList}\small\item\em Typedef for struct {\em \hyperlink{struct__RNG__rcb}{\_\-RNG\_\-rcb}\/}. \item\end{CompactList}\end{CompactItemize}
\subsection*{Functions}
\begin{CompactItemize}
\item 
static void $\ast$ \hyperlink{RNG_8c_a3}{rng\_\-allocate} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, int minimum, const void $\ast$cur\-Wrt, int $\ast$allocated, const \hyperlink{struct__TOC}{TOC} $\ast$toc)
\begin{CompactList}\small\item\em The underlying workhorse allocator. \item\end{CompactList}\item 
static \hyperlink{RW__comdefs_8h_a6}{RW\_\-state} \hyperlink{RNG_8c_a4}{rng\_\-\_\-wait} (\hyperlink{struct__RW__tmr}{RW\_\-tmr} $\ast$tmr, \hyperlink{RW__comdefs_8h_a6}{RW\_\-state} state, unsigned char $\ast$volatile $\ast$rrd, unsigned char $\ast$rd, int needed)
\begin{CompactList}\small\item\em Blocks the requestor indefinitely until there is a reasonable chance enough memory has been returned to satisfy the request. \item\end{CompactList}\item 
const \hyperlink{struct__RNG__dsc}{RNG\_\-dsc} $\ast$ \hyperlink{RNG_8c_a5}{RNG\_\-dsc\_\-get} (const \hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb)
\begin{CompactList}\small\item\em Query routine to return a pointer to the ring buffer description structure. \item\end{CompactList}\item 
const \hyperlink{struct__RNG__dyn}{RNG\_\-dyn} $\ast$ \hyperlink{RNG_8c_a6}{RNG\_\-dyn\_\-get} (const \hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb)
\begin{CompactList}\small\item\em Query routine to return a pointer to the ring buffer dynamic quantities. \item\end{CompactList}\item 
int \hyperlink{RNG_8c_a7}{RNG\_\-destroy} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb)
\begin{CompactList}\small\item\em Returns any resources associated with this ring buffer. \item\end{CompactList}\item 
int \hyperlink{RNG_8c_a8}{RNG\_\-sizeof\_\-rcb} ()
\begin{CompactList}\small\item\em Returns the size of the Ring Contol Block. \item\end{CompactList}\item 
int \hyperlink{RNG_8c_a9}{RNG\_\-init} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, \hyperlink{RNG_8h_a3}{RNG\_\-type} type, void $\ast$buffer, int size, int underflow, int overflow, int alignment)
\begin{CompactList}\small\item\em Initializes the control structure for a Ring buffer. \item\end{CompactList}\item 
void $\ast$ \hyperlink{RNG_8c_a10}{RNG\_\-get} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, int request, const void $\ast$write)
\begin{CompactList}\small\item\em Non-blocking allocation request for a specified amount of memory. \item\end{CompactList}\item 
void $\ast$ \hyperlink{RNG_8c_a11}{RNG\_\-get\-W} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, int request, const void $\ast$write)
\begin{CompactList}\small\item\em Blocking allocation request for a specified amount of memory. \item\end{CompactList}\item 
void $\ast$ \hyperlink{RNG_8c_a12}{RNG\_\-get\-W\_\-toc} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, int request, const void $\ast$write, const \hyperlink{struct__TOC}{TOC} $\ast$toc)
\begin{CompactList}\small\item\em Blocking allocation request for a specified amount of memory, with timeout. \item\end{CompactList}\item 
void $\ast$ \hyperlink{RNG_8c_a13}{RNG\_\-grab} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, int minimum, const void $\ast$write, int $\ast$allocated)
\begin{CompactList}\small\item\em Non-blocking allocation request for all the remaining contigious memory, {\em i.e\/}. a greedy form of {\em RNG\_\-get\/}. \item\end{CompactList}\item 
void $\ast$ \hyperlink{RNG_8c_a14}{RNG\_\-grab\-W} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, int minimum, const void $\ast$write, int $\ast$allocated)
\begin{CompactList}\small\item\em Blocking allocation request for all the remaining contigious memory, {\em i.e\/}. a greedy form of {\em RNG\_\-get\-W\/}. \item\end{CompactList}\item 
void $\ast$ \hyperlink{RNG_8c_a15}{RNG\_\-grab\-W\_\-toc} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, int minimum, const void $\ast$write, int $\ast$allocated, const \hyperlink{struct__TOC}{TOC} $\ast$toc)
\begin{CompactList}\small\item\em Blocking allocation request for all the remaining contigious memory with a timeout, {\em i.e\/}. a greedy form of {\em RNG\_\-get\-Wtos\/}. \item\end{CompactList}\item 
int \hyperlink{RNG_8c_a16}{RNG\_\-free} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, const void $\ast$packet, int amount)
\begin{CompactList}\small\item\em Frees the requested amount of memory from the specified address. \item\end{CompactList}\item 
void $\ast$ \hyperlink{RNG_8c_a17}{RNG\_\-shrink} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb, const void $\ast$write, int left)
\begin{CompactList}\small\item\em Shrinks the previously allocated packet back to the specified address. \item\end{CompactList}\item 
int \hyperlink{RNG_8c_a18}{RNG\_\-reset} (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$rcb)
\begin{CompactList}\small\item\em If the ring buffer is empty, reset the read and write pointers to their initial positions. This can only be called if the user knows that the buffer is empty. \item\end{CompactList}\end{CompactItemize}


\subsection{Detailed Description}
Utility for configuring a pool of memory as a ring buffer. 

\begin{Desc}
\item[Author:]JJRussell - \href{mailto:russell@slac.stanford.edu}{\tt russell@slac.stanford.edu}\end{Desc}


\footnotesize\begin{verbatim}   CVS $Id: RNG.c,v 1.9 2009/03/26 01:45:57 russell Exp $

\end{verbatim}
\normalsize


\begin{Desc}
\item[SYNOPSIS]Implements a set of routines for managing a {\bf single} {\bf writer} / {\bf single} {\bf reader} ring buffer. The routines are thread and interrupt level safe, although one should {\em not\/} use the blocking forms \hyperlink{RNG_8c_a11}{RNG\_\-get\-W()} and \hyperlink{RNG_8c_a14}{RNG\_\-grab\-W()} nor any of their timeout variations in interrupt routines.\end{Desc}
The most common usage would be to have the WRITER allocate the memory and fill it. This would then be passed along to another thread which would 'read' or consume the contents, then free the memory.

While ring buffers managers are quick and simply allocators, ring buffers have their limitations. This version supports only in order allocation and deallocation. That is, one must deallocate the memory in the same order that it was allocated.

This version of ring buffer management does provide some help when the end of the ring buffer is reached. In order to keep the allocation request contigious in this case, the ring buffer may be configured with an overflow area. The ring buffer management utilities are allowed to use the overflow to satisfy an allocation request, but they never begin an allocation in the overflow area. It is the user's responsibility to specify the overflow area to be as large as the maximum size request that will be made.

The user may also configure an underflow area, which is symmetric to the overflow area, except at the top of the buffer. It's usage is a bit more esoteric. Imagine the situation of wishing to DMA 1000 bytes into a piece of memory allocated by the RNG utility. Circumstances dictate that the memory be contigious within the ring buffer pool. The DMA operation naturally demands continuity. Suppose the current state of the ring buffer is such that one is close the end of the ring buffer pool. The overflow area could be used to satisfy this request. At the end of the DMA operation, the user simply allocates the amount of memory which spilled into the overflow area at the top of the ring buffer and copies into it. The user is now pretty content. The DMA operation proceeded nicely into a chunk of contigious memory and, after the copy operation, the results are contigious in the ring buffer. So what's the problem? It's the copy operation. Suppose the ring buffer only had 4 bytes left at the bottom, leaving the user to copy 996 bytes back to the top. If the allocation could have been made 4 bytes above the top of the ring buffer, then only 4 bytes would have to be copied to the bottom. The underflow provides the memory to implement this scheme.

\begin{Desc}
\item[Warning:]After having said all that, the underflow is not yet implemented.\end{Desc}
\begin{Desc}
\item[USAGE EXAMPLE]\end{Desc}


\footnotesize\begin{verbatim}   unsigned char pool[POOL_SIZE];

   size = RNG_sizeof_rcb ();
   rcb  = (RNG_rcb *)MBA_alloc (size);
   RNG_init (rcb, pool, sizeof(pool), BYTE_ALIGN, RNG_K_TYPE_FIFO_PENDING);
   .
   .
   max = 1000;  / * Ask for 1000 bytes of memory * /
   msg = (unsigned char *)RNG_getW (rcb, max, NULL, RNG_K_WTO_FOREVER);
   .
   .
   / * Fill this memory, then return the used portion * /
   next = fillMemory (msg, max, &left);
   RNG_shrink (rcb, next, left);
   used = max - left;
   .
   .
   / * Return the rest of the allocated memory * /
   RNG_free (rcb, msg, used);
\end{verbatim}
\normalsize


\begin{Desc}
\item[IMPLEMENTATION NOTE 1]A circular buffer has a couple of very nice properties. The one exploited here is one can implement a single writer/single reader (or if you prefer, a single allocator/single freer) set of routines without the need for memory interlocks. Of course if you want the allocator to block on insufficient memory, then this is not the case. One needs a synchronization mechanism.\end{Desc}
The writer (allocator) only need modify the WRITE pointer, while the reader (freer) need only modify the READ pointer. Each may reference the contents of the other pointer. These references may be 'stale', in the sense that the actual value may change, but the consequences of this are beign. For instance, consider the allocater. It must determine how much memory is still available in the pool. It does this by calculating the distance between the READ and WRITE pointers. Potentially, a freer could interrupt this thread of execution just after this value is calculated. However, all this really means is that the allocator may not see all the memory that is available at that exact instance in time. So two things will happen in this case

1. There is enough memory to satisfy the request 2. There is not enough memory to satisfy the request

In the first case, all is well, the allocator got what he wanted. In the second case, the allocator is forced to retry. This is really no different than if the allocator had been called slightly sooner (before the free routine could put back the memory), so unless there is some highly determinestic reason which sequences the allocator and freer, this is just the luck of the draw.

There is, as always, one complication; how to distinguish the completely full state from the completely empty state. The tact taken here is to always contain the WRITE pointer within the pool, but, when the pool is completely empty, to represent the READ pointer by the WRITE pointer + the size of the buffer. This means that the READ buffer can potentially point outside the buffer. This is okay, provided that anytime this value is used, it is first checked to see if it is outside the pool. It can then be constrained to be within the pool simply be subtracting the size of the pool.

The WRITE (allocator) does this when the distance between the two pointers is calculated. If this distance is the size of the pool, read pointer can be safely pushed to it's value - length of the pool. There is no danger of the FREER manipulating the pointer, since all the memory is allocated, ie there is no $\ast$$\ast$legitimate$\ast$$\ast$ reason for the free routine to be called.

\begin{Desc}
\item[IMPLEMENTATION NOTE 2]These first two variables WR and RD can potentially be modified from different threads, so references to these values cannot be optimized out. After much experimenting, I finally landed on the following syntax for declaring the value of the pointer to be volatile. Note that this is not the same as\end{Desc}
volatile unsigned char $\ast$adr;

This declares the contents at the location adr to be volatile, not the value of adr. The former is what one usually wants, but in this case, it is the value of adr that is volatile.

Without the volatile declaration the optimizer is free to tranform

w1 = rcb-$>$wr; w1 = rcb-$>$wr; w2 = rcb-$>$wr; into w2 = w1; w3 = rcb-$>$wr; w3 = w1;

If rcb-$>$wr is being modified from another thread of execution, this is incorrect.

\subsection{Define Documentation}
\hypertarget{RNG_8c_a0}{
\index{RNG.c@{RNG.c}!ROUND_TO@{ROUND\_\-TO}}
\index{ROUND_TO@{ROUND\_\-TO}!RNG.c@{RNG.c}}
\subsubsection[ROUND\_\-TO]{\setlength{\rightskip}{0pt plus 5cm}\#define ROUND\_\-TO(\_\-ptr, \_\-msk)~(((unsigned int)(\_\-ptr) + \_\-msk) \& $\sim$\_\-msk)}}
\label{RNG_8c_a0}


Rounds the specified pointer up to the specified binary boundary. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em \_\-ptr}]The pointer to round \item[{\em \_\-msk}]Bit mask corresponding to the binary boundary, ie round to 4, {\em \_\-msk\/} = 3, round to 8, {\em \_\-msk\/} = 7, etc \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]The specified pointer rounded up to the specified binary boundary.\end{Desc}


\subsection{Typedef Documentation}
\hypertarget{RNG_8c_a1}{
\index{RNG.c@{RNG.c}!RNG_dyn@{RNG\_\-dyn}}
\index{RNG_dyn@{RNG\_\-dyn}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-dyn]{\setlength{\rightskip}{0pt plus 5cm}\hyperlink{struct__RNG__dyn}{RNG\_\-dyn}}}
\label{RNG_8c_a1}


Typedef for \hyperlink{struct__RNG__dyn}{\_\-RNG\_\-dyn}. 

This is an internal structure. It is available as a package private structure for debugging purposes, but, otherwise is not exposed to the user.

While the user is free to cache a pointer to this structure, he is not free to cache the values; they are dynamic. Furthermore, all the quantities are declared volatile, making it illegal for the compiler to cache them.\hypertarget{RNG_8c_a2}{
\index{RNG.c@{RNG.c}!RNG_rcb@{RNG\_\-rcb}}
\index{RNG_rcb@{RNG\_\-rcb}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-rcb]{\setlength{\rightskip}{0pt plus 5cm}\hyperlink{struct__RNG__rcb}{RNG\_\-rcb}}}
\label{RNG_8c_a2}


Typedef for struct {\em \hyperlink{struct__RNG__rcb}{\_\-RNG\_\-rcb}\/}. 

This structure contains all the context information needed to describe and control a ring buffer.

\subsection{Function Documentation}
\hypertarget{RNG_8c_a4}{
\index{RNG.c@{RNG.c}!rng__wait@{rng\_\-\_\-wait}}
\index{rng__wait@{rng\_\-\_\-wait}!RNG.c@{RNG.c}}
\subsubsection[rng\_\-\_\-wait]{\setlength{\rightskip}{0pt plus 5cm}static \hyperlink{RW__comdefs_8h_a6}{RW\_\-state} rng\_\-\_\-wait (\hyperlink{struct__RW__tmr}{RW\_\-tmr} $\ast$ {\em tmr}, \hyperlink{RW__comdefs_8h_a6}{RW\_\-state} {\em state}, unsigned char $\ast$volatile $\ast$ {\em rrd}, unsigned char $\ast$ {\em rd}, int {\em needed})\hspace{0.3cm}{\tt  \mbox{[}inline, static\mbox{]}}}}
\label{RNG_8c_a4}


Blocks the requestor indefinitely until there is a reasonable chance enough memory has been returned to satisfy the request. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em tmr}]The RW timer control structure \item[{\em state}]The current state of {\em tmr\/}. \item[{\em rrd}]The address of read pointer \item[{\em rd}]The current value of the read pointer \item[{\em needed}]The amount of memory needed \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]The update RW timer state\end{Desc}
\hypertarget{RNG_8c_a3}{
\index{RNG.c@{RNG.c}!rng_allocate@{rng\_\-allocate}}
\index{rng_allocate@{rng\_\-allocate}!RNG.c@{RNG.c}}
\subsubsection[rng\_\-allocate]{\setlength{\rightskip}{0pt plus 5cm}static void $\ast$ rng\_\-allocate (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, int {\em request}, const void $\ast$ {\em write}, int $\ast$ {\em allocated}, const \hyperlink{struct__TOC}{TOC} $\ast$ {\em toc})\hspace{0.3cm}{\tt  \mbox{[}static\mbox{]}}}}
\label{RNG_8c_a3}


The underlying workhorse allocator. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The ring buffer control block\item[{\em request}]The requested amount of memory to acquire. If the {\em allocated'\/} parameter is NULL, this is interpretted as the exact amount to allocate. If the {\em allocated\/} parameter is non-NULL, then this is interpretted as the minimum amount to allocate.\item[{\em write}]The predicted value of the next write pointer. This should be the value of the last allocated memory address + its size. This is used for integrity checking. If one wishes to live dangerously, NULL may be specified, in which case no check is performed\item[{\em allocated}]Returned as the size actually allocated. This may be NULL, in which case the allocated amount is exactly the {\em requested\/}. If not NULL, all the available contigious memory is allocated. In this case, the request is treated as a minimum allocation.\item[{\em toc}]The timeout control block. This controls the type of timeout's that are requested.\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If successful, a pointer to the allocated memory. If not, then NULL. NULL will occur if there is an error (the write pointer does not match the expected) or in the case of a timeout.\end{Desc}
This is the workhouse allocator. All other versions of allocating memory get funnelled into this routine. The versions are distinguished by the value of the parameters. In particular, {\em allocated\/} and {\em toc\/} parameters.

The allocation does not execute that many lines of code, but there are a couple of cases and some subtle details to consider, so this routine looks considerably bulker than one might suspect. The complexity is in the number of cases that most be handled. Both the dispatching to the proper case and the code within the proper case are quick, its just that there are a number of cases to handle.

The code is heavily commented, defining the cases and the sublities. Some of these comments refer to the diagram below which defines and describes the various states the ring buffer may be in.

{\bf DETAILS} \par
 {\bf -------} \par
 In order to do the allocation, one must determine which of three possible states of the ring buffer is in. These three scenerios which are distinguished by the sign of RD - WR. The third scenerio is when the buffer is completely empty. One could legitimately force the WR and RD pointers to the top and bottom of the buffers, but this would kill the useful (debugging) feature of the ring buffer, ie to treat it as a history buffer. So this case is treated as a degenerate version of the second case.

The diagrams below are meant to illustrate 2 these 3 cases. The allocated memory is indicated by the x's, while the free memory is indicated by the blank spaces. WR and RD represent the current values of the WRITE and READ pointers.



\footnotesize\begin{verbatim}            RD - WR > 0                  RD - WR < 0

        +-----------------+          +----------------+
        |xxxxxxxxxxxxxxxxx|          |                |
        |xxxxxxxxxxxxxxxxx|          |   FREE SPACE   |
        |xxxxxxxxxxxxxxxxx|          |                |
        |xxxxxxxxxxxxxxxxx|      RD  +----------------+
    WR  +-----------------+          |xxxxxxxxxxxxxxxx|
        |                 |          |xxxxxxxxxxxxxxxx|
        |   FREE SPACE    |          |xxxxxxxxxxxxxxxx|
        |                 |          |xxxxxxxxxxxxxxxx|
        |                 |          |xxxxxxxxxxxxxxxx|
    RD  +-----------------+          |xxxxxxxxxxxxxxxx|
        |xxxxxxxxxxxxxxxxx|      WR  +----------------+
        |xxxxxxxxxxxxxxxxx|          |                |
        |xxxxxxxxxxxxxxxxx|          |  FREE SPACE    |
        |xxxxxxxxxxxxxxxxx|          |                |
        +-----------------+          +----------------+

  \end{verbatim}
\normalsize


{\bf CASE} 1: RD - WR $>$ 0 \par
 There is one free area of memory which starts at the current WS pointer and continues to th current READ pointer. This case is straight-forward, either the amount of memory satisfies the requested size or it doesn't.

{\bf CASE} 2: RD - WR $<$ 0 \par
 There are two free areas of memory. The first choice is to try to satisfy the request by the piece which extends from the current WRITE to the end of the memory pool. If this does not satisfy the request, the amount from the beginning of the pool to the current READ pointer is tried. If this works one must 'remember' the abandoned piece so that it gets properly freed. In some sense, this piece is internally allocated. When the READ pointer catches up to this location (by doing RNG\_\-free's) this shard of memory is also freed.

{\bf CASE} 3: RD - WR = 0 (actually the SIZE of the POOL) \par
 This indicates that the buffer is completely empty. For the most part, this is treated exactly as CASE 2. The one exception is when neither space is big enough to satisfy the request. In this case, since the entire buffer is empty, one can move the WR to the beginning of the buffer and the RD pointer to the bottom. This somewhat destroys the buffer for use as a history buffer, but, the alternative is to deny the caller the memory, even though it is available.\hypertarget{RNG_8c_a7}{
\index{RNG.c@{RNG.c}!RNG_destroy@{RNG\_\-destroy}}
\index{RNG_destroy@{RNG\_\-destroy}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-destroy]{\setlength{\rightskip}{0pt plus 5cm}int RNG\_\-destroy (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb})}}
\label{RNG_8c_a7}


Returns any resources associated with this ring buffer. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block \end{description}
\end{Desc}
\begin{Desc}
\item[Return values:]
\begin{description}
\item[{\em Status}]Frees any internally gathered resources associated with the specified ring buffer. The {\em rcb\/} is no longer usable as ring buffer after this call.\end{description}
\end{Desc}
\begin{Desc}
\item[Warning:]It is the user's responsibility to dispose of the memory associated with the buffer that was being managed and the memory containing the Ring Control Block.\end{Desc}
\hypertarget{RNG_8c_a5}{
\index{RNG.c@{RNG.c}!RNG_dsc_get@{RNG\_\-dsc\_\-get}}
\index{RNG_dsc_get@{RNG\_\-dsc\_\-get}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-dsc\_\-get]{\setlength{\rightskip}{0pt plus 5cm}void $\ast$ RNG\_\-dsc\_\-get (const \hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb})}}
\label{RNG_8c_a5}


Query routine to return a pointer to the ring buffer description structure. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The ring control block \end{description}
\end{Desc}
\begin{Desc}
\item[Return values:]
\begin{description}
\item[{\em A}]pointer to ring buffer description\end{description}
\end{Desc}
Returns a pointer to the ring buffer description structure. This structure contains all the static information about the ring buffer. Because these properties are static, the user may cache a pointer to this structure or the value of any of its elements. They will not change from the time the ring buffer is initialized until it is destroyed.

Here is a overview of the elements and there use.

{\em beg\/} This a pointer to the top of the underflow portion of the buffer. If if there is no underflow area, this will be the same as {\em rbeg\/}. Because of alignment reason, this pointer may or may not agree with the original buffer pointer passed in by the user.

{\em rbeg\/} Pointer to the top of the ring buffer proper.

{\em rend\/} Pointer to the bottom of the ring buffer proper. Also, by definition, the start of the overflow area.

{\em end\/} Pointer to the bottom of the overflow area.

{\em msk\/} The alignment mask, for shorts = 1, ints = 3, long long = 7

{\em buf\/} The original buffer pointer passed into RCB\_\-init by the user. This routine along with {\em bufsize\/} allows the user to recover the original address and size of the pool of memory the RNG utilities where requested to manage. This may be useful when closing the ring buffer, allowing the user to return the managed memory to where ever it came from.

{\em bufsize\/} The size of the original buffer\hypertarget{RNG_8c_a6}{
\index{RNG.c@{RNG.c}!RNG_dyn_get@{RNG\_\-dyn\_\-get}}
\index{RNG_dyn_get@{RNG\_\-dyn\_\-get}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-dyn\_\-get]{\setlength{\rightskip}{0pt plus 5cm}const \hyperlink{struct__RNG__dyn}{RNG\_\-dyn} $\ast$ RNG\_\-dyn\_\-get (const \hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb})}}
\label{RNG_8c_a6}


Query routine to return a pointer to the ring buffer dynamic quantities. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The ring control block \end{description}
\end{Desc}
\begin{Desc}
\item[Return values:]
\begin{description}
\item[{\em A}]pointer to ring buffer description\end{description}
\end{Desc}
Returns a pointer to the ring buffer dynamic structure. This structure contains most of the dynamic information about the ring buffer. While the user may cache a pointer to this structure, because these properties are dynamic, the user may cache a pointer

{\em rd\/} 

{\em wr\/} Whereas many of the other query routines return pointers or values that are static and valid once the ring buffer has been initialized, this pointer is dynamic. Let the user beware.

{\em shard\/} Fetch a pointer to an potential shard. A shard is defined as an internally allocated piece of memory. The shard, by definition, occurs at the end of the buffer, absorbing the unallocated memory from the last allocation to the end of the buffer. The shard is left when the next allocation cannot be fulfilled by this remaining piece of memory, but there is enough memory at the top of the buffer. In this case, the allocation routine abandons this shard of memory, but notes it as such. When the memory preceding this shard is freed, the shard will be freed also.

Almost by definition, ring buffers configured with an overflow area will never have a shard. The caller has agreed that the overflow are will always cover any allocation, hence no shard will ever exist in this case.\hypertarget{RNG_8c_a16}{
\index{RNG.c@{RNG.c}!RNG_free@{RNG\_\-free}}
\index{RNG_free@{RNG\_\-free}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-free]{\setlength{\rightskip}{0pt plus 5cm}int RNG\_\-free (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, const void $\ast$ {\em packet}, int {\em amount})}}
\label{RNG_8c_a16}


Frees the requested amount of memory from the specified address. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block \item[{\em packet}]The pointer where the free begins \item[{\em amount}]The amount of memory to free \end{description}
\end{Desc}
\begin{Desc}
\item[Return values:]
\begin{description}
\item[{\em 0}]Successful \item[{\em -1}]Packet being freed is not contigous with the previous packet being freed \item[{\em -2}]Packet being freed extended into the shard area. Since this area is owned by the ring buffer and cannot belong to the user, this is a user specification error.\end{description}
\end{Desc}
Frees the requested {\em amount\/} of memory beginning at {\em ptr\/}. Note that, unlike many other allocators, RNG\_\-free allows partial freeing. One is not obligated to match allocations and deallocations. The only restriction is that the free {\em ptr\/} must be consistent with the next location to be freed by the Ring Buffer utilities, and that one frees only that which is allocated.

If fails, the current read pointer is returned. The only practical reason for failing is that the packet being freed is does not match the current read pointer. Currently there is no sanity check to prevent the user from freeing more memory than is actually allocated. That is fairly expensive and, the thought is, if one does this, the next free is going to fail. This is a little dicey, but see how this works. If it doesn't will add the proper sanity check.

There is one case where overfreeing is detected, that is when the packet being freed extends into the user area. As compared with detecting an arbritary overfree, this one is relatively cheap, so it is done.\hypertarget{RNG_8c_a10}{
\index{RNG.c@{RNG.c}!RNG_get@{RNG\_\-get}}
\index{RNG_get@{RNG\_\-get}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-get]{\setlength{\rightskip}{0pt plus 5cm}void $\ast$ RNG\_\-get (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, int {\em request}, const void $\ast$ {\em write})}}
\label{RNG_8c_a10}


Non-blocking allocation request for a specified amount of memory. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block\item[{\em request}]The size of the request, in bytes.\item[{\em write}]The end of the previously allocated block. Given the loose nature of ring buffers, this is used as an integrity check. If one is feeling brave, this may be specified as NULL. Doing this will skip the integrity checking.\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If successful, a pointer to the allocated memory, else NULL.\end{Desc}
Attempts to allocate the requested amount of memory. If insufficient memory is available or the {\em write\/} pointer is inconsistent with the internal write pointer, NULL is returned. The user can distinguish these two cases by calling {\em RNG\_\-wr()\/}, to fetch the current value of the write pointer. The user may also live dangerously and specify NULL for the {\em write\/} argument, in which case the consistency check is bypassed. No check is made to see if the request is for more memory than can ever be satisfied.

\begin{Desc}
\item[Special Cases]If the request is for 0 bytes, the next write pointer is returned. This allows the user to refresh where in the buffer the next write will come from. Alternatively, the user can use this value to check his own prejudice on the value of the next write pointer.\end{Desc}
\begin{Desc}
\item[Note:]Remember, this is used as an integrity check. In some cases, the value of the returned write pointer will not match this value because of the wrap-around nature of ring buffers. Effectively all values of the write pointer past the end of the ring buffer proper must be remapped to the beginning of the ring buffer. Maybe a better way to thing of the {\em write\/} pointer is as the value at the end of the last allocation. It only so happens that a large fraction of the time this value is also the value of returned by the next get.\end{Desc}
\hypertarget{RNG_8c_a11}{
\index{RNG.c@{RNG.c}!RNG_getW@{RNG\_\-getW}}
\index{RNG_getW@{RNG\_\-getW}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-getW]{\setlength{\rightskip}{0pt plus 5cm}void $\ast$ RNG\_\-get\-W (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, int {\em request}, const void $\ast$ {\em write})}}
\label{RNG_8c_a11}


Blocking allocation request for a specified amount of memory. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block\item[{\em request}]The size of the request, in bytes.\item[{\em write}]The end of the previously allocated block. Given the loose nature of ring buffers, this is used as an integrity check. If one is feeling brave, this may be specified as NULL. Doing this will skip the integrity checking.\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If successful, a pointer to the allocated memory, else NULL.\end{Desc}
Attempts to allocate the requested amount of memory. If insufficient memory is available {\em RNG\_\-get\-W\/} blocks until the requested amount is available. No check is made to see if the request is for more memory than can every be satisfied.

If the {\em write\/} pointer is inconsistent with the internal write pointer, NULL is returned. The user can distinguish these two cases by calling {\em RNG\_\-wr()\/}, to fetch the current value of the write pointer. The user may also live dangerously and specify NULL for the {\em write\/} argument, in which case the consistency check is bypassed.\hypertarget{RNG_8c_a12}{
\index{RNG.c@{RNG.c}!RNG_getW_toc@{RNG\_\-getW\_\-toc}}
\index{RNG_getW_toc@{RNG\_\-getW\_\-toc}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-getW\_\-toc]{\setlength{\rightskip}{0pt plus 5cm}void $\ast$ RNG\_\-get\-W\_\-toc (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, int {\em request}, const void $\ast$ {\em write}, const \hyperlink{struct__TOC}{TOC} $\ast$ {\em toc})}}
\label{RNG_8c_a12}


Blocking allocation request for a specified amount of memory, with timeout. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block\item[{\em request}]The size of the request, in bytes\item[{\em write}]The end of the previously allocated block. Given the loose nature of ring buffers, this is used as an integrity check. If one is feeling brave, this may be specified as NULL. Doing this will skip the integrity checking.\item[{\em toc}]The timeout control structure. This specifies the timeout value. TOC\_\-NOWAIT and TOC\_\-FOREVER may be specified here, although in this case the user should consider using {\em RNG\_\-get\/} or {\em RNG\_\-get\-W\/}.\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If successful, a pointer to the allocated memory, else NULL.\end{Desc}
Attempts to allocate the requested amount of memory. If insufficient memory is available {\em RNG\_\-get\-W\/} blocks until the requested amount is available or until the timeout period has expired. No check is made to see if the request is for more memory than can every be satisfied.

If the {\em write\/} pointer is inconsistent with the internal write pointer, NULL is returned. The user can distinguish these two cases by calling {\em RNG\_\-wr()\/}, to fetch the current value of the write pointer. The user may also live dangerously and specify NULL for the {\em write\/} argument, in which case the consistency check is bypassed.\hypertarget{RNG_8c_a13}{
\index{RNG.c@{RNG.c}!RNG_grab@{RNG\_\-grab}}
\index{RNG_grab@{RNG\_\-grab}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-grab]{\setlength{\rightskip}{0pt plus 5cm}void $\ast$ RNG\_\-grab (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, int {\em minimum}, const void $\ast$ {\em write}, int $\ast$ {\em allocated})}}
\label{RNG_8c_a13}


Non-blocking allocation request for all the remaining contigious memory, {\em i.e\/}. a greedy form of {\em RNG\_\-get\/}. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block\item[{\em minimum}]The minimum size requested, in bytes.\item[{\em write}]The end of the previously allocated block. Given the loose nature of ring buffers, this is used as an integrity check. If one is feeling brave, this may be specified as NULL. Doing this will skip the integrity checking.\item[{\em allocated}]Pointer to receive the actual amount, in bytes, that was allocated.\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If successful, a pointer to the allocated memory, else NULL.\end{Desc}
This is a greedy form of allocation. All the contigious memory from the current write pointer on is allocated to the caller provided this amount is larger than the minimum requested. This allows the user to continually fill memory even if does not know at allocation time how much is needed. This routine is often used with \hyperlink{RNG_8c_a17}{RNG\_\-shrink()}. Here one allocates as much as one can with RNG\_\-grab, uses what he wants, then returns the unused portion by calling \hyperlink{RNG_8c_a17}{RNG\_\-shrink()}.

If there is less than the minimum amount of memory in the pool, NULL is returned.\hypertarget{RNG_8c_a14}{
\index{RNG.c@{RNG.c}!RNG_grabW@{RNG\_\-grabW}}
\index{RNG_grabW@{RNG\_\-grabW}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-grabW]{\setlength{\rightskip}{0pt plus 5cm}void $\ast$ RNG\_\-grab\-W (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, int {\em minimum}, const void $\ast$ {\em write}, int $\ast$ {\em allocated})}}
\label{RNG_8c_a14}


Blocking allocation request for all the remaining contigious memory, {\em i.e\/}. a greedy form of {\em RNG\_\-get\-W\/}. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block\item[{\em minimum}]The minimum size requested, in bytes.\item[{\em write}]The end of the previously allocated block. Given the loose nature of ring buffers, this is used as an integrity check. If one is feeling brave, this may be specified as NULL. Doing this will skip the integrity checking.\item[{\em allocated}]Pointer to receive the actual amount, in bytes, that was allocated.\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If successful, a pointer to the allocated memory, else NULL.\end{Desc}
This is a greedy form of allocation. All the contigious memory from the current write pointer on is allocated to the caller provided this amount is larger than the minimum requested. This allows the user to continually fill memory even if does not know at allocation time how much is needed. This routine is often used with \hyperlink{RNG_8c_a17}{RNG\_\-shrink()}. Here one allocates as much as one can with RNG\_\-grab, uses what he wants, then returns the unused portion by calling \hyperlink{RNG_8c_a17}{RNG\_\-shrink()}.

If there is less than the minimum amount of memory in the pool, {\em RNG\_\-grab\-W\/} waits until the memory shows up. NULL is only on an internal error.\hypertarget{RNG_8c_a15}{
\index{RNG.c@{RNG.c}!RNG_grabW_toc@{RNG\_\-grabW\_\-toc}}
\index{RNG_grabW_toc@{RNG\_\-grabW\_\-toc}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-grabW\_\-toc]{\setlength{\rightskip}{0pt plus 5cm}void $\ast$ RNG\_\-grab\-W\_\-toc (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, int {\em minimum}, const void $\ast$ {\em write}, int $\ast$ {\em allocated}, const \hyperlink{struct__TOC}{TOC} $\ast$ {\em toc})}}
\label{RNG_8c_a15}


Blocking allocation request for all the remaining contigious memory with a timeout, {\em i.e\/}. a greedy form of {\em RNG\_\-get\-Wtos\/}. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block\item[{\em minimum}]The minimum size of the request, in bytes.\item[{\em write}]The end of the previously allocated block. Given the loose nature of ring buffers, this is used as an integrity check. If one is feeling brave, this may be specified as NULL. Doing this will skip the integrity checking.\item[{\em allocated}]Returned as the amount of memory actually allocated.\item[{\em toc}]The timeout control structure. This specifies the timeout value. TOC\_\-NOWAIT and TOC\_\-FOREVER may be specified here, although in this case the user should consider using {\em RNG\_\-grab\/} or {\em RNG\_\-grab\-W\/}.\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If successful, a pointer to the allocated memory, else NULL.\end{Desc}
Attempts to allocate the requested amount of memory. If insufficient memory is available {\em RNG\_\-grab\-W\/} blocks until the requested amount is available or until the timeout period has expired. No check is made to see if the request is for more memory than can every be satisfied.

If the {\em write\/} pointer is inconsistent with the internal write pointer, NULL is returned. The user can distinguish these two cases by calling {\em RNG\_\-wr()\/}, to fetch the current value of the write pointer. The user may also live dangerously and specify NULL for the {\em write\/} argument, in which case the consistency check is bypassed.\hypertarget{RNG_8c_a9}{
\index{RNG.c@{RNG.c}!RNG_init@{RNG\_\-init}}
\index{RNG_init@{RNG\_\-init}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-init]{\setlength{\rightskip}{0pt plus 5cm}int RNG\_\-init (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, \hyperlink{RNG_8h_a3}{RNG\_\-type} {\em type}, void $\ast$ {\em buffer}, int {\em size}, int {\em underflow}, int {\em overflow}, int {\em alignment})}}
\label{RNG_8c_a9}


Initializes the control structure for a Ring buffer. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]Pointer to the ring buffer control block structure to be initialized.\item[{\em type}]Indicates the type of ring buffer. This mainly controls the blocking. If insufficient memory is available, the allocation calls will block until it becomes available or a timeout occurs.\item[{\em buffer}]The buffer to be managed\item[{\em size}]The total size of the buffer (in bytes) to be managed\item[{\em underflow}]The size (in bytes) to be assigned to the underflow area. This area is an area immediately preceeding the ring buffer area.\end{description}
\end{Desc}
\begin{Desc}
\item[Warning:]Currently this feature is not implemented and should be specified as 0. It is provided for forward compatibility.\end{Desc}
\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em overflow}]The size (in bytes) to be assigned to the overflow area. This area carved from the end {\em buf\/}. The useful property of the overflow area is that while memory may be allocated from the overflow area, an initial allocation never begins in the overflow area. This allows some continuity when the wrap-around point of the ring buffer is encountered.\end{description}
\end{Desc}
This number may be 0, but must be less than the total size since it taken from the total size.

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em alignment}]The byte alignment, expressed in binary powers of 2, eg\begin{itemize}
\item 0 =$>$ 1 byte alignment\item 1 =$>$ 2 byte alignment\item 2 =$>$ 4 byte alignment\item 3 =$>$ 8 byte alignment\end{itemize}
\end{description}
\end{Desc}
\begin{Desc}
\item[Return values:]
\begin{description}
\item[{\em Status}]Initializes a Ring Control Block to manage a pool of memory. The memory is carved into three pieces, an underflow area, a ring buffer area, and an overflow area. The detailed use and meaning of these areas is described elsewhere.\end{description}
\end{Desc}
\hypertarget{RNG_8c_a18}{
\index{RNG.c@{RNG.c}!RNG_reset@{RNG\_\-reset}}
\index{RNG_reset@{RNG\_\-reset}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-reset]{\setlength{\rightskip}{0pt plus 5cm}int RNG\_\-reset (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb})}}
\label{RNG_8c_a18}


If the ring buffer is empty, reset the read and write pointers to their initial positions. This can only be called if the user knows that the buffer is empty. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If 0 is successful else ERROR (-1). The only plausible error is that a reset was requested on a buffer that was not empty.\end{Desc}
Unlike many allocators a Ring Buffer has many states that correspond to the empty state. Consider the initial state, the read pointer is at the bottom of the buffer and the write pointer is at the top. After on allocation the read pointer is at the top of the buffer and the write pointer is at the end of the allocated buffer. If the buffer is now freed, the read pointer advances to the write pointer. The ring buffer is now totally empty, however, it is a different {\em empty\/} state than the original {\em empty\/} state. One consequence of this is that a request on the original state could be as large as the entire ring buffer and succeed. However, the same request on the second empty state would fail. This is because the largest contigious block availabe is from the current write pointer to the end of the buffer. Since the write pointer is not at the top of the buffer, this contigious block is necessarily smaller.

So, one may ask, why not just reset the pointers to the empty state any time the ring buffer is totally empty. The answer is that this destroys any history that the ring buffer may accumulate. Imagine the case where one allocates some memory and then immediately frees it. The current implementation would deliver a different memory block each time. In a debugging mode, one could go back and examine this memory for some clues. If the buffer pointers where to be continually reset, this the memory would always be allocated from the top of the pool, and this debugging feature would be lost.

One possible alternative would be to make this resetting a optional configuration parameter on the ring buffer initialization. That way this would happen automatically.\hypertarget{RNG_8c_a17}{
\index{RNG.c@{RNG.c}!RNG_shrink@{RNG\_\-shrink}}
\index{RNG_shrink@{RNG\_\-shrink}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-shrink]{\setlength{\rightskip}{0pt plus 5cm}void $\ast$ RNG\_\-shrink (\hyperlink{struct__RNG__rcb}{RNG\_\-rcb} $\ast$ {\em rcb}, const void $\ast$ {\em write}, int {\em left})}}
\label{RNG_8c_a17}


Shrinks the previously allocated packet back to the specified address. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em rcb}]The Ring Control Block\item[{\em write}]The address to shrink to. The current write pointer, up to alignment factors, is moved to this address.\item[{\em left}]The unused amount, in bytes, of the previously allocated packet. This value + {\em write\/} addresss must match the current write pointer. If not, error. Note that the amount being returned must be consistent with the alignment factors. Concretely stated, if one demands 8-byte alignment, one cannot return in units less than 8-bytes.\end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]If successful, the next write pointer. Due to alignment reasons, this may or may not be the same as {\em write\/}. If NULL, error.\end{Desc}
Routine shrinks the previously allocated packet back to the specified address. A check is performed to see if this {\em write\/} pointer plus the number of bytes {\em left\/} in the old allocation is consistent with the Ring Buffer Manager's internal write pointer. If not, NULL is returned.

Typically one would allocate a block of memory, and fill it by advancing the pointer returned and decreasing the amount left. After filling the buffer, one would then call RNG\_\-shrink to return the unused portion. The parameters to {\em RNG\_\-shrink\/} will be the address of the next location to be written and the amount left.

Note also that this has no consequences on waking anyone up who may be waiting for memory. By definition, this is a single allocator system. Since, RNG\_\-shrink is really just extension of the allocation process, no one can be waiting.

{\bf EXAMPLE} \par
 {\bf -------} \par




\footnotesize\begin{verbatim}      amount = 100;
      ptr    = RNG_get (rcb, amount, prv);
      if (ptr == NULL) perror ("No memory\n");

      *ptr++ = 0xdeadbeef;  amount -= 1;
      *ptr++ = 0xabadbabe;  amount -= 1;

      chk    = RNG_shrink (rcb, ptr, amount);
      if (chk == NULL) perror ("Bad shrink\n");
\end{verbatim}
\normalsize
\hypertarget{RNG_8c_a8}{
\index{RNG.c@{RNG.c}!RNG_sizeof_rcb@{RNG\_\-sizeof\_\-rcb}}
\index{RNG_sizeof_rcb@{RNG\_\-sizeof\_\-rcb}!RNG.c@{RNG.c}}
\subsubsection[RNG\_\-sizeof\_\-rcb]{\setlength{\rightskip}{0pt plus 5cm}int RNG\_\-sizeof\_\-rcb (void)}}
\label{RNG_8c_a8}


Returns the size of the Ring Contol Block. 

\begin{Desc}
\item[Return values:]
\begin{description}
\item[{\em The}]size of a Ring Control Block\end{description}
\end{Desc}
This routine allows the user to allocate or set aside a block of memory to be used as Ring Control Block. It is the first step when initializing a Ring Control buffer. This routine allows the implementation to hide the internal structure of a Ring Control Block, but still allow the user to control its allocation.