]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/LibC/Containers/Queues/Fifo.c
StdLib: Fix some build problems and obscure bugs.
[mirror_edk2.git] / StdLib / LibC / Containers / Queues / Fifo.c
index 996498e1d9038005877a5ced3058425d11b78387..73254d2e56248e7d3e95dcfb3cc3b43afe29462c 100644 (file)
@@ -15,7 +15,7 @@
   One element of the FIFO is always reserved as the "terminator" element.  Thus,\r
   the capacity of a FIFO is actually NumElements-1.\r
 \r
-  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials are licensed and made available\r
   under the terms and conditions of the BSD License which accompanies this\r
   distribution.  The full text of the license may be found at\r
@@ -102,10 +102,10 @@ FIFO_FreeSpace (
   WDex = Self->WriteIndex;\r
 \r
   if(RDex <= WDex) {\r
-    Count = Self->NumElements - ((WDex - RDex) - 1);\r
+    Count = (Self->NumElements - (WDex - RDex)) - 1;\r
   }\r
   else {\r
-    Count = (RDex - WDex);\r
+    Count = (RDex - WDex)-1;\r
   }\r
   if(As == AsBytes) {\r
     Count *= Self->ElementSize;\r
@@ -221,32 +221,31 @@ FIFO_Enqueue (
   assert(Self != NULL);\r
   assert(pElement != NULL);\r
 \r
-  if(FIFO_IsFull(Self)) {\r
-    Count = 0;\r
+  if(FIFO_IsFull(Self)) {                                                 // FIFO is full so can't add to it\r
+    Count = 0;                                                              // Zero characters added\r
   }\r
-  else {\r
-    Count = MIN(Count, Self->FreeSpace(Self, AsElements));\r
-    SizeOfElement = Self->ElementSize;\r
-    Windex = Self->WriteIndex;\r
-\r
-    ElemPtr = (uintptr_t)pElement;\r
-\r
-    QPtr   = (uintptr_t)Self->Queue + (SizeOfElement * Windex);\r
-    for(i = 0; i < Count; ++i) {\r
-      (void)CopyMem((void *)QPtr, (const void *)ElemPtr, SizeOfElement);\r
-      Windex = (UINT32)ModuloIncrement(Windex, Self->NumElements);\r
-      if(Windex == 0) {   // If the index wrapped\r
-        QPtr = (uintptr_t)Self->Queue;\r
+  else {                                                                  // Otherwise, FIFO is not full...\r
+    Count = MIN(Count, Self->FreeSpace(Self, AsElements));                  // Smaller of requested or available space\r
+    SizeOfElement = Self->ElementSize;                                      // Size of Elements, in bytes\r
+    Windex = Self->WriteIndex;                                              // Index of first writable slot in FIFO\r
+\r
+    ElemPtr = (uintptr_t)pElement;                                          // Addr. of element to add, as an integer\r
+    QPtr    = (uintptr_t)Self->Queue + (SizeOfElement * Windex);            // Addr. in FIFO to write, as an integer\r
+\r
+    for(i = 0; i < Count; ++i) {                                            // For Count elements...\r
+      (void)CopyMem((void *)QPtr, (const void *)ElemPtr, SizeOfElement);      // Copy an element into the FIFO\r
+      Windex = (UINT32)ModuloIncrement(Windex, Self->NumElements);            // Increment the Write index, wrap if necessary\r
+      if(Windex == 0) {                                                       // If the index wrapped\r
+        QPtr = (uintptr_t)Self->Queue;                                          // Go to the beginning\r
       }\r
       else {\r
-        QPtr += SizeOfElement;\r
+        QPtr += SizeOfElement;                                                // Otherwise, point to next in FIFO\r
       }\r
-      ElemPtr += SizeOfElement;\r
+      ElemPtr += SizeOfElement;                                               // And also point to next Element to add\r
     }\r
-    (void)ZeroMem((void*)QPtr, SizeOfElement);\r
-    Self->WriteIndex = Windex;\r
+    Self->WriteIndex = Windex;                                              // Finally, save the new Write Index\r
   }\r
-  return Count;\r
+  return Count;                                                           // Number of elements added to FIFO\r
 }\r
 \r
 /** Read or copy elements from the FIFO.\r
@@ -277,7 +276,6 @@ FIFO_Dequeue (
   BOOLEAN   Consume\r
   )\r
 {\r
-  UINTN         ElemPtr;\r
   UINTN         QPtr;\r
   UINT32        RDex;\r
   UINT32        SizeOfElement;\r
@@ -285,38 +283,40 @@ FIFO_Dequeue (
 \r
   assert(Self != NULL);\r
   assert(pElement != NULL);\r
-  assert(Count != 0);\r
 \r
   if(FIFO_IsEmpty(Self)) {\r
     Count = 0;\r
   }\r
   else {\r
-    RDex          = Self->ReadIndex;\r
-    SizeOfElement = Self->ElementSize;\r
-    ElemPtr       = (UINTN)pElement;\r
-    Count         = MIN(Count, Self->Count(Self, AsElements));\r
-\r
-    QPtr = (UINTN)Self->Queue + (RDex * Self->ElementSize);\r
-    for(i = 0; i < Count; ++i) {\r
-      (void)CopyMem((void *)ElemPtr, (const void *)QPtr, Self->ElementSize);\r
-      RDex = (UINT32)ModuloIncrement(RDex, Self->NumElements);\r
-      if(RDex == 0) {   // If the index wrapped\r
-        QPtr = (UINTN)Self->Queue;\r
+    RDex          = Self->ReadIndex;                                  // Get this FIFO's Read Index\r
+    SizeOfElement = Self->ElementSize;                                // Get size of this FIFO's elements\r
+    Count         = MIN(Count, Self->Count(Self, AsElements));        // Lesser of requested or actual\r
+\r
+    QPtr = (UINTN)Self->Queue + (RDex * Self->ElementSize);           // Point to Read location in FIFO\r
+    for(i = 0; i < Count; ++i) {                                      // Iterate Count times...\r
+      (void)CopyMem(pElement, (const void *)QPtr, Self->ElementSize);   // Copy element from FIFO to caller's buffer\r
+      RDex = (UINT32)ModuloIncrement(RDex, Self->NumElements);          // Increment Read Index\r
+      if(RDex == 0) {                                                   // If the index wrapped\r
+        QPtr = (UINTN)Self->Queue;                                        // Point back to beginning of data\r
       }\r
-      else {\r
-        QPtr += Self->ElementSize;\r
+      else {                                                            // Otherwise\r
+        QPtr += Self->ElementSize;                                        // Point to the next element in FIFO\r
       }\r
-      ElemPtr += Self->ElementSize;\r
-    }\r
-    if(Consume) {\r
-      Self->ReadIndex = RDex;\r
+      pElement = (char*)pElement + Self->ElementSize;                   // Point to next element in caller's buffer\r
+    }                                                                 // Iterate: for loop\r
+    if(Consume) {                                                     // If caller requests data consumption\r
+      Self->ReadIndex = RDex;                                           // Set FIFO's Read Index to new Index\r
     }\r
   }\r
-  return Count;\r
+  return Count;                                                     // Return number of elements actually read\r
 }\r
 \r
 /** Read elements from the FIFO.\r
 \r
+    Read the specified number of elements from the FIFO, removing each element read.\r
+    The number of elements actually read from the FIFO is returned.  This number can differ\r
+    from the Count requested if more elements are requested than are in the FIFO.\r
+\r
     @param[in]    Self        Pointer to the FIFO instance.\r
     @param[out]   pElement    Pointer to where to store the element read from the FIFO.\r
     @param[in]    Count       Number of elements to dequeue.\r
@@ -338,7 +338,7 @@ FIFO_Read (
 \r
 /** Make a copy of the FIFO's data.\r
     The contents of the FIFO is copied out and linearized without affecting the\r
-    FIFO contents.\r
+    FIFO contents.  This function is idempotent.\r
 \r
     @param[in]    Self        Pointer to the FIFO instance.\r
     @param[out]   pElement    Pointer to where to store the elements copied from the FIFO.\r
@@ -435,7 +435,7 @@ FIFO_Flush (
 \r
   assert(Self != NULL);\r
 \r
-  NumInQ = FIFO_FreeSpace(Self, AsElements);\r
+  NumInQ = FIFO_NumInQueue(Self, AsElements);\r
   if(NumToFlush >= NumInQ) {\r
     Self->ReadIndex   = 0;\r
     Self->WriteIndex  = 0;\r
@@ -464,7 +464,7 @@ FIFO_Truncate (
 \r
   assert(Self != NULL);\r
 \r
-  Remainder = Self->Count(Self, AsElements);\r
+  Remainder = FIFO_NumInQueue(Self, AsElements);\r
   if(Remainder > 0) {\r
     Self->WriteIndex = (UINT32)ModuloDecrement(Self->WriteIndex, Self->NumElements);\r
     --Remainder;\r