Main Page   Interface   Data Structures   File List   Data Fields   Globals  

RNG.h File Reference

Utility for configuring a pool of memory as a ring buffer. More...

#include "BBC/LLI_type.h"

Defines

#define RNG_K_WTO_NO_WAIT   (0)
 Timeout = 0, ie do not wait.

#define RNG_K_WTO_FOREVER   (-1)
 Wait forever.


Typedefs

typedef _RNG_rcb RNG_rcb
 Typedef for RNG buffer control block.

typedef enum _RNG_type RNG_type
 Typedef of the enumeration _RNG_type.


Enumerations

enum  _RNG_type {
  RNG_K_TYPE_NON_BLOCKING = LLI_K_TYPE_NON_BLOCKING,
  RNG_K_TYPE_FIFO_BLOCKING = LLI_K_TYPE_FIFO_BLOCKING,
  RNG_K_TYPE_PRIORITY_BLOCKING = LLI_K_TYPE_PRIORITY_BLOCKING
}
 The type of blocking to use when an allocation is attempted on an empty pool. More...


Functions

void * RNG_beg (const struct _RNG_rcb *rcb)
 Query routine to return a pointer to the beginning of the underflow area. More...

void * RNG_rbeg (const struct _RNG_rcb *rcb)
 Query routine to return a pointer to the beginning of the ring buffer area. More...

void * RNG_rend (const struct _RNG_rcb *rcb)
 Query routine to return a pointer to the end of the ring buffer area. More...

void * RNG_end (const struct _RNG_rcb *rcb)
 Query routine to return a pointer to the end of the overflow area. More...

void * RNG_rd (const struct _RNG_rcb *rcb)
 Query routine to return a pointer to current read pointer the ring buffer area. More...

void * RNG_wr (const struct _RNG_rcb *rcb)
 Query routine to return a pointer to the current write pointer. More...

void * RNG_shard (const struct _RNG_rcb *rcb)
 Query routine to return a pointer to current list of shards. More...

void * RNG_buf (const struct _RNG_rcb *rcb)
 Query routine to return a pointer to the original buffer. More...

int RNG_bsize (const struct _RNG_rcb *rcb)
 Query routine to return the size of the original buffer. More...

int RNG_destroy (struct _RNG_rcb *rcb)
 Returns any resources associated with this ring buffer. More...

int RNG_sizeof_rcb (void)
 Returns the size of the Ring Contol Block. More...

int RNG_init (struct _RNG_rcb *rcb, unsigned char *buf, int size, int underflow, int overflow, int alignment, RNG_type blocking)
 Initializes the control structure for a Ring buffer. More...

void * RNG_get (struct _RNG_rcb *rcb, int request, const void *chkWrt)
 Non-blocking allocation request for a specified amount of memory. More...

void * RNG_grab (struct _RNG_rcb *rcb, int minimum, const void *chkWrt, int *allocated)
 Non-blocking allocation request for all the remaining contigious memory. More...

void * RNG_getW (struct _RNG_rcb *rcb, int request, const void *chkWrt, int timeout)
 Blocking allocation request for a specified amount of memory. More...

void * RNG_grabW (struct _RNG_rcb *rcb, int minimum, const void *chkWrt, int *allocated, int timeout)
 Non-blocking allocation request for all the remaining contigious memory. More...

int RNG_free (struct _RNG_rcb *rcb, const void *packet, int amount)
 Frees the requested amount of memory from the specified address. More...

void * RNG_shrink (struct _RNG_rcb *rcb, const void *newWrt, int left)
 Shrinks the previously allocated packet back to the specified address. More...

int RNG_reset (struct _RNG_rcb *rcb)
 If the pool is empty, resets the WR/RD pointers to their initial values. More...

unsigned int RNG_usec_to_rto (unsigned int usecs)
 Converts a time, specified in usecs, to a timeout value.


Detailed Description

Utility for configuring a pool of memory as a ring buffer.

Author:
JJRussell - russell@slac.stanford.edu
ABSTRACT
--------
Implements a set of routines for managing a \bsingle writer / single reader ring buffer. The routines are thread and interrupt level safe, although one should not use the blocking forms RNG_getW() and RNG_grabW() in interrupt routines.

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.

Warning:
After having said all that, the underflow is not yet implemented.
USAGE EXAMPLE
-------------

    unsigned char pool[POOL_SIZE];
  
    size = RNG_sizeof_rcb ();
    rcb  = (struct _RNG_rcb *)malloc (size);
    RNG_init (rcb, pool, sizeof(pool), BYTE_ALIGN, RNG_K_TYPE_FIFO_BLOCKING);
    .
    .
    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);
  


Enumeration Type Documentation

enum _RNG_type
 

The type of blocking to use when an allocation is attempted on an empty pool.

This determines how the ring allocators, RNG_getW() and RNG_grabW(), calls will behave when an allocation is attempted on an empty pool. One can specify non-blocking or two types of blocking, either blocking in FIFO order or PRIORITY order. If a non-blocking type is requested, common practice would be to use the simpler RNG_get() routine, since it never waits.

