public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v6 0/1] Add function QuickSort into MdePkg/BaseLib
@ 2021-10-06  0:30 IanX Kuo
  2021-10-06  0:30 ` [PATCH v6 1/1] MdePkg/BaseLib: Add QuickSort function on BaseLib IanX Kuo
  0 siblings, 1 reply; 4+ messages in thread
From: IanX Kuo @ 2021-10-06  0:30 UTC (permalink / raw)
  To: devel; +Cc: amy.chan, ray.ni, IanX Kuo

From: IanX Kuo <ianx.kuo@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3675

First change
1. MdePkg/BaseLib: Add QuickSort function

It need to seperate to second change
2. MdeModulePkg/SortLib: Use QuickSort instead of QuickSortWorker
3. CryptLib/CryptLib: Remove duplicate QuickSortWorker
4. CpuCacheInfoLib: Remove MdeModulePkg dependency

IanX Kuo (1):
  MdePkg/BaseLib: Add QuickSort function on BaseLib

 MdePkg/Include/Library/BaseLib.h              |  49 ++++++++
 MdePkg/Library/BaseLib/BaseLib.inf            |   1 +
 MdePkg/Library/BaseLib/QuickSort.c            | 116 ++++++++++++++++++
 .../Library/BaseLib/UnitTestHostBaseLib.inf   |   3 +-
 4 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 MdePkg/Library/BaseLib/QuickSort.c

-- 
2.30.0.windows.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v6 1/1] MdePkg/BaseLib: Add QuickSort function on BaseLib
  2021-10-06  0:30 [PATCH v6 0/1] Add function QuickSort into MdePkg/BaseLib IanX Kuo
@ 2021-10-06  0:30 ` IanX Kuo
  2021-10-06  1:15   ` [edk2-devel] " guajen0710
  2021-10-07 10:29   ` Marvin Häuser
  0 siblings, 2 replies; 4+ messages in thread
From: IanX Kuo @ 2021-10-06  0:30 UTC (permalink / raw)
  To: devel
  Cc: amy.chan, ray.ni, IanX Kuo, Michael D Kinney, Liming Gao,
	Zhiguang Liu

From: IanX Kuo <ianx.kuo@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3675

Add QuickSort function into BaseLib

Cc: Ray Ni <ray.ni@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: IanX Kuo <ianx.kuo@intel.com>
---
 MdePkg/Include/Library/BaseLib.h              |  49 ++++++++
 MdePkg/Library/BaseLib/BaseLib.inf            |   1 +
 MdePkg/Library/BaseLib/QuickSort.c            | 116 ++++++++++++++++++
 .../Library/BaseLib/UnitTestHostBaseLib.inf   |   3 +-
 4 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 MdePkg/Library/BaseLib/QuickSort.c

diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 2452c1d92e..0ae0f4e6af 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -2856,6 +2856,55 @@ RemoveEntryList (
 //
 // Math Services
 //
+/**
+  Prototype for comparison function for any two element types.
+
+  @param[in] Buffer1                  The pointer to first buffer.
+  @param[in] Buffer2                  The pointer to second buffer.
+
+  @retval 0                           Buffer1 equal to Buffer2.
+  @return <0                          Buffer1 is less than Buffer2.
+  @return >0                          Buffer1 is greater than Buffer2.
+**/
+typedef
+INTN
+(EFIAPI *BASE_SORT_COMPARE)(
+  IN CONST VOID                 *Buffer1,
+  IN CONST VOID                 *Buffer2
+  );
+
+/**
+  This function is identical to perform QuickSort,
+  except that is uses the pre-allocated buffer so the in place sorting does not need to
+  allocate and free buffers constantly.
+
+  Each element must be equal sized.
+
+  if BufferToSort is NULL, then ASSERT.
+  if CompareFunction is NULL, then ASSERT.
+  if BufferOneElement is NULL, then ASSERT.
+  if ElementSize is < 1, then ASSERT.
+
+  if Count is < 2 then perform no action.
+
+  @param[in, out] BufferToSort   on call a Buffer of (possibly sorted) elements
+                                 on return a buffer of sorted elements
+  @param[in] Count               the number of elements in the buffer to sort
+  @param[in] ElementSize         Size of an element in bytes
+  @param[in] CompareFunction     The function to call to perform the comparison
+                                 of any 2 elements
+  @param[out] BufferOneElement   Caller provided buffer whose size equals to ElementSize.
+                                 It's used by QuickSort() for swapping in sorting.
+**/
+VOID
+EFIAPI
+QuickSort (
+  IN OUT VOID                           *BufferToSort,
+  IN CONST UINTN                        Count,
+  IN CONST UINTN                        ElementSize,
+  IN       BASE_SORT_COMPARE            CompareFunction,
+  OUT VOID                              *BufferOneElement
+  );
 
 /**
   Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 6efa5315b6..cebda3b210 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -32,6 +32,7 @@
   SwapBytes16.c
   LongJump.c
   SetJump.c
+  QuickSort.c
   RShiftU64.c
   RRotU64.c
   RRotU32.c
diff --git a/MdePkg/Library/BaseLib/QuickSort.c b/MdePkg/Library/BaseLib/QuickSort.c
new file mode 100644
index 0000000000..3aff18188b
--- /dev/null
+++ b/MdePkg/Library/BaseLib/QuickSort.c
@@ -0,0 +1,116 @@
+/** @file
+  Math worker functions.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BaseLibInternals.h"
+
+/**
+  This function is identical to perform QuickSort,
+  except that is uses the pre-allocated buffer so the in place sorting does not need to
+  allocate and free buffers constantly.
+
+  Each element must be equal sized.
+
+  if BufferToSort is NULL, then ASSERT.
+  if CompareFunction is NULL, then ASSERT.
+  if BufferOneElement is NULL, then ASSERT.
+  if ElementSize is < 1, then ASSERT.
+
+  if Count is < 2 then perform no action.
+
+  @param[in, out] BufferToSort   on call a Buffer of (possibly sorted) elements
+                                 on return a buffer of sorted elements
+  @param[in] Count               the number of elements in the buffer to sort
+  @param[in] ElementSize         Size of an element in bytes
+  @param[in] CompareFunction     The function to call to perform the comparison
+                                 of any 2 elements
+  @param[out] BufferOneElement   Caller provided buffer whose size equals to ElementSize.
+                                 It's used by QuickSort() for swapping in sorting.
+**/
+VOID
+EFIAPI
+QuickSort (
+  IN OUT VOID                           *BufferToSort,
+  IN CONST UINTN                        Count,
+  IN CONST UINTN                        ElementSize,
+  IN       BASE_SORT_COMPARE            CompareFunction,
+  OUT VOID                              *BufferOneElement
+  )
+{
+  VOID        *Pivot;
+  UINTN       LoopCount;
+  UINTN       NextSwapLocation;
+
+  ASSERT (BufferToSort     != NULL);
+  ASSERT (CompareFunction  != NULL);
+  ASSERT (BufferOneElement != NULL);
+  ASSERT (ElementSize      >= 1);
+
+  if (Count < 2) {
+    return;
+  }
+
+  NextSwapLocation = 0;
+
+  //
+  // pick a pivot (we choose last element)
+  //
+  Pivot = ((UINT8*) BufferToSort + ((Count - 1) * ElementSize));
+
+  //
+  // Now get the pivot such that all on "left" are below it
+  // and everything "right" are above it
+  //
+  for (LoopCount = 0; LoopCount < Count -1; LoopCount++) {
+    //
+    // if the pivot is greater than the element.
+    //
+    if (CompareFunction ((VOID*) ((UINT8*) BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0){
+      //
+      // swap
+      //
+      CopyMem (BufferOneElement, (UINT8*) BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
+      CopyMem ((UINT8*) BufferToSort + (NextSwapLocation * ElementSize), (UINT8*) BufferToSort + ((LoopCount) * ElementSize), ElementSize);
+      CopyMem ((UINT8*) BufferToSort + ((LoopCount)*ElementSize), BufferOneElement, ElementSize);
+
+      //
+      // increment NextSwapLocation
+      //
+      NextSwapLocation++;
+    }
+  }
+  //
+  // swap pivot to it's final position (NextSwapLocation)
+  //
+  CopyMem (BufferOneElement, Pivot, ElementSize);
+  CopyMem (Pivot, (UINT8*) BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
+  CopyMem ((UINT8*) BufferToSort + (NextSwapLocation * ElementSize), BufferOneElement, ElementSize);
+
+  //
+  // Now recurse on 2 partial lists.  neither of these will have the 'pivot' element
+  // IE list is sorted left half, pivot element, sorted right half...
+  //
+  if (NextSwapLocation >= 2) {
+    QuickSort (
+      BufferToSort,
+      NextSwapLocation,
+      ElementSize,
+      CompareFunction,
+      BufferOneElement
+      );
+  }
+
+  if ((Count - NextSwapLocation - 1) >= 2) {
+    QuickSort (
+      (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
+      Count - NextSwapLocation - 1,
+      ElementSize,
+      CompareFunction,
+      BufferOneElement
+      );
+  }
+}
diff --git a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
index eae1a7158d..d09bd12bef 100644
--- a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
+++ b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Base Library implementation for use with host based unit tests.
 #
-#  Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
 #  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
 #  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
 #  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
@@ -33,6 +33,7 @@
   SwapBytes16.c
   LongJump.c
   SetJump.c
+  QuickSort.c
   RShiftU64.c
   RRotU64.c
   RRotU32.c
-- 
2.30.0.windows.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [edk2-devel] [PATCH v6 1/1] MdePkg/BaseLib: Add QuickSort function on BaseLib
  2021-10-06  0:30 ` [PATCH v6 1/1] MdePkg/BaseLib: Add QuickSort function on BaseLib IanX Kuo
@ 2021-10-06  1:15   ` guajen0710
  2021-10-07 10:29   ` Marvin Häuser
  1 sibling, 0 replies; 4+ messages in thread
From: guajen0710 @ 2021-10-06  1:15 UTC (permalink / raw)
  To: devel, ianx.kuo, mhaeuser

[-- Attachment #1: Type: text/plain, Size: 9419 bytes --]

Hi Marvin

Thanks for reply on Patch V5
I think the patch should eliminate your concern.

IanX Kuo <ianx.kuo@intel.com> 於 2021年10月6日 週三 上午8:31 寫道:

> From: IanX Kuo <ianx.kuo@intel.com>
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3675
>
> Add QuickSort function into BaseLib
>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> Signed-off-by: IanX Kuo <ianx.kuo@intel.com>
> ---
>  MdePkg/Include/Library/BaseLib.h              |  49 ++++++++
>  MdePkg/Library/BaseLib/BaseLib.inf            |   1 +
>  MdePkg/Library/BaseLib/QuickSort.c            | 116 ++++++++++++++++++
>  .../Library/BaseLib/UnitTestHostBaseLib.inf   |   3 +-
>  4 files changed, 168 insertions(+), 1 deletion(-)
>  create mode 100644 MdePkg/Library/BaseLib/QuickSort.c
>
> diff --git a/MdePkg/Include/Library/BaseLib.h
> b/MdePkg/Include/Library/BaseLib.h
> index 2452c1d92e..0ae0f4e6af 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -2856,6 +2856,55 @@ RemoveEntryList (
>  //
>  // Math Services
>  //
> +/**
> +  Prototype for comparison function for any two element types.
> +
> +  @param[in] Buffer1                  The pointer to first buffer.
> +  @param[in] Buffer2                  The pointer to second buffer.
> +
> +  @retval 0                           Buffer1 equal to Buffer2.
> +  @return <0                          Buffer1 is less than Buffer2.
> +  @return >0                          Buffer1 is greater than Buffer2.
> +**/
> +typedef
> +INTN
> +(EFIAPI *BASE_SORT_COMPARE)(
> +  IN CONST VOID                 *Buffer1,
> +  IN CONST VOID                 *Buffer2
> +  );
> +
> +/**
> +  This function is identical to perform QuickSort,
> +  except that is uses the pre-allocated buffer so the in place sorting
> does not need to
> +  allocate and free buffers constantly.
> +
> +  Each element must be equal sized.
> +
> +  if BufferToSort is NULL, then ASSERT.
> +  if CompareFunction is NULL, then ASSERT.
> +  if BufferOneElement is NULL, then ASSERT.
> +  if ElementSize is < 1, then ASSERT.
> +
> +  if Count is < 2 then perform no action.
> +
> +  @param[in, out] BufferToSort   on call a Buffer of (possibly sorted)
> elements
> +                                 on return a buffer of sorted elements
> +  @param[in] Count               the number of elements in the buffer to
> sort
> +  @param[in] ElementSize         Size of an element in bytes
> +  @param[in] CompareFunction     The function to call to perform the
> comparison
> +                                 of any 2 elements
> +  @param[out] BufferOneElement   Caller provided buffer whose size equals
> to ElementSize.
> +                                 It's used by QuickSort() for swapping in
> sorting.
> +**/
> +VOID
> +EFIAPI
> +QuickSort (
> +  IN OUT VOID                           *BufferToSort,
> +  IN CONST UINTN                        Count,
> +  IN CONST UINTN                        ElementSize,
> +  IN       BASE_SORT_COMPARE            CompareFunction,
> +  OUT VOID                              *BufferOneElement
> +  );
>
>  /**
>    Shifts a 64-bit integer left between 0 and 63 bits. The low bits are
> filled
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> b/MdePkg/Library/BaseLib/BaseLib.inf
> index 6efa5315b6..cebda3b210 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -32,6 +32,7 @@
>    SwapBytes16.c
>    LongJump.c
>    SetJump.c
> +  QuickSort.c
>    RShiftU64.c
>    RRotU64.c
>    RRotU32.c
> diff --git a/MdePkg/Library/BaseLib/QuickSort.c
> b/MdePkg/Library/BaseLib/QuickSort.c
> new file mode 100644
> index 0000000000..3aff18188b
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/QuickSort.c
> @@ -0,0 +1,116 @@
> +/** @file
> +  Math worker functions.
> +
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "BaseLibInternals.h"
> +
> +/**
> +  This function is identical to perform QuickSort,
> +  except that is uses the pre-allocated buffer so the in place sorting
> does not need to
> +  allocate and free buffers constantly.
> +
> +  Each element must be equal sized.
> +
> +  if BufferToSort is NULL, then ASSERT.
> +  if CompareFunction is NULL, then ASSERT.
> +  if BufferOneElement is NULL, then ASSERT.
> +  if ElementSize is < 1, then ASSERT.
> +
> +  if Count is < 2 then perform no action.
> +
> +  @param[in, out] BufferToSort   on call a Buffer of (possibly sorted)
> elements
> +                                 on return a buffer of sorted elements
> +  @param[in] Count               the number of elements in the buffer to
> sort
> +  @param[in] ElementSize         Size of an element in bytes
> +  @param[in] CompareFunction     The function to call to perform the
> comparison
> +                                 of any 2 elements
> +  @param[out] BufferOneElement   Caller provided buffer whose size equals
> to ElementSize.
> +                                 It's used by QuickSort() for swapping in
> sorting.
> +**/
> +VOID
> +EFIAPI
> +QuickSort (
> +  IN OUT VOID                           *BufferToSort,
> +  IN CONST UINTN                        Count,
> +  IN CONST UINTN                        ElementSize,
> +  IN       BASE_SORT_COMPARE            CompareFunction,
> +  OUT VOID                              *BufferOneElement
> +  )
> +{
> +  VOID        *Pivot;
> +  UINTN       LoopCount;
> +  UINTN       NextSwapLocation;
> +
> +  ASSERT (BufferToSort     != NULL);
> +  ASSERT (CompareFunction  != NULL);
> +  ASSERT (BufferOneElement != NULL);
> +  ASSERT (ElementSize      >= 1);
> +
> +  if (Count < 2) {
> +    return;
> +  }
> +
> +  NextSwapLocation = 0;
> +
> +  //
> +  // pick a pivot (we choose last element)
> +  //
> +  Pivot = ((UINT8*) BufferToSort + ((Count - 1) * ElementSize));
> +
> +  //
> +  // Now get the pivot such that all on "left" are below it
> +  // and everything "right" are above it
> +  //
> +  for (LoopCount = 0; LoopCount < Count -1; LoopCount++) {
> +    //
> +    // if the pivot is greater than the element.
> +    //
> +    if (CompareFunction ((VOID*) ((UINT8*) BufferToSort + ((LoopCount) *
> ElementSize)), Pivot) <= 0){
> +      //
> +      // swap
> +      //
> +      CopyMem (BufferOneElement, (UINT8*) BufferToSort +
> (NextSwapLocation * ElementSize), ElementSize);
> +      CopyMem ((UINT8*) BufferToSort + (NextSwapLocation * ElementSize),
> (UINT8*) BufferToSort + ((LoopCount) * ElementSize), ElementSize);
> +      CopyMem ((UINT8*) BufferToSort + ((LoopCount)*ElementSize),
> BufferOneElement, ElementSize);
> +
> +      //
> +      // increment NextSwapLocation
> +      //
> +      NextSwapLocation++;
> +    }
> +  }
> +  //
> +  // swap pivot to it's final position (NextSwapLocation)
> +  //
> +  CopyMem (BufferOneElement, Pivot, ElementSize);
> +  CopyMem (Pivot, (UINT8*) BufferToSort + (NextSwapLocation *
> ElementSize), ElementSize);
> +  CopyMem ((UINT8*) BufferToSort + (NextSwapLocation * ElementSize),
> BufferOneElement, ElementSize);
> +
> +  //
> +  // Now recurse on 2 partial lists.  neither of these will have the
> 'pivot' element
> +  // IE list is sorted left half, pivot element, sorted right half...
> +  //
> +  if (NextSwapLocation >= 2) {
> +    QuickSort (
> +      BufferToSort,
> +      NextSwapLocation,
> +      ElementSize,
> +      CompareFunction,
> +      BufferOneElement
> +      );
> +  }
> +
> +  if ((Count - NextSwapLocation - 1) >= 2) {
> +    QuickSort (
> +      (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> +      Count - NextSwapLocation - 1,
> +      ElementSize,
> +      CompareFunction,
> +      BufferOneElement
> +      );
> +  }
> +}
> diff --git a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> index eae1a7158d..d09bd12bef 100644
> --- a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> +++ b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> @@ -1,7 +1,7 @@
>  ## @file
>  #  Base Library implementation for use with host based unit tests.
>  #
> -#  Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
>  #  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
>  #  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
>  #  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> @@ -33,6 +33,7 @@
>    SwapBytes16.c
>    LongJump.c
>    SetJump.c
> +  QuickSort.c
>    RShiftU64.c
>    RRotU64.c
>    RRotU32.c
> --
> 2.30.0.windows.1
>
>
>
> ------------
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#81531): https://edk2.groups.io/g/devel/message/81531
> Mute This Topic: https://groups.io/mt/86108888/4133238
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub [guajen0710@gmail.com]
> ------------
>
>
>

[-- Attachment #2: Type: text/html, Size: 11952 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [edk2-devel] [PATCH v6 1/1] MdePkg/BaseLib: Add QuickSort function on BaseLib
  2021-10-06  0:30 ` [PATCH v6 1/1] MdePkg/BaseLib: Add QuickSort function on BaseLib IanX Kuo
  2021-10-06  1:15   ` [edk2-devel] " guajen0710
@ 2021-10-07 10:29   ` Marvin Häuser
  1 sibling, 0 replies; 4+ messages in thread
From: Marvin Häuser @ 2021-10-07 10:29 UTC (permalink / raw)
  To: devel, ianx.kuo
  Cc: amy.chan, ray.ni, Michael D Kinney, Liming Gao, Zhiguang Liu

On 06/10/2021 02:30, IanX Kuo wrote:
> From: IanX Kuo <ianx.kuo@intel.com>
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3675
>
> Add QuickSort function into BaseLib
>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> Signed-off-by: IanX Kuo <ianx.kuo@intel.com>
> ---
>   MdePkg/Include/Library/BaseLib.h              |  49 ++++++++
>   MdePkg/Library/BaseLib/BaseLib.inf            |   1 +
>   MdePkg/Library/BaseLib/QuickSort.c            | 116 ++++++++++++++++++
>   .../Library/BaseLib/UnitTestHostBaseLib.inf   |   3 +-
>   4 files changed, 168 insertions(+), 1 deletion(-)
>   create mode 100644 MdePkg/Library/BaseLib/QuickSort.c
>
> diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
> index 2452c1d92e..0ae0f4e6af 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -2856,6 +2856,55 @@ RemoveEntryList (
>   //
>   // Math Services
>   //
> +/**
> +  Prototype for comparison function for any two element types.
> +
> +  @param[in] Buffer1                  The pointer to first buffer.
> +  @param[in] Buffer2                  The pointer to second buffer.
> +
> +  @retval 0                           Buffer1 equal to Buffer2.
> +  @return <0                          Buffer1 is less than Buffer2.
> +  @return >0                          Buffer1 is greater than Buffer2.
> +**/
> +typedef
> +INTN
> +(EFIAPI *BASE_SORT_COMPARE)(
> +  IN CONST VOID                 *Buffer1,
> +  IN CONST VOID                 *Buffer2
> +  );
> +
> +/**
> +  This function is identical to perform QuickSort,
> +  except that is uses the pre-allocated buffer so the in place sorting does not need to
> +  allocate and free buffers constantly.
> +
> +  Each element must be equal sized.
> +
> +  if BufferToSort is NULL, then ASSERT.
> +  if CompareFunction is NULL, then ASSERT.
> +  if BufferOneElement is NULL, then ASSERT.
> +  if ElementSize is < 1, then ASSERT.
> +
> +  if Count is < 2 then perform no action.
> +
> +  @param[in, out] BufferToSort   on call a Buffer of (possibly sorted) elements
> +                                 on return a buffer of sorted elements
> +  @param[in] Count               the number of elements in the buffer to sort
> +  @param[in] ElementSize         Size of an element in bytes
> +  @param[in] CompareFunction     The function to call to perform the comparison
> +                                 of any 2 elements
> +  @param[out] BufferOneElement   Caller provided buffer whose size equals to ElementSize.
> +                                 It's used by QuickSort() for swapping in sorting.
> +**/
> +VOID
> +EFIAPI
> +QuickSort (
> +  IN OUT VOID                           *BufferToSort,
> +  IN CONST UINTN                        Count,
> +  IN CONST UINTN                        ElementSize,
> +  IN       BASE_SORT_COMPARE            CompareFunction,
> +  OUT VOID                              *BufferOneElement
> +  );
>   
>   /**
>     Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
> index 6efa5315b6..cebda3b210 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -32,6 +32,7 @@
>     SwapBytes16.c
>     LongJump.c
>     SetJump.c
> +  QuickSort.c
>     RShiftU64.c
>     RRotU64.c
>     RRotU32.c
> diff --git a/MdePkg/Library/BaseLib/QuickSort.c b/MdePkg/Library/BaseLib/QuickSort.c
> new file mode 100644
> index 0000000000..3aff18188b
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/QuickSort.c
> @@ -0,0 +1,116 @@
> +/** @file
> +  Math worker functions.
> +
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "BaseLibInternals.h"
> +
> +/**
> +  This function is identical to perform QuickSort,
> +  except that is uses the pre-allocated buffer so the in place sorting does not need to
> +  allocate and free buffers constantly.
> +
> +  Each element must be equal sized.
> +
> +  if BufferToSort is NULL, then ASSERT.
> +  if CompareFunction is NULL, then ASSERT.
> +  if BufferOneElement is NULL, then ASSERT.
> +  if ElementSize is < 1, then ASSERT.
> +
> +  if Count is < 2 then perform no action.
> +
> +  @param[in, out] BufferToSort   on call a Buffer of (possibly sorted) elements
> +                                 on return a buffer of sorted elements
> +  @param[in] Count               the number of elements in the buffer to sort
> +  @param[in] ElementSize         Size of an element in bytes
> +  @param[in] CompareFunction     The function to call to perform the comparison
> +                                 of any 2 elements
> +  @param[out] BufferOneElement   Caller provided buffer whose size equals to ElementSize.
> +                                 It's used by QuickSort() for swapping in sorting.
> +**/
> +VOID
> +EFIAPI
> +QuickSort (
> +  IN OUT VOID                           *BufferToSort,
> +  IN CONST UINTN                        Count,
> +  IN CONST UINTN                        ElementSize,
> +  IN       BASE_SORT_COMPARE            CompareFunction,
> +  OUT VOID                              *BufferOneElement
> +  )
> +{
> +  VOID        *Pivot;
> +  UINTN       LoopCount;
> +  UINTN       NextSwapLocation;
> +
> +  ASSERT (BufferToSort     != NULL);
> +  ASSERT (CompareFunction  != NULL);
> +  ASSERT (BufferOneElement != NULL);
> +  ASSERT (ElementSize      >= 1);
> +
> +  if (Count < 2) {
> +    return;
> +  }
> +
> +  NextSwapLocation = 0;
> +
> +  //
> +  // pick a pivot (we choose last element)
> +  //
> +  Pivot = ((UINT8*) BufferToSort + ((Count - 1) * ElementSize));
> +
> +  //
> +  // Now get the pivot such that all on "left" are below it
> +  // and everything "right" are above it
> +  //
> +  for (LoopCount = 0; LoopCount < Count -1; LoopCount++) {
> +    //
> +    // if the pivot is greater than the element.

This comment was rewritten, but semantically means the exact same thing 
as before. The point is that the below code swaps also on equality (<*=* 
0) as well.

Thanks for the changes!

Best regards,
Marvin

> +    //
> +    if (CompareFunction ((VOID*) ((UINT8*) BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0){
> +      //
> +      // swap
> +      //
> +      CopyMem (BufferOneElement, (UINT8*) BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> +      CopyMem ((UINT8*) BufferToSort + (NextSwapLocation * ElementSize), (UINT8*) BufferToSort + ((LoopCount) * ElementSize), ElementSize);
> +      CopyMem ((UINT8*) BufferToSort + ((LoopCount)*ElementSize), BufferOneElement, ElementSize);
> +
> +      //
> +      // increment NextSwapLocation
> +      //
> +      NextSwapLocation++;
> +    }
> +  }
> +  //
> +  // swap pivot to it's final position (NextSwapLocation)
> +  //
> +  CopyMem (BufferOneElement, Pivot, ElementSize);
> +  CopyMem (Pivot, (UINT8*) BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> +  CopyMem ((UINT8*) BufferToSort + (NextSwapLocation * ElementSize), BufferOneElement, ElementSize);
> +
> +  //
> +  // Now recurse on 2 partial lists.  neither of these will have the 'pivot' element
> +  // IE list is sorted left half, pivot element, sorted right half...
> +  //
> +  if (NextSwapLocation >= 2) {
> +    QuickSort (
> +      BufferToSort,
> +      NextSwapLocation,
> +      ElementSize,
> +      CompareFunction,
> +      BufferOneElement
> +      );
> +  }
> +
> +  if ((Count - NextSwapLocation - 1) >= 2) {
> +    QuickSort (
> +      (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> +      Count - NextSwapLocation - 1,
> +      ElementSize,
> +      CompareFunction,
> +      BufferOneElement
> +      );
> +  }
> +}
> diff --git a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> index eae1a7158d..d09bd12bef 100644
> --- a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> +++ b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> @@ -1,7 +1,7 @@
>   ## @file
>   #  Base Library implementation for use with host based unit tests.
>   #
> -#  Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
>   #  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
>   #  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
>   #  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> @@ -33,6 +33,7 @@
>     SwapBytes16.c
>     LongJump.c
>     SetJump.c
> +  QuickSort.c
>     RShiftU64.c
>     RRotU64.c
>     RRotU32.c


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-10-07 10:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-06  0:30 [PATCH v6 0/1] Add function QuickSort into MdePkg/BaseLib IanX Kuo
2021-10-06  0:30 ` [PATCH v6 1/1] MdePkg/BaseLib: Add QuickSort function on BaseLib IanX Kuo
2021-10-06  1:15   ` [edk2-devel] " guajen0710
2021-10-07 10:29   ` Marvin Häuser

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox