Removed variables that had no effect on code behavior. Fifo.c::FIFO_Dequeue: Replaced instances of "Self->ElementSize" with preexisting variable "SizeOfElement". IIOutilities.c::IIO_GetInChar: Fixed variable of wrong, but compatible, type and made updating of housekeeping variables dependent upon successful completion of reading from the buffer. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> Reviewed by: Daryl McDaniel <daryl.mcdaniel@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16276 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			526 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			526 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Class for arbitrary sized FIFO queues.
 | 
						|
 | 
						|
  The FIFO is empty if both the Read and Write indexes are equal.
 | 
						|
  The FIFO is full if the next write would make the Read and Write indexes equal.
 | 
						|
 | 
						|
  Member variable NumElements is the maximum number of elements that can be
 | 
						|
  contained in the FIFO.
 | 
						|
    If NumElements is ZERO, there is an error.
 | 
						|
    NumElements should be in the range 1:N.
 | 
						|
 | 
						|
  Members WriteIndex and ReadIndex are indexes into the array implementing the
 | 
						|
  FIFO.  They should be in the range 0:(NumElements - 1).
 | 
						|
 | 
						|
  One element of the FIFO is always reserved as the "terminator" element.  Thus,
 | 
						|
  the capacity of a FIFO is actually NumElements-1.
 | 
						|
 | 
						|
  Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
 | 
						|
  This program and the accompanying materials are licensed and made available
 | 
						|
  under the terms and conditions of the BSD License which accompanies this
 | 
						|
  distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php.
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
**/
 | 
						|
#include  <Uefi.h>
 | 
						|
#include  <Library/BaseLib.h>
 | 
						|
#include  <Library/BaseMemoryLib.h>
 | 
						|
#include  <Library/MemoryAllocationLib.h>
 | 
						|
 | 
						|
#include  <LibConfig.h>
 | 
						|
 | 
						|
#include  <assert.h>
 | 
						|
#include  <errno.h>
 | 
						|
#include  <stdlib.h>
 | 
						|
#include  <stdint.h>
 | 
						|
#include  <wchar.h>
 | 
						|
#include  <Containers/Fifo.h>
 | 
						|
 | 
						|
