Paul Gofman : kernelbase: Move FlsAlloc() implementation to ntdll.RtlFlsAlloc().

Alexandre Julliard julliard at winehq.org
Thu Oct 1 15:50:29 CDT 2020


Module: wine
Branch: master
Commit: c955eee9e8ba92118f2192578128d4756030c7a4
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c955eee9e8ba92118f2192578128d4756030c7a4

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Tue Sep 29 23:15:29 2020 +0300

kernelbase: Move FlsAlloc() implementation to ntdll.RtlFlsAlloc().

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/fiber.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 dlls/kernelbase/thread.c    | 32 +-------------------------------
 dlls/ntdll/ntdll.spec       |  1 +
 dlls/ntdll/thread.c         | 43 +++++++++++++++++++++++++++++++++++++++++++
 include/winternl.h          |  1 +
 5 files changed, 88 insertions(+), 31 deletions(-)

diff --git a/dlls/kernel32/tests/fiber.c b/dlls/kernel32/tests/fiber.c
index db2bd0923b..b058dae749 100644
--- a/dlls/kernel32/tests/fiber.c
+++ b/dlls/kernel32/tests/fiber.c
@@ -18,6 +18,11 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <stdarg.h>
+
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
+#include <winternl.h>
 #include "wine/test.h"
 
 static LPVOID (WINAPI *pCreateFiber)(SIZE_T,LPFIBER_START_ROUTINE,LPVOID);
@@ -32,6 +37,7 @@ static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
 static BOOL (WINAPI *pFlsFree)(DWORD);
 static PVOID (WINAPI *pFlsGetValue)(DWORD);
 static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID);
+static NTSTATUS (WINAPI *pRtlFlsAlloc)(PFLS_CALLBACK_FUNCTION,DWORD*);
 
 static void *fibers[3];
 static BYTE testparam = 185;
@@ -44,6 +50,7 @@ static int cbCount = 0;
 static VOID init_funcs(void)
 {
     HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
+    HMODULE hntdll = GetModuleHandleA("ntdll.dll");
 
 #define X(f) p##f = (void*)GetProcAddress(hKernel32, #f);
     X(CreateFiber);
@@ -59,6 +66,11 @@ static VOID init_funcs(void)
     X(FlsGetValue);
     X(FlsSetValue);
 #undef X
+
+#define X(f) p##f = (void*)GetProcAddress(hntdll, #f);
+    X(RtlFlsAlloc);
+#undef X
+
 }
 
 static VOID WINAPI FiberLocalStorageProc(PVOID lpFlsData)
@@ -171,9 +183,14 @@ static void test_FiberHandling(void)
     if (pIsThreadAFiber) ok(!pIsThreadAFiber(), "IsThreadAFiber reported TRUE\n");
 }
 
+#define FLS_TEST_INDEX_COUNT 4096
+
 static void test_FiberLocalStorage(void)
 {
+    static DWORD fls_indices[FLS_TEST_INDEX_COUNT];
+    unsigned int i, count;
     DWORD fls, fls_2;
+    NTSTATUS status;
     BOOL ret;
     void* val;
 
@@ -183,6 +200,31 @@ static void test_FiberLocalStorage(void)
         return;
     }
 
+    if (pRtlFlsAlloc)
+    {
+        for (i = 0; i < FLS_TEST_INDEX_COUNT; ++i)
+        {
+            fls_indices[i] = 0xdeadbeef;
+            status = pRtlFlsAlloc(NULL, &fls_indices[i]);
+            ok(!status || status == STATUS_NO_MEMORY, "Got unexpected status %#x.\n", status);
+            if (status)
+            {
+                ok(fls_indices[i] == 0xdeadbeef, "Got unexpected index %#x.\n", fls_indices[i]);
+                break;
+            }
+        }
+        count = i;
+        /* FLS limits are increased since Win10 18312. */
+        ok(count && (count <= 127 || (count > 4000 && count < 4096)), "Got unexpected count %u.\n", count);
+
+        for (i = 0; i < count; ++i)
+            pFlsFree(fls_indices[i]);
+    }
+    else
+    {
+        win_skip("RtlFlsAlloc is not available.\n");
+    }
+
     /* Test an unallocated index
      * FlsFree should fail
      * FlsGetValue and FlsSetValue should succeed
diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c
index f20d460d07..c302bbd1b8 100644
--- a/dlls/kernelbase/thread.c
+++ b/dlls/kernelbase/thread.c
@@ -1066,38 +1066,8 @@ void WINAPI DECLSPEC_HOTPATCH SwitchToFiber( LPVOID fiber )
 DWORD WINAPI DECLSPEC_HOTPATCH FlsAlloc( PFLS_CALLBACK_FUNCTION callback )
 {
     DWORD index;
-    PEB * const peb = NtCurrentTeb()->Peb;
 
-    RtlAcquirePebLock();
-    if (!peb->FlsCallback &&
-        !(peb->FlsCallback = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                        8 * sizeof(peb->FlsBitmapBits) * sizeof(void*) )))
-    {
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-        index = FLS_OUT_OF_INDEXES;
-    }
-    else
-    {
-        index = RtlFindClearBitsAndSet( peb->FlsBitmap, 1, 1 );
-        if (index != ~0U)
-        {
-            if (!NtCurrentTeb()->FlsSlots &&
-                !(NtCurrentTeb()->FlsSlots = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                                        8 * sizeof(peb->FlsBitmapBits) * sizeof(void*) )))
-            {
-                RtlClearBits( peb->FlsBitmap, index, 1 );
-                index = FLS_OUT_OF_INDEXES;
-                SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-            }
-            else
-            {
-                NtCurrentTeb()->FlsSlots[index] = 0; /* clear the value */
-                peb->FlsCallback[index] = callback;
-            }
-        }
-        else SetLastError( ERROR_NO_MORE_ITEMS );
-    }
-    RtlReleasePebLock();
+    if (!set_ntstatus( RtlFlsAlloc( callback, &index ))) return FLS_OUT_OF_INDEXES;
     return index;
 }
 
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 0ec73d3d1d..aac2af26f3 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -666,6 +666,7 @@
 @ stdcall RtlFindSetRuns(ptr ptr long long)
 @ stdcall RtlFirstEntrySList(ptr)
 @ stdcall RtlFirstFreeAce(ptr ptr)
+@ stdcall RtlFlsAlloc(ptr ptr)
 @ stub RtlFlushPropertySet
 # @ stub RtlFlushSecureMemoryCache
 @ stdcall RtlFormatCurrentUserKeyPath(ptr)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 0f31fe18a7..f277a52dc0 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -246,3 +246,46 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
 {
     return NtCurrentTeb()->ActiveFrame;
 }
+
+
+/***********************************************************************
+ * Fibers
+ ***********************************************************************/
+
+
+/***********************************************************************
+ *              RtlFlsAlloc  (NTDLL.@)
+ */
+NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsAlloc( PFLS_CALLBACK_FUNCTION callback, DWORD *ret_index )
+{
+    PEB * const peb = NtCurrentTeb()->Peb;
+    NTSTATUS status = STATUS_NO_MEMORY;
+    DWORD index;
+
+    RtlAcquirePebLock();
+    if (peb->FlsCallback ||
+        (peb->FlsCallback = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                        8 * sizeof(peb->FlsBitmapBits) * sizeof(void*) )))
+    {
+        index = RtlFindClearBitsAndSet( peb->FlsBitmap, 1, 1 );
+        if (index != ~0U)
+        {
+            if (!NtCurrentTeb()->FlsSlots &&
+                !(NtCurrentTeb()->FlsSlots = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                                        8 * sizeof(peb->FlsBitmapBits) * sizeof(void*) )))
+            {
+                RtlClearBits( peb->FlsBitmap, index, 1 );
+            }
+            else
+            {
+                NtCurrentTeb()->FlsSlots[index] = 0; /* clear the value */
+                peb->FlsCallback[index] = callback;
+                status = STATUS_SUCCESS;
+            }
+        }
+    }
+    RtlReleasePebLock();
+    if (!status)
+        *ret_index = index;
+    return status;
+}
diff --git a/include/winternl.h b/include/winternl.h
index 7be69b2901..ba9d944259 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -3371,6 +3371,7 @@ NTSYSAPI ULONG     WINAPI RtlFindSetBits(PCRTL_BITMAP,ULONG,ULONG);
 NTSYSAPI ULONG     WINAPI RtlFindSetBitsAndClear(PRTL_BITMAP,ULONG,ULONG);
 NTSYSAPI ULONG     WINAPI RtlFindSetRuns(PCRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN);
 NTSYSAPI BOOLEAN   WINAPI RtlFirstFreeAce(PACL,PACE_HEADER *);
+NTSYSAPI NTSTATUS  WINAPI RtlFlsAlloc(PFLS_CALLBACK_FUNCTION,ULONG *);
 NTSYSAPI NTSTATUS  WINAPI RtlFormatCurrentUserKeyPath(PUNICODE_STRING);
 NTSYSAPI NTSTATUS  WINAPI RtlFormatMessage(LPCWSTR,ULONG,BOOLEAN,BOOLEAN,BOOLEAN,__ms_va_list *,LPWSTR,ULONG,ULONG*);
 NTSYSAPI NTSTATUS  WINAPI RtlFormatMessageEx(LPCWSTR,ULONG,BOOLEAN,BOOLEAN,BOOLEAN,__ms_va_list *,LPWSTR,ULONG,ULONG*,ULONG);




More information about the wine-cvs mailing list