GLAST/LAT > DAQ and FSW > FSW > Doxygen Index > PBS / V2-10-15
Constituent: pbs     Tag: mv2304
#include "PBS/RW_type.h"
#include "PBS/TOC_comdefs.h"
#include "PBS/TOV.h"
Include dependency graph for RNG.h:
This graph shows which files directly or indirectly include this file:
Data Structures | |
struct | _RNG_dsc |
This describes all the static properties of the ring buffer. More... | |
Defines | |
#define | RNG_K_PTR_ERROR (1) |
Returned by either the RNG_get() or RNG_grab routines when an internal error is detected. | |
#define | RNG_PTR_IS_VALID(ptr) ( (unsigned int)ptr > RNG_K_PTR_ERROR) |
Checks that the returned pointer is valid. | |
#define | RNG_PTR_IS_ERROR(ptr) ( (unsigned int)ptr == RNG_K_PTR_ERROR) |
Checks if the pointer is indicates failure to allocate because of an error. | |
Typedefs | |
typedef enum _RNG_type | RNG_type |
Typedef for enum _RNG_type. | |
typedef _RNG_dsc | RNG_dsc |
Typedef for struct _RNG_dsc. | |
Enumerations | |
enum | _RNG_type { RNG_K_TYPE_LOCKING_ONLY = RW_K_TYPE_LOCKING_ONLY, RNG_K_TYPE_PENDING = RW_K_TYPE_PENDING, RNG_K_TYPE_PENDING_WTO = RW_K_TYPE_PENDING_WTO } |
An enumeration of the types of ring buffers that can be created. More... | |
Functions | |
const RNG_dsc * | RNG_dsc_get (const RNG_rcb *rcb) |
Query routine to return a pointer to the ring buffer description structure. | |
int | RNG_sizeof_rcb (void) |
Returns the size of the Ring Contol Block. | |
int | RNG_init (RNG_rcb *rcb, RNG_type type, void *buffer, int size, int underflow, int overflow, int alignment) |
Initializes the control structure for a Ring buffer. | |
int | RNG_destroy (RNG_rcb *rcb) |
Returns any resources associated with this ring buffer. | |
void * | RNG_get (RNG_rcb *rcb, int request, const void *write) |
Non-blocking allocation request for a specified amount of memory. | |
void * | RNG_getW (RNG_rcb *rcb, int request, const void *write) |
Blocking allocation request for a specified amount of memory. | |
void * | RNG_getW_toc (RNG_rcb *rcb, int request, const void *check_Wr, const TOC *toc) |
Blocking allocation request for a specified amount of memory, with timeout. | |
void * | RNG_grab (RNG_rcb *rcb, int minimum, const void *write, int *allocated) |
Non-blocking allocation request for all the remaining contigious memory, i.e. a greedy form of RNG_get. | |
void * | RNG_grabW (RNG_rcb *rcb, int minimum, const void *write, int *allocated) |
Blocking allocation request for all the remaining contigious memory, i.e. a greedy form of RNG_getW. | |
void * | RNG_grabW_toc (RNG_rcb *rcb, int minimum, const void *check_wr, int *allocated, const TOC *toc) |
Blocking allocation request for all the remaining contigious memory with a timeout, i.e. a greedy form of RNG_getWtos. | |
int | RNG_free (RNG_rcb *rcb, const void *packet, int amount) |
Frees the requested amount of memory from the specified address. | |
void * | RNG_shrink (RNG_rcb *rcb, const void *write, int left) |
Shrinks the previously allocated packet back to the specified address. | |
int | RNG_reset (RNG_rcb *rcb) |
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. |
CVS $Id: RNG.h,v 1.3 2003/09/27 18:52:15 russell Exp $
SYNOPSIS
Implements a set of routines for managing a single 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() nor any of their timeout variations in interrupt routines. While nothing in the code prohibits multiple writers and readers, using a ring buffer in this fashion runs is not natural. Ring buffers are really just a software implementation of a FIFO, which, by its nature, is a single writer, single reader object.
|
Returned by either the RNG_get() or RNG_grab routines when an internal error is detected.
|
|
Checks if the pointer is indicates failure to allocate because of an error.
|
|
Checks that the returned pointer is valid.
This macro checks that the pointer is not one of these values. This attempts to address the age old problem of how to indicate an error condition without resorting to an additional parameter for a status value. |
|
Typedef for struct _RNG_dsc. This structure describes all the static properties of the ring buffer. The ring buffer composed of three pieces carved out of a user provided block of memory. The three pieces are
Underflow area Main pool Overflow area Picturally the ring buffer looks like
+---------------+ beg | | | Underflow | | | +---------------+ rbeg | | | Main | | Ring | | Buffer | | | +---------------+ rend | | | Underflow | | | +---------------+ end As is common practice, the pointers to the beginning of the areas point at the real beginning and the pointers to the ending of the areas point one past the actual last address so that sizes are trivially calculated. As a convenience the address of the initial buffer, its size and the requested ring buffer type are also kept in this structure. This may be useful to the user when he later attempts to free this memory. Note that due to alignment rounding the initial buffer address and size may not match the ring buffer's beginning address and size. |
|
Typedef for enum _RNG_type. 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 blocking and with and without timeouts. Note that there is no choice as to the blocking types as one sees in the LLI facility. This is because the blocking type affects only the behavior when multiple tasks are being blocked. Given the single writer / single reader nature of the ring buffer, the issue what to do when multiple tasking are pending never comes up. If a non-blocking type is requested, common practice would be to use the simpler RNG_get() routine, since it never waits. The RNG_getWxxx and RNG_grabWxxx should not be used in this case, although their behavior is currently defined to degenerate to the RNG_get and RNG_grab, respectively. |
|
An enumeration of the types of ring buffers that can be created.
|
|
Returns any resources associated with this ring buffer.
|
|
Query routine to return a pointer to the ring buffer description structure.
Here is a overview of the elements and there use. 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 rbeg. Because of alignment reason, this pointer may or may not agree with the original buffer pointer passed in by the user. rbeg Pointer to the top of the ring buffer proper. rend Pointer to the bottom of the ring buffer proper. Also, by definition, the start of the overflow area. end Pointer to the bottom of the overflow area. msk The alignment mask, for shorts = 1, ints = 3, long long = 7 buf The original buffer pointer passed into RCB_init by the user. This routine along with 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. bufsize The size of the original buffer |
|
Frees the requested amount of memory from the specified address.
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. |
|
Non-blocking allocation request for a specified amount of memory.
|
|
Blocking allocation request for a specified amount of memory.
If the write 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 write argument, in which case the consistency check is bypassed. |
|
Blocking allocation request for a specified amount of memory, with timeout.
If the write 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 write argument, in which case the consistency check is bypassed. |
|
Non-blocking allocation request for all the remaining contigious memory, i.e. a greedy form of RNG_get.
If there is less than the minimum amount of memory in the pool, NULL is returned. |
|
Blocking allocation request for all the remaining contigious memory, i.e. a greedy form of RNG_getW.
If there is less than the minimum amount of memory in the pool, RNG_grabW waits until the memory shows up. NULL is only on an internal error. |
|
Blocking allocation request for all the remaining contigious memory with a timeout, i.e. a greedy form of RNG_getWtos.
If the write 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 write argument, in which case the consistency check is bypassed. |
|
Initializes the control structure for a Ring buffer.
|
|
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.
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. |
|
Shrinks the previously allocated packet back to the specified address.
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 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.
EXAMPLE
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"); |
|
Returns the size of the Ring Contol Block.
|