/** Determine number of items available to read from the FIFO.
 | 
						|
 | 
						|
    The number of items are either the number of bytes, or the number of elements
 | 
						|
    depending upon the value of the As enumerator.
 | 
						|
 | 
						|
    @param[in]    Self      Pointer to the FIFO instance.
 | 
						|
    @param[in]    As        An enumeration variable whose value determines whether the
 | 
						|
                            returned value is the number of bytes or the number of elements
 | 
						|
                            currently contained by the FIFO.
 | 
						|
 | 
						|
    @retval   0       The FIFO is empty.
 | 
						|
    @retval   >=0     The number of items contained by the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
FIFO_NumInQueue (
 | 
						|
  cFIFO        *Self,
 | 
						|
  FIFO_ElemBytes    As
 | 
						|
)
 | 
						|
{
 | 
						|
  size_t    Count;
 | 
						|
 | 
						|
  if(Self->ReadIndex <= Self->WriteIndex) {
 | 
						|
    Count = Self->WriteIndex - Self->ReadIndex;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    Count = Self->NumElements - (Self->ReadIndex - Self->WriteIndex);
 | 
						|
  }
 | 
						|
  if(As == AsBytes) {
 | 
						|
    Count *= Self->ElementSize;
 | 
						|
  }
 | 
						|
  return Count;
 | 
						|
}
 | 
						|
 | 
						|
/** Determine amount of free space in the FIFO that can be written into.
 | 
						|
 | 
						|
    The number of items are either the number of bytes, or the number of elements
 | 
						|
    depending upon the value of the As enumerator.
 | 
						|
 | 
						|
    @param[in]    Self      Pointer to the FIFO instance.
 | 
						|
    @param[in]    As        An enumeration variable whose value determines whether the
 | 
						|
                            returned value is the number of bytes or the number of elements
 | 
						|
                            currently available in the FIFO.
 | 
						|
 | 
						|
    @retval   0       The FIFO is full.
 | 
						|
    @retval   >=0     The number of items which can be accepted by the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
FIFO_FreeSpace (
 | 
						|
  cFIFO            *Self,
 | 
						|
  FIFO_ElemBytes    As
 | 
						|
)
 | 
						|
{
 | 
						|
  size_t    Count;
 | 
						|
  UINT32    RDex;
 | 
						|
  UINT32    WDex;
 | 
						|
 | 
						|
  RDex = Self->ReadIndex;
 | 
						|
  WDex = Self->WriteIndex;
 | 
						|
 | 
						|
  if(RDex <= WDex) {
 | 
						|
    Count = (Self->NumElements - (WDex - RDex)) - 1;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    Count = (RDex - WDex)-1;
 | 
						|
  }
 | 
						|
  if(As == AsBytes) {
 | 
						|
    Count *= Self->ElementSize;
 | 
						|
  }
 | 
						|
  return Count;
 | 
						|
}
 | 
						|
 | 
						|
/** Reduce the FIFO contents by NumElem elements.
 | 
						|
 | 
						|
    @param[in]    Self      Pointer to the FIFO instance.
 | 
						|
    @param[in]    NumElem   Number of elements to delete from the FIFO.
 | 
						|
 | 
						|
    @retval   0   FIFO is now empty.
 | 
						|
    @retval   N>0 There are still N elements in the FIFO.
 | 
						|
    @retval   -1  There are fewer than NumElem elements in the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
ssize_t
 | 
						|
FIFO_Reduce (
 | 
						|
  cFIFO    *Self,
 | 
						|
  size_t    NumElem
 | 
						|
  )
 | 
						|
{
 | 
						|
  size_t    QCount;
 | 
						|
  ssize_t   RetVal;
 | 
						|
 | 
						|
  assert(Self != NULL);
 | 
						|
 | 
						|
  QCount = FIFO_NumInQueue(Self, AsElements);
 | 
						|
  if(NumElem > QCount) {
 | 
						|
    RetVal = -1;
 | 
						|
    errno   = EINVAL;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    RetVal = (ssize_t)ModuloAdd(Self->ReadIndex, (UINT32)NumElem, Self->NumElements);
 | 
						|
    Self->ReadIndex = (UINT32)RetVal;
 | 
						|
 | 
						|
    RetVal = (ssize_t)(QCount - NumElem);
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Test whether the FIFO is empty.
 | 
						|
 | 
						|
    @param[in]    Self      Pointer to the FIFO instance.
 | 
						|
 | 
						|
    @retval   TRUE    The FIFO is empty.
 | 
						|
    @retval   FALSE   There is data in the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
FIFO_IsEmpty (
 | 
						|
  cFIFO *Self
 | 
						|
  )
 | 
						|
{
 | 
						|
  assert(Self != NULL);
 | 
						|
 | 
						|
  return (BOOLEAN)(Self->WriteIndex == Self->ReadIndex);
 | 
						|
}
 | 
						|
 | 
						|
/** Test whether the FIFO is full.
 | 
						|
 | 
						|
    @param[in]    Self      Pointer to the FIFO instance.
 | 
						|
 | 
						|
    @retval   TRUE    The FIFO is full.
 | 
						|
    @retval   FALSE   There is free space in the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
FIFO_IsFull (
 | 
						|
  cFIFO *Self
 | 
						|
  )
 | 
						|
{
 | 
						|
  assert(Self != NULL);
 | 
						|
 | 
						|
  return (BOOLEAN)(ModuloIncrement(Self->WriteIndex, Self->NumElements) == (INT32)Self->ReadIndex);
 | 
						|
}
 | 
						|
 | 
						|
/** Add one or more elements to the FIFO.
 | 
						|
 | 
						|
    This function allows one to add one or more elements, as specified by Count,
 | 
						|
    to the FIFO.  Each element is of the size specified when the FIFO object
 | 
						|
    was instantiated (FIFO.ElementSize).
 | 
						|
 | 
						|
    pElement points to the first byte of the first element to be added.
 | 
						|
    If multiple elements are to be added, the elements are expected to be
 | 
						|
    organized as a packed array.
 | 
						|
 | 
						|
    @param[in]    Self        Pointer to the FIFO instance.
 | 
						|
    @param[in]    pElement    Pointer to the element(s) to enqueue (add).
 | 
						|
    @param[in]    Count       Number of elements to add.
 | 
						|
 | 
						|
    @retval   0       The FIFO is full.
 | 
						|
    @retval   >=0     The number of elements added to the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
FIFO_Enqueue (
 | 
						|
  cFIFO        *Self,
 | 
						|
  const void   *pElement,
 | 
						|
  size_t        Count
 | 
						|
  )
 | 
						|
{
 | 
						|
  uintptr_t     ElemPtr;
 | 
						|
  uintptr_t     QPtr;
 | 
						|
  size_t        i;
 | 
						|
  UINT32        SizeOfElement;
 | 
						|
  UINT32        Windex;
 | 
						|
 | 
						|
  assert(Self != NULL);
 | 
						|
  assert(pElement != NULL);
 | 
						|
 | 
						|
  if(FIFO_IsFull(Self)) {                                                 // FIFO is full so can't add to it
 | 
						|
    Count = 0;                                                              // Zero characters added
 | 
						|
  }
 | 
						|
  else {                                                                  // Otherwise, FIFO is not full...
 | 
						|
    Count = MIN(Count, Self->FreeSpace(Self, AsElements));                  // Smaller of requested or available space
 | 
						|
    SizeOfElement = Self->ElementSize;                                      // Size of Elements, in bytes
 | 
						|
    Windex = Self->WriteIndex;                                              // Index of first writable slot in FIFO
 | 
						|
 | 
						|
    ElemPtr = (uintptr_t)pElement;                                          // Addr. of element to add, as an integer
 | 
						|
    QPtr    = (uintptr_t)Self->Queue + (SizeOfElement * Windex);            // Addr. in FIFO to write, as an integer
 | 
						|
 | 
						|
    for(i = 0; i < Count; ++i) {                                            // For Count elements...
 | 
						|
      (void)CopyMem((void *)QPtr, (const void *)ElemPtr, SizeOfElement);      // Copy an element into the FIFO
 | 
						|
      Windex = (UINT32)ModuloIncrement(Windex, Self->NumElements);            // Increment the Write index, wrap if necessary
 | 
						|
      if(Windex == 0) {                                                       // If the index wrapped
 | 
						|
        QPtr = (uintptr_t)Self->Queue;                                          // Go to the beginning
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        QPtr += SizeOfElement;                                                // Otherwise, point to next in FIFO
 | 
						|
      }
 | 
						|
      ElemPtr += SizeOfElement;                                               // And also point to next Element to add
 | 
						|
    }
 | 
						|
    Self->WriteIndex = Windex;                                              // Finally, save the new Write Index
 | 
						|
  }
 | 
						|
  return Count;                                                           // Number of elements added to FIFO
 | 
						|
}
 | 
						|
 | 
						|
/** Read or copy elements from the FIFO.
 | 
						|
 | 
						|
    This function allows one to read one or more elements, as specified by Count,
 | 
						|
    from the FIFO.  Each element is of the size specified when the FIFO object
 | 
						|
    was instantiated (FIFO.ElementSize).
 | 
						|
 | 
						|
    pElement points to the destination of the first byte of the first element
 | 
						|
    to be read. If multiple elements are to be read, the elements are expected
 | 
						|
    to be organized as a packed array.
 | 
						|
 | 
						|
    @param[in]    Self        Pointer to the FIFO instance.
 | 
						|
    @param[out]   pElement    Pointer to where to store the element(s) read from the FIFO.
 | 
						|
    @param[in]    Count       Number of elements to dequeue.
 | 
						|
    @param[in]    Consume     If TRUE, consume read elements.  Otherwise, preserve.
 | 
						|
 | 
						|
    @retval   0       The FIFO is empty.
 | 
						|
    @retval   >=0     The number of elements read from the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
FIFO_Dequeue (
 | 
						|
  cFIFO    *Self,
 | 
						|
  void     *pElement,
 | 
						|
  size_t    Count,
 | 
						|
  BOOLEAN   Consume
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN         QPtr;
 | 
						|
  UINT32        RDex;
 | 
						|
  UINT32        SizeOfElement;
 | 
						|
  UINT32        i;
 | 
						|
 | 
						|
  assert(Self != NULL);
 | 
						|
  assert(pElement != NULL);
 | 
						|
 | 
						|
  if(FIFO_IsEmpty(Self)) {
 | 
						|
    Count = 0;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    RDex          = Self->ReadIndex;                                  // Get this FIFO's Read Index
 | 
						|
    SizeOfElement = Self->ElementSize;                                // Get size of this FIFO's elements
 | 
						|
    Count         = MIN(Count, Self->Count(Self, AsElements));        // Lesser of requested or actual
 | 
						|
 | 
						|
    QPtr = (UINTN)Self->Queue + (RDex * SizeOfElement);           // Point to Read location in FIFO
 | 
						|
    for(i = 0; i < Count; ++i) {                                      // Iterate Count times...
 | 
						|
      (void)CopyMem(pElement, (const void *)QPtr, SizeOfElement);   // Copy element from FIFO to caller's buffer
 | 
						|
      RDex = (UINT32)ModuloIncrement(RDex, Self->NumElements);          // Increment Read Index
 | 
						|
      if(RDex == 0) {                                                   // If the index wrapped
 | 
						|
        QPtr = (UINTN)Self->Queue;                                        // Point back to beginning of data
 | 
						|
      }
 | 
						|
      else {                                                            // Otherwise
 | 
						|
        QPtr += SizeOfElement;                                        // Point to the next element in FIFO
 | 
						|
      }
 | 
						|
      pElement = (char*)pElement + SizeOfElement;                   // Point to next element in caller's buffer
 | 
						|
    }                                                                 // Iterate: for loop
 | 
						|
    if(Consume) {                                                     // If caller requests data consumption
 | 
						|
      Self->ReadIndex = RDex;                                           // Set FIFO's Read Index to new Index
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return Count;                                                     // Return number of elements actually read
 | 
						|
}
 | 
						|
 | 
						|
/** Read elements from the FIFO.
 | 
						|
 | 
						|
    Read the specified number of elements from the FIFO, removing each element read.
 | 
						|
    The number of elements actually read from the FIFO is returned.  This number can differ
 | 
						|
    from the Count requested if more elements are requested than are in the FIFO.
 | 
						|
 | 
						|
    @param[in]    Self        Pointer to the FIFO instance.
 | 
						|
    @param[out]   pElement    Pointer to where to store the element read from the FIFO.
 | 
						|
    @param[in]    Count       Number of elements to dequeue.
 | 
						|
 | 
						|
    @retval   0       The FIFO is empty.
 | 
						|
    @retval   >=0     The number of elements read from the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
FIFO_Read (
 | 
						|
  cFIFO    *Self,
 | 
						|
  void     *pElement,
 | 
						|
  size_t    Count
 | 
						|
  )
 | 
						|
{
 | 
						|
  return FIFO_Dequeue(Self, pElement, Count, TRUE);
 | 
						|
}
 | 
						|
 | 
						|
/** Make a copy of the FIFO's data.
 | 
						|
    The contents of the FIFO is copied out and linearized without affecting the
 | 
						|
    FIFO contents.  This function is idempotent.
 | 
						|
 | 
						|
    @param[in]    Self        Pointer to the FIFO instance.
 | 
						|
    @param[out]   pElement    Pointer to where to store the elements copied from the FIFO.
 | 
						|
    @param[in]    Count       Number of elements to copy.
 | 
						|
 | 
						|
    @retval   0       The FIFO is empty.
 | 
						|
    @retval   >=0     The number of elements copied from the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
FIFO_Copy (
 | 
						|
  cFIFO    *Self,
 | 
						|
  void     *pElement,
 | 
						|
  size_t    Count
 | 
						|
  )
 | 
						|
{
 | 
						|
  return FIFO_Dequeue(Self, pElement, Count, FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/** Get the FIFO's current Read Index.
 | 
						|
 | 
						|
    @param[in]    Self      Pointer to the FIFO instance.
 | 
						|
**/
 | 
						|