Enumeration values:
RNG_K_TYPE_NON_BLOCKING  No Blocking when the pool is exhausted
RNG_K_TYPE_FIFO_BLOCKING  FIFO Blocking when the pool is exhausted
RNG_K_TYPE_PRIORITY_BLOCKING  PRIORITY blocking when the pool is exhausted


Function Documentation

void * RNG_beg const struct _RNG_rcb *    rcb
 

Query routine to return a pointer to the beginning of the underflow area.

Parameters:
rcb  The Ring Control Block
Returns:
A pointer to the beginning of the underflow area.
This routine is primarily used for debugging purposes, but is also useful when determining whether a region of memory occupies any of the underflow area. The underflow area ends at the beginning of the ring buffer area, set RNG_rbeg().

Warning:
Note that due to rounding to alignment boundaries this pointer may or may not be the same as the beginning of the original buffer.

int RNG_bsize const struct _RNG_rcb *    rcb
 

Query routine to return the size of the original buffer.

Parameters:
rcb  The Ring Control Block
Returns:
The size of the original pool of memory the RNG utilities where requested to manage.
This routine, along with RNG_buf(), returns the original buffer address and size that the RNG utilities where requested to manage. These two values may be useful when the RNG buffer is being destroyed, allowing the user to return the buffer to whereever it belongs

void * RNG_buf const struct _RNG_rcb *    rcb
 

Query routine to return a pointer to the original buffer.

Parameters:
rcb  The Ring Control Block
Returns:
A pointer to the original pool of memory the RNG utilities where requested to manage.
This routine, along with RNG_bsize(), returns the original buffer address and size that the RNG utilities where requested to manage. These two values may be useful when the RNG buffer is being destroyed, allowing the user to return the buffer to whereever it belongs.

int RNG_destroy struct _RNG_rcb *    rcb
 

Returns any resources associated with this ring buffer.

Parameters:
rcb  The Ring Control Block
Returns:
Status
Frees any internally gathered resources associated with the specified ring buffer. The rcb is no longer usable as ring buffer after this call.

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.

void * RNG_end const struct _RNG_rcb *    rcb
 

Query routine to return a pointer to the end of the overflow area.

Parameters:
rcb  The Ring Control Block
Returns:
A pointer to the end of the overflow area
This routine is primarily used for debugging purposes, but may be useful when determining whether a region of memory occupies the overflow area.

Warning:
Due to rounding to alignment boundaries, this pointer may or may not coincide with the ending of the original pool of memory the RNG utilities where asked to manage.

int RNG_free struct _RNG_rcb *    rcb,
const void *    ptr,
int    amount
 

Frees the requested amount of memory from the specified address.

Parameters:
rcb  The Ring Control Block
ptr  The pointer where the free begins
amount  The amount of memory to free
Returns:
Status
Frees the requested amount of memory beginning at 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 \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.

void * RNG_get struct _RNG_rcb *    rcb,
int    request,
const void *    chkWrt
 

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

Parameters:
rcb  The Ring Control Block
request  The size, in bytes, of the request
chkWrt  The anticipated allocation value, to within alignment factors. This maybe specified as NULL.
Returns:
If successful, a pointer to the allocated memory, else NULL.
Attempts to allocate the requested amount of memory. If insufficient memory is available or the chkWrt pointer is inconsistent with the internal write pointer, NULL is returned. The user can distinguish these two cases by calling RNG_wr(), to fetch the current value of the write pointer. The user may also live dangerously and specify NULL for the chkWrt argument, in which case the consistency check is bypassed.

void * RNG_getW struct _RNG_rcb *    rcb,
int    request,
const void *    chkWrt,
int    timeout
 

Blocking allocation request for a specified amount of memory.

Parameters:
rcb  The Ring Control Block
request  The size, in bytes, of the request
chkWrt  The anticipated allocation value, to within alignment factors. This maybe specified as NULL.
timeout  The timeout period. Currently only RNG_K_WTO_NO_WAIT (0) and RNG_K_WTO_FOREVER (-1) are supported.
Returns:
If successful, a pointer to the allocated memory, else NULL.
Attempts to allocate the requested amount of memory. If the chkWrt pointer is inconsistent with the internal write pointer, or insufficeint memory is available and the timeout period expires, NULL is returned. The user can distinguish these two cases by calling RNG_wr(), to fetch the current value of the write pointer. The user may also live dangerously and specify NULL for the chkWrt argument, in which case the consistency check is bypassed.

Warning:
Blocking on a RNG buffer that is does not have blocking enable will be treated as a NO WAIT call.

void * RNG_grab struct _RNG_rcb *    rcb,
int    minimum,
const void *    chkWrt,
int *    allocated
 

Non-blocking allocation request for all the remaining contigious memory.

Parameters:
rcb  The Ring Control Block
request  The size, in bytes, of the request
chkWrt  The anticipated allocation value, to within alignment factors. This maybe specified as NULL.
allocated  Pointer to receive the actual amount, in bytes, that was allocated.
Returns:
If successful, a pointer to the allocated memory, else NULL.
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 RNG_shrink(). Here one allocates as much as one can with RNG_grab, uses what he wants, then returns the unused portion by calling RNG_shrink().

