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