static
 | 
						|
UINT32
 | 
						|
EFIAPI
 | 
						|
FIFO_GetRDex (
 | 
						|
  cFIFO *Self
 | 
						|
)
 | 
						|
{
 | 
						|
  assert(Self != NULL);
 | 
						|
 | 
						|
  return Self->ReadIndex;
 | 
						|
}
 | 
						|
 | 
						|
/** Get the FIFO's current Write Index.
 | 
						|
 | 
						|
    @param[in]    Self      Pointer to the FIFO instance.
 | 
						|
 | 
						|
    @return   The current value of the FIFO's WriteIndex member is returned.
 | 
						|
**/
 | 
						|
static
 | 
						|
UINT32
 | 
						|
EFIAPI
 | 
						|
FIFO_GetWDex (
 | 
						|
  cFIFO *Self
 | 
						|
)
 | 
						|
{
 | 
						|
  assert(Self != NULL);
 | 
						|
 | 
						|
  return Self->WriteIndex;
 | 
						|
}
 | 
						|
 | 
						|
/** Cleanly delete a FIFO instance.
 | 
						|
 | 
						|
    @param[in]    Self              Pointer to the FIFO instance.
 | 
						|
**/
 | 
						|
static
 | 
						|
void
 | 
						|
EFIAPI
 | 
						|
