From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) by mx.groups.io with SMTP id smtpd.web12.28381.1632730494217930578 for ; Mon, 27 Sep 2021 01:14:55 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@posteo.de header.s=2017 header.b=HRonwcOK; spf=pass (domain: posteo.de, ip: 185.67.36.66, mailfrom: mhaeuser@posteo.de) Received: from submission (posteo.de [89.146.220.130]) by mout02.posteo.de (Postfix) with ESMTPS id 89C92240109 for ; Mon, 27 Sep 2021 10:14:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.de; s=2017; t=1632730490; bh=/6qq9WrwLT7l1p8sQyIBiK4lS7doqA8lsfHI2Pevde8=; h=Subject:To:Cc:From:Date:From; b=HRonwcOKVr2Tzns8UIGWu7qOAPXLZiDVhK8G/6/IE+LadtPuvbezzWy3Chm38swzl CzwmleQvX4y2+SdTfpFtaEjM7AEWY8z8VRIRNH1DEjx3zP9mFvnz/fsScgBqgAICU0 R1klIZj3fchJ0wNv5hwL5CvofIHQmZ1p494TKcwKfyj8PeQBI8ZxPwthh5dBQDhXOr Dxmrrr6s1fG7kIKiLteGH+aDBW0adqcYdg41lO/fKxDnEwsJ5422iFHWMyuUFbwm/c KMWImQtwPVjMnk4ypsw5abk55q1QJCP/7X5HRrlKgZTSdoJk3Fz7u2vmVlKRC2VVgJ H701Md6lAmHgg== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4HHwRC3XHJz9rxK; Mon, 27 Sep 2021 10:14:47 +0200 (CEST) Subject: Re: [edk2-devel] RFC: Add BaseLib/QuickSort in MdePkg To: "fanjianfeng@byosoft.com.cn" , "devel@edk2.groups.io" , "Ni, Ray" , 'gaoliming' , "Chan, Amy" , 'Andrew Fish' Cc: "Kinney, Michael D" , "'Gao, Liming'" , "Liu, Zhiguang" , "Wang, Jian J" , "Gao, Zhichao" References: <001a01d7aa99$d744af80$85ce0e80$@byosoft.com.cn> <003401d7aaa1$c7166830$55433890$@byosoft.com.cn> <16A70FAC1585C7C1.27516@groups.io> <00cf01d7b27a$59145d20$0b3d1760$@byosoft.com.cn> <2021092708451371303013@byosoft.com.cn> From: =?UTF-8?B?TWFydmluIEjDpHVzZXI=?= Message-ID: <7c260e5d-363e-8579-5a38-3cc5e2336bdb@posteo.de> Date: Mon, 27 Sep 2021 08:14:47 +0000 MIME-Version: 1.0 In-Reply-To: <2021092708451371303013@byosoft.com.cn> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-GB Content-Transfer-Encoding: quoted-printable On 27/09/2021 02:45, fanjianfeng@byosoft.com.cn wrote: > Making baselib implementation depend on MemoryAllocationLib=20 > (indirectly on Pei Service and gBS), it may prevent=20 > this=C2=A0base=C2=A0API=C2=A0using=C2=A0at some=C2=A0seneraio. i don't th= ink it's better. That is why I asked about a split-API scenario, one of which does not=20 depend on dynamic memory allocation (SetVariable-like) and one does=20 (wrapper-like). > Add this parameter and make this parameter is optional, > 1, when NULL, use the local 256 bytes stack > 2, if 256 bytes stack is not enough, return RETURE_BUFFER_TOO_SAMLL, > 3, caller check the return status, to do nothing=C2=A0or to allocate enou= gh=20 > buffer for retry > > This is just like SetVariable()'s implementation. Yes, and because that is SetVariable's implementation, we have library=20 functions to make it less error-prone and more convenient [1]. As a=20 matter of fact, we have a (semi-lax) policy in our codebases to avoid=20 such functions like the plague and use those library wrappers where-ever=20 it can make sense. The only super-rare exceptions I can think of are=20 when we know the size of the element ahead of time. Also SetVariable has=20 no arbitrary constraint on when it may work the first time, and there is=20 code that will fail when the first return is not EFI_BUFFER_TOO_SMALL. This solution honestly yields even more problems, because it introduces=20 a Status return which was not there before. For common code safety and=20 quality policy, this requires the value *must* be retrieved and checked=20 in some fashion. So all callers, no matter the prior knowledge of the=20 element size, now need either a runtime check and handling for a status=20 that they (may) know can never be returned, or ASSERTs if the function=20 spec really imposes the arbitrary 256 Bytes constraint. Latter doesn't=20 really work I think. What if someone wants to sort in SEC and noticed=20 they only have 64 Bytes on the stack to work with, realistically? Any=20 code depending on the 256 Byte constraint, passing NULL and not doing=20 additional handling, would seize to work. Former is too complicated, see=20 wrappers. In my opinion, the memory must *either* be fully managed by=20 the caller *or* the callee (and you may have both in separate functions,=20 as I suggested), but not sometimes here, sometimes there. Best regards, Marvin [1]=20 https://github.com/tianocore/edk2/blob/46b4606ba23498d3d0e66b53e498eb3d5d59= 2586/MdePkg/Library/UefiLib/UefiLib.c#L1309-L1360 > > ------------------------------------------------------------------------ > Jeff > fanjianfeng@byosoft.com.cn > > *From:* Marvin H=C3=A4user > *Date:*=C2=A02021-09-26=C2=A019:20 > *To:* devel ; ray.ni > ; gaoliming > ; Chan, Amy > ; 'Andrew Fish' > *CC:* Kinney, Michael D ; 'Gao, > Liming' ; Liu, Zhiguang > ; Wang, Jian J > ; Gao, Zhichao > > *Subject:*=C2=A0Re: [edk2-devel] RFC: Add BaseLib/QuickSort in MdePkg > Hey Ray, > In my opinion that spec is too complicated. For some cases it is > obvious, but I think the last anyone wants to see is a > (STATIC_)ASSERT > before most QuickSort calls to ensure the element size *really* is <= =3D > 256 Bytes. In my opinion, there are two roads: > 1) Make the parameter required (I think this is what Liming > suggested). > The caller would always need to provide said buffer, and it can do > as it > sees fit - on the stack, in a pool, in a page, who knows. > 2) Remove the parameter entirely. The library would depend on > MemoryAllocationLib again, but also would have an optimisation by > choosing stack vs pool based on ElementSize. > Usually I would prefer 2), as it is less prone to caller errors, but > considering the low-level nature of edk2, I can totally see the > point to > allow the caller to control whether there are dynamic memory > allocations > made or not as possible with 1). 2) could technically also be a > wrapper > for 1) if you want granular control and convenience/safety (why not > actually?). > Both approaches have the advantage that it is crystal-clear what the > caller's job is - to always or to never allocate the buffer. > Best regards, > Marvin > On 26/09/2021 04:24, Ni, Ray wrote: > > > > Liming, > > > > The purpose of the optional BufferOneElement is to ease consumer=E2= =80=99s > > life assuming most of the time the element size should be > smaller than > > 256. > > > > Are you saying that it=E2=80=99s a bit hard to calculate the actual > value of > > sizeof (Element) when writing code? > > > > I recommend consumer always allocates memory if it=E2=80=99s hard t= o judge > > sizeof (Element) < 256. > > > > Searching edk2 code, I can find below code using PerformQuickSort()= : > > > >=C2=A0 1. ShellPkg/UefiShellCommandLib: It=E2=80=99s sorting array o= f > >=C2=A0=C2=A0=C2=A0=C2=A0 (EFI_DEVICE_PATH_PROTOCOL *). > >=C2=A0 2. UefiCpuPkg/CpuCacheInfoLib: It=E2=80=99s sorting array of > =C2=A0CPU_CACHE_INFO. > >=C2=A0 3. MinPlatformPkg/AcpiTables: It=E2=80=99s sorting array of > EFI_CPU_ID_ORDER_MAP. > >=C2=A0 4. MdeModulePkg/UefiBootManagerLib: It=E2=80=99s sorting arra= y of > >=C2=A0=C2=A0=C2=A0=C2=A0 EFI_BOOT_MANAGER_LOAD_OPTION. > >=C2=A0 5. MdeModulePkg/CapsuleApp: It=E2=80=99s sorting array of (EF= I_FILE_INFO *) > >=C2=A0 6. CryptoPkg/CrtWrapper: It=E2=80=99s sorting array of (unkno= wn type). > >=C2=A0 7. RedfishPkg/RedfishCrtLib: It=E2=80=99s sorting array of (u= nknown type). > > > > For 1~5, it=E2=80=99s easy to know that the size of the element is = smaller > > than 256. The AllocatePool() can be skipped. > > > > Thanks, > > > > Ray > > > > *From:*gaoliming > > *Sent:* Sunday, September 26, 2021 10:01 AM > > *To:* Ni, Ray ; devel@edk2.groups.io; Chan, Amy > > ; 'Andrew Fish' > > *Cc:* Kinney, Michael D ; 'Gao, Liming' > > ; Liu, Zhiguang ; > Wang, > > Jian J ; Gao, Zhichao > > *Subject:* =E5=9B=9E=E5=A4=8D: [edk2-devel] RFC: Add BaseLib/QuickS= ort in MdePkg > > > > Ray: > > > > I may suggest to always require BufferOneElement. The consumer code > > may not know ElementSize. To avoid the error, the consumer must > > allocate buffer for BufferOneElement. If so, BufferOneElement is > the > > required parameter. > > > > Thanks > > > > Liming > > > > *=E5=8F=91=E4=BB=B6=E4=BA=BA**:*Ni, Ray > > > *=E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:* 2021=E5=B9=B49=E6=9C=8824= =E6=97=A5 11:53 > > *=E6=94=B6=E4=BB=B6=E4=BA=BA:* devel@edk2.groups.io ; Ni, > Ray > > >; Chan, Amy > > >; gaoliming > > >; > 'Andrew > > Fish' > > > *=E6=8A=84=E9=80=81:* Kinney, Michael D > >; 'Gao, Liming' > > >; Liu, Zhiguang > > >; Wang, > Jian J > > >; Gao, > Zhichao > > > > > *=E4=B8=BB=E9=A2=98:* RE: [edk2-devel] RFC: Add BaseLib/QuickSort i= n MdePkg > > > > More details on new QuickSort() API: > > > > The new API needs to carry additional parameter =E2=80=9CBufferOneE= lement=E2=80=9D. > > > > This parameter gives QuickSort() the temporary buffer for > swapping in > > sorting. > > > > It=E2=80=99s to avoid BaseLib depends on MemoryAllocationLib. > > > > =E2=80=A6 > > > > @param [in] BufferOneElement =C2=A0When ElementSize > 256, caller > needs to > > provide a buffer whose size > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0equals to ElementSize. It=E2=80=99s used = by > > QuickSort() for swapping in sorting. > > > > When ElementSize <=3D 256, QuickSort() uses a local stack 256-byte > buffer. > > > > @retval EFI_INVALID_PARAMETER When (ElementSize > 256) and > > (BufferOneElement =3D=3D NULL). > > > > =E2=80=A6 > > > > VOID > > > > EFIAPI > > > > QuickSort=C2=A0( > > > > =C2=A0=C2=A0IN=C2=A0OUT VOID=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*BufferToSort, > > > > =C2=A0=C2=A0IN=C2=A0CONST=C2=A0UINTN ElementCount, > > > > =C2=A0=C2=A0IN=C2=A0CONST=C2=A0UINTN ElementSize, > > > > =C2=A0=C2=A0IN=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SORT_COMPAR= E CompareFunction, > > > > IN VOID=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 *BufferOneElement OPTIONAL > > > > ); > > > > Any comments? > > > > *From:*devel@edk2.groups.io > > > *On Behalf Of > > *Ni, Ray > > *Sent:* Wednesday, September 22, 2021 2:04 PM > > *To:* Chan, Amy >; > > gaoliming > >; 'Andrew Fish' > >; 'edk2-devel-groups-io' > > > > > *Cc:* Kinney, Michael D > >; 'Gao, Liming' > > >; Liu, Zhiguang > > >; Wang, > Jian J > > >; Gao, > Zhichao > > > > > *Subject:* Re: [edk2-devel] RFC: Add BaseLib/QuickSort in MdePkg > > > > I don=E2=80=99t see objection so far. > > > > So, the final solution is: > > > >=C2=A0 1. Add QuickSort() API to BaseLib in MdePkg. > >=C2=A0 2. Update existing=C2=A0MdeModulePkg/SortLib to use QuickSort= () in the > >=C2=A0=C2=A0=C2=A0=C2=A0 implementation (proposed by Andrew Fish and= Liming Gao) > >=C2=A0 3. Update UefiCpuPkg to use QuickSortLib to remove improper > >=C2=A0=C2=A0=C2=A0=C2=A0 dependency on MdeModulePkg > > > > Thanks, > > > > Ray > > > > *From:*Ni, Ray > > *Sent:* Thursday, September 16, 2021 10:48 AM > > *To:* Chan, Amy >; > > gaoliming > >; 'Andrew Fish' > >; 'edk2-devel-groups-io' > > > > > *Cc:* Kinney, Michael D > >; 'Gao, Liming' > > >; Liu, Zhiguang > > >; Wang, > Jian J > > >; Gao, > Zhichao > > > > > *Subject:* RE: [edk2-devel] RFC: Add BaseLib/QuickSort in MdePkg > > > > Amy, > > > > No. We only Add QuickSort() function API into BaseLib.h. > > > > *From:*Chan, Amy > > > *Sent:* Thursday, September 16, 2021 10:46 AM > > *To:* gaoliming > >; 'Andrew Fish' > >; 'edk2-devel-groups-io' > > > > > *Cc:* Ni, Ray >; Kinney, > > Michael D > >; 'Gao, Liming' > > >; Liu, Zhiguang > > >; Wang, > Jian J > > >; Gao, > Zhichao > > > > > *Subject:* RE: [edk2-devel] RFC: Add BaseLib/QuickSort in MdePkg > > > > Just to double confirm, will we have the null instance of > QuickSort in > > MdePkg? > > > > Regards, > > > > Amy > > > > *From:*gaoliming > > > > *Sent:* Thursday, September 16, 2021 10:23 AM > > *To:* 'Andrew Fish' >; > > 'edk2-devel-groups-io' > > > > *Cc:* Ni, Ray >; Kinney, > > Michael D > >; 'Gao, Liming' > > >; Liu, Zhiguang > > >; Wang, > Jian J > > >; Gao, > Zhichao > > >; Chan, Amy > > > > > *Subject:* =E5=9B=9E=E5=A4=8D: [edk2-devel] RFC: Add BaseLib/QuickS= ort in MdePkg > > > > Andrew: > > > > Thanks for your suggestion. I think your idea is better. We add new > > QuickSort() API to BaseLib, and update SortLib library instance to > > consume BaseLib QuickSort() API. This way has no change in current > > SortLib library class. It is the compatible solution. > > > > Thanks > > > > Liming > > > > *=E5=8F=91=E4=BB=B6=E4=BA=BA**:*Andrew Fish > > > *=E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:* 2021=E5=B9=B49=E6=9C=8816= =E6=97=A5 10:13 > > *=E6=94=B6=E4=BB=B6=E4=BA=BA:* edk2-devel-groups-io > >; Liming Gao > > > > > *=E6=8A=84=E9=80=81:* Ni, Ray >; Mike > > Kinney > >; Gao, Liming > > >; Liu, Zhiguang > > >; Wang, > Jian J > > >; Gao, > Zhichao > > >; Chan, Amy > > > > > *=E4=B8=BB=E9=A2=98:* Re: [edk2-devel] RFC: Add BaseLib/QuickSort i= n MdePkg > > > >=C2=A0=C2=A0=C2=A0=C2=A0 On Sep 15, 2021, at 6:26 PM, gaoliming >=C2=A0=C2=A0=C2=A0=C2=A0 > wrote: > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Ray: > > > >=C2=A0=C2=A0=C2=A0=C2=A0 SortLib has been added since 2015. I would = suggest to still keep > >=C2=A0=C2=A0=C2=A0=C2=A0 this library class. To resolve the package = dependency, my > proposal > >=C2=A0=C2=A0=C2=A0=C2=A0 is to move the library class header file So= rtLib.h from > >=C2=A0=C2=A0=C2=A0=C2=A0 MdeModulePkg to MdePkg, and still keep the = library instance in > >=C2=A0=C2=A0=C2=A0=C2=A0 MdeModulePkg. This proposal has no impact o= n the existing > platform. > > > > If we add QuickSort() API to the BaseLib can we not just port the > > existing=C2=A0MdeModulePkg/SortLib to use QuickSort() in the > > implementation? Or is there some other way to add the new thing > in a > > backward compatible way. > > > > Thanks, > > > > Andrew Fish > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Thanks > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Liming > > > >=C2=A0=C2=A0=C2=A0=C2=A0 *=E5=8F=91=E4=BB=B6=E4=BA=BA**:*devel@edk2.= groups.io > > > >*=E4=BB=A3=E8=A1=A8***Ni, Ray > >=C2=A0=C2=A0=C2=A0=C2=A0 *=E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:*2021= =E5=B9=B49=E6=9C=8814=E6=97=A514:15 > >=C2=A0=C2=A0=C2=A0=C2=A0 *=E6=94=B6=E4=BB=B6=E4=BA=BA:*Kinney, Micha= el D >=C2=A0=C2=A0=C2=A0=C2=A0 >; Gao, = Liming > >=C2=A0=C2=A0=C2=A0=C2=A0 >; Liu, > >=C2=A0=C2=A0=C2=A0=C2=A0 Zhiguang >; > >=C2=A0=C2=A0=C2=A0=C2=A0 Wang, Jian J >=C2=A0=C2=A0=C2=A0=C2=A0 >; Gao, Zhich= ao > >=C2=A0=C2=A0=C2=A0=C2=A0 > > >=C2=A0=C2=A0=C2=A0=C2=A0 *=E6=8A=84=E9=80=81:*devel@edk2.groups.io <= mailto:devel@edk2.groups.io>; > Chan, Amy > >=C2=A0=C2=A0=C2=A0=C2=A0 > > >=C2=A0=C2=A0=C2=A0=C2=A0 *=E4=B8=BB=E9=A2=98:*[edk2-devel] RFC: Add = BaseLib/QuickSort in MdePkg > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Hi package maintainers of MdePkg, MdeModule= Pkg and ShellPkg, > >=C2=A0=C2=A0=C2=A0=C2=A0 community, > > > >=C2=A0=C2=A0=C2=A0=C2=A0 A commit (UefiCpuPkg/CpuCacheInfoLib: Sort = CpuCacheInfo array > > > ) > >=C2=A0=C2=A0=C2=A0=C2=A0 to UefiCpuPkg let > >=C2=A0=C2=A0=C2=A0=C2=A0 UefiCpuPkg depend on MdeModulePkg because t= he SortLib class and > >=C2=A0=C2=A0=C2=A0=C2=A0 instances are all in MdeModulePkg. > > > >=C2=A0=C2=A0=C2=A0=C2=A0 UefiCpuPkg depending on MdeModulePkg breaks= the rule that > >=C2=A0=C2=A0=C2=A0=C2=A0 =E2=80=9CUefiCpuPkg should ONLY depend on M= dePkg=E2=80=9D. > > > >=C2=A0=C2=A0=C2=A0=C2=A0 To address this issue, there are two approa= ches: > > > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 1. Duplicate the sort logic in UefiCp= uPkg to not depend on > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 MdeModulePkg/SortLi= b > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 2. Add QuickSort() API to BaseLib in = MdePkg. > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Approach #2 (MdePkg/BaseLib/QuickSort) make= s more sense because > >=C2=A0=C2=A0=C2=A0=C2=A0 quick sort is a standard algorithm. > > > >=C2=A0=C2=A0=C2=A0=C2=A0 We encourage consumers to update their code= to use the quick > sort > >=C2=A0=C2=A0=C2=A0=C2=A0 in MdePkg and gradually deprecate today=E2= =80=99s MdeModulePkg/SortLib. > > > >=C2=A0=C2=A0=C2=A0=C2=A0 If you don=E2=80=99t have concerns, I plan = to: > > > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 1. =E2=80=9CAdd QuickSort() to BaseLi= b=E2=80=9D and update all existing > consumers > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 to use this API ins= tead. > > > >=C2=A0=C2=A0=C2=A0=C2=A0 VOID > > > >=C2=A0=C2=A0=C2=A0=C2=A0 EFIAPI > > > >=C2=A0=C2=A0=C2=A0=C2=A0 QuickSort=C2=A0( > > > >=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0IN=C2=A0OUT=C2=A0VOID=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*BufferToSort, > > > >=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0IN=C2=A0CONST=C2=A0UINTN Count, > > > >=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0IN=C2=A0CONST=C2=A0UINTN Elemen= tSize, > > > > =C2=A0=C2=A0IN=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SORT_COMPAR= E=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0CompareFunction > > > >=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0); > > > >=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 2. =E2=80=9CAdd new ShellPkg/SortComp= areLib=E2=80=9D > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Background: ShellPkg requires to sort devic= epath/string so 3 > APIs > >=C2=A0=C2=A0=C2=A0=C2=A0 in UefiSortLib (DevicePathCompare, StringNo= CaseCompare, > >=C2=A0=C2=A0=C2=A0=C2=A0 StringCompare) are provided for Shell usage= . we can move the 3 > >=C2=A0=C2=A0=C2=A0=C2=A0 APIs to the SortCompareLib and update Shell= code to use > >=C2=A0=C2=A0=C2=A0=C2=A0 BaseLib/QuickSort directly, with the sort c= ompare function from > >=C2=A0=C2=A0=C2=A0=C2=A0 SortCompareLib. > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Any concerns? > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Thanks, > > > >=C2=A0=C2=A0=C2=A0=C2=A0 Ray > > > > > =20 >