Revision: 17015
          http://sourceforge.net/p/edk2/code/17015
Author:   lgao4
Date:     2015-03-06 02:57:11 +0000 (Fri, 06 Mar 2015)
Log Message:
-----------
MdeModulePkg: serve allocations from higher-up bins if current bin is empty

This patch changes the allocation logic for the pool allocator to only
allocate additional pages if the requested allocation cannot be fulfilled
from the current bin or any of the larger ones. If there are larger blocks
available, they will be used to serve the allocation, and the remainder will
be carved up into smaller blocks using the existing carving up logic.
Note that all pool sizes are a multiple of the smallest pool size, so it is
guaranteed that the remainder will be carved up without spilling. Due to the
exponential nature of the pool sizes, the amount of work is logarithmic in
the size of the available block.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <[email protected]>
Reviewed-by: Liming Gao <[email protected]>

Modified Paths:
--------------
    trunk/edk2/MdeModulePkg/Core/Dxe/Mem/Pool.c

Modified: trunk/edk2/MdeModulePkg/Core/Dxe/Mem/Pool.c
===================================================================
--- trunk/edk2/MdeModulePkg/Core/Dxe/Mem/Pool.c 2015-03-06 02:56:20 UTC (rev 
17014)
+++ trunk/edk2/MdeModulePkg/Core/Dxe/Mem/Pool.c 2015-03-06 02:57:11 UTC (rev 
17015)
@@ -292,7 +292,7 @@
   VOID        *Buffer;
   UINTN       Index;
   UINTN       FSize;
-  UINTN       Offset;
+  UINTN       Offset, MaxOffset;
   UINTN       NoPages;
   UINTN       Granularity;
 
@@ -343,7 +343,23 @@
   //
   if (IsListEmpty (&Pool->FreeList[Index])) {
 
+    Offset = LIST_TO_SIZE (Index);
+    MaxOffset = Granularity;
+
     //
+    // Check the bins holding larger blocks, and carve one up if needed
+    //
+    while (++Index < SIZE_TO_LIST (Granularity)) {
+      if (!IsListEmpty (&Pool->FreeList[Index])) {
+        Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, 
POOL_FREE_SIGNATURE);
+        RemoveEntryList (&Free->Link);
+        NewPage = (VOID *) Free;
+        MaxOffset = LIST_TO_SIZE (Index);
+        goto Carve;
+      }
+    }
+
+    //
     // Get another page
     //
     NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (Granularity), 
Granularity);
@@ -354,29 +370,28 @@
     //
     // Serve the allocation request from the head of the allocated block
     //
+Carve:
     Head = (POOL_HEAD *) NewPage;
-    Offset = LIST_TO_SIZE (Index);
 
     //
     // Carve up remaining space into free pool blocks
     //
-    Index = SIZE_TO_LIST (Granularity) - 1;
-    while (Offset < Granularity) {
+    Index--;
+    while (Offset < MaxOffset) {
       ASSERT (Index < MAX_POOL_LIST);
       FSize = LIST_TO_SIZE(Index);
 
-      while (Offset + FSize <= Granularity) {
+      while (Offset + FSize <= MaxOffset) {
         Free = (POOL_FREE *) &NewPage[Offset];
         Free->Signature = POOL_FREE_SIGNATURE;
         Free->Index     = (UINT32)Index;
         InsertHeadList (&Pool->FreeList[Index], &Free->Link);
         Offset += FSize;
       }
-
       Index -= 1;
     }
 
-    ASSERT (Offset == Granularity);
+    ASSERT (Offset == MaxOffset);
     goto Done;
   }
 


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to