FIFO_Delete (
 | 
						|
  cFIFO *Self
 | 
						|
  )
 | 
						|
{
 | 
						|
  assert(Self != NULL);
 | 
						|
 | 
						|
  if(Self->Queue != NULL) {
 | 
						|
    FreePool(Self->Queue);
 | 
						|
    Self->Queue = NULL;     // Zombie catcher
 | 
						|
  }
 | 
						|
  FreePool(Self);
 | 
						|
}
 | 
						|
 | 
						|
/** Empty the FIFO, discarding up to NumToFlush elements.
 | 
						|
 | 
						|
    @param[in]    Self              Pointer to the FIFO instance.
 | 
						|
    @param[in]    NumToFlush        Number of elements to flush from the FIFO.
 | 
						|
                                    If larger than the number of elements in the
 | 
						|
                                    FIFO, the FIFO is emptied.
 | 
						|
 | 
						|
    @return     Returns the number of elements remaining in the FIFO after the flush.
 | 
						|
**/
 | 
						|
static
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
FIFO_Flush (
 | 
						|
  cFIFO  *Self,
 | 
						|
  size_t  NumToFlush
 | 
						|
  )
 | 
						|
{
 | 
						|
  size_t  NumInQ;
 | 
						|
  size_t  Remainder;
 | 
						|
 | 
						|
  assert(Self != NULL);
 | 
						|
 | 
						|
  NumInQ = FIFO_NumInQueue(Self, AsElements);
 | 
						|
  if(NumToFlush >= NumInQ) {
 | 
						|
    Self->ReadIndex   = 0;
 | 
						|
    Self->WriteIndex  = 0;
 | 
						|
    Remainder = 0;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    Remainder = FIFO_Reduce(Self, NumToFlush);
 | 
						|
  }
 | 
						|
  return Remainder;
 | 
						|
}
 | 
						|
 | 
						|
