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

Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2020-09-29 23:15:29 +03:00 committed by Alexandre Julliard
parent d25854ad31
commit c955eee9e8
5 changed files with 88 additions and 31 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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);