If there is less than the minimum amount of memory in the pool, NULL is returned.

void * RNG_grabW struct _RNG_rcb *    rcb,
int    minimum,
const void *    chkWrt,
int *    allocated,
int    timeout
 

Non-blocking allocation request for all the remaining contigious memory.

Parameters:
rcb  The Ring Control Block
request  The size, in bytes, of the request
chkWrt  The anticipated allocation value, to within alignment factors. This maybe specified as NULL.
allocated  Pointer to receive the actual amount, in bytes, that was allocated.
timeout  The timeout period. Currently only RNG_K_WTO_NO_WAIT (0) and RNG_K_WTO_FOREVER (-1) are supported.
Returns:
If successful, a pointer to the allocated memory, else NULL.
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 RNG_shrink(). Here one allocates as much as one can with RNG_grab, uses what he wants, then returns the unused portion by calling RNG_shrink().

If less the timeout period expires or the internal write pointer is inconsistent with the chkWrt argument, NULL is returned. The user may distinguish these cases by calling RNG_wr().

Warning:
Blocking on a RNG buffer that is does not have blocking enable will be treated as a NO WAIT call.

int RNG_init struct _RNG_rcb *    rcb,
unsigned char *    buf,
int    size,
int    underflow,
int    overflow,
int    alignment,
RNG_type    blocking
 

Initializes the control structure for a Ring buffer.

Parameters:
rcb  The Ring Control Block
buf  The buffer to be managed
size  The size, in bytes, of the buffer to be managed
underflow  The size, in bytes, of the underflow area
overflow  The size, in bytes, of the overflow area
alignment  The desired alignment of all requests, expressed as a power of 2, eg 0 => 1 byte alignment, 1 => 2 byte alignment, 2 => 4 byte alignment, etc.
blocking  The type of blocking the user wishes. See RNG_type for the types available and their description.
Returns:
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.

void * RNG_rbeg const struct _RNG_rcb *    rcb
 

Query routine to return a pointer to the beginning of the ring buffer area.

Parameters:
rcb  The Ring Control Block
Returns:
A pointer to the beginning of the ring buffer area. By definition, this is also the end of the underflow area.
This routine is primarily used for debugging purposes, but is also useful when determining whether a region of memory occupies any of the underflow area or is in the ring buffer pool proper. The underflow area extends from the pointer returned by RNG_beg() to the pointer returned by this routine. The end of the ring buffer pool is returned from RNG_rend().

void * RNG_rd const struct _RNG_rcb *    rcb
 

Query routine to return a pointer to current read pointer the ring buffer area.

Parameters:
rcb  The Ring Control Block
Returns:
The value of the current read pointer
This routine is primarily used for debugging purposes.

Warning:
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.

void * RNG_rend const struct _RNG_rcb *    rcb
 

Query routine to return a pointer to the end of the ring buffer area.

Parameters:
rcb  The Ring Control Block
Returns:
A pointer to the end of the ring buffer area. By definition this is also the start of the overflow area.
This routine is primarily used for debugging purposes, but is also useful when determining whether a region of memory occupies either the ring buffer pool proper or the overflow area. This pointer is the boundary between those two regions.

int RNG_reset struct _RNG_rcb *    rcb
 

If the pool is empty, resets the WR/RD pointers to their initial values.

Parameters:
The  ring control block
Returns:
Status
Normally the read and write pointers are not diddle with except on allocation and deallocation. In an empty pool, the read and write pointers will can be anywhere. This means that the maximum contigious memory may not be available for use. This routine allows the user to reset these pointers to their initial positions, thus maximizing the amount of contigious memory. The downside of this move is that the Ring Buffer loses some of its 'history' feature, which may be valuable as a debugging aid.

void * RNG_shard const struct _RNG_rcb *    rcb
 

Query routine to return a pointer to current list of shards.

Parameters:
rcb  The Ring Control Block
Returns:
A pointer to any abandoned memory
Warning:
This is provided for debugging purposes only.

void * RNG_shrink struct _RNG_rcb *    rcb,
const void *    newWrt,
int    left
 

Shrinks the previously allocated packet back to the specified address.

Parameters:
rcb  The Ring Control Block
newWrt  The address to shrink to. The current write pointer, up to alignment factors, is moved to this address.
left  The number of unused bytes from the previous allocation. This is used as a consistency check.
Returns:
If successful, the next write pointer. Due to alignment reasons, this may or may not be the same as \newWrt.
Routine shrinks the previously allocated packet back to the specified address. A check is performed to see if this newWrt pointer plus the number of bytes \left in the old allocation is consistent with the Ring Buffer Manager's internal write pointer. If not, NULL is returned.

int RNG_sizeof_rcb void   
 

Returns the size of the Ring Contol Block.

Returns:
The size of a Ring Control Block
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.

void * RNG_wr const struct _RNG_rcb *    rcb
 

Query routine to return a pointer to the current write pointer.

Parameters:
rcb  The Ring Control Block
Returns:
The value of the current write pointer
This routine is primarily used for debugging purposes.

Warning:
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.


Generated on Fri Mar 1 16:56:57 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001