/** Remove the most recently added element from the FIFO.
 | 
						|
 | 
						|
    @param[in]    Self              Pointer to the FIFO instance.
 | 
						|
 | 
						|
    @return     Returns the number of elements remaining in the FIFO.
 | 
						|
**/
 | 
						|
static
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
FIFO_Truncate (
 | 
						|
  cFIFO  *Self
 | 
						|
  )
 | 
						|
{
 | 
						|
  size_t  Remainder;
 | 
						|
 | 
						|
  assert(Self != NULL);
 | 
						|
 | 
						|
  Remainder = FIFO_NumInQueue(Self, AsElements);
 | 
						|
  if(Remainder > 0) {
 | 
						|
    Self->WriteIndex = (UINT32)ModuloDecrement(Self->WriteIndex, Self->NumElements);
 | 
						|
    --Remainder;
 | 
						|
  }
 | 
						|
  return Remainder;
 | 
						|
}
 | 
						|
 | 
						|
/** Construct a new instance of a FIFO Queue.
 | 
						|
 | 
						|
    @param[in]    NumElements   Number of elements to be contained in the new FIFO.
 | 
						|
    @param[in]    ElementSize   Size, in bytes, of an element.
 | 
						|
 | 
						|
    @retval   NULL      Unable to create the instance.
 | 
						|
    @retval   NonNULL   Pointer to the new FIFO instance.
 | 
						|
**/
 | 
						|
cFIFO *
 | 
						|
EFIAPI
 | 
						|
New_cFIFO(
 | 
						|
  UINT32    NumElements,
 | 
						|
  size_t    ElementSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  cFIFO        *FIFO;
 | 
						|
  UINT8        *Queue;
 | 
						|
 | 
						|
  FIFO = NULL;
 | 
						|
  if((NumElements > 2) && (ElementSize > 0)) {
 | 
						|
    FIFO = (cFIFO *)AllocatePool(sizeof(cFIFO));
 | 
						|
    if(FIFO != NULL) {
 | 
						|
      Queue = (UINT8 *)AllocateZeroPool(NumElements * ElementSize);
 | 
						|
      if(Queue != NULL) {
 | 
						|
        FIFO->Write       = FIFO_Enqueue;
 | 
						|
        FIFO->Read        = FIFO_Read;
 | 
						|
        FIFO->Copy        = FIFO_Copy;
 | 
						|
        FIFO->IsEmpty     = FIFO_IsEmpty;
 | 
						|
        FIFO->IsFull      = FIFO_IsFull;
 | 
						|
        FIFO->Count       = FIFO_NumInQueue;
 | 
						|
        FIFO->FreeSpace   = FIFO_FreeSpace;
 | 
						|
        FIFO->Flush       = FIFO_Flush;
 | 
						|
        FIFO->Truncate    = FIFO_Truncate;
 | 
						|
        FIFO->Delete      = FIFO_Delete;
 | 
						|
        FIFO->GetRDex     = FIFO_GetRDex;
 | 
						|
        FIFO->GetWDex     = FIFO_GetWDex;
 | 
						|
 | 
						|
        FIFO->Queue       = Queue;
 | 
						|
        FIFO->ElementSize = (UINT32)ElementSize;
 | 
						|
        FIFO->NumElements = (UINT32)NumElements;
 | 
						|
        FIFO->ReadIndex   = 0;
 | 
						|
        FIFO->WriteIndex  = 0;
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        FreePool(FIFO);
 | 
						|
        FIFO = NULL;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return FIFO;
 | 
						|
}
 |