Commit c955eee9 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

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

parent d25854ad
...@@ -18,6 +18,11 @@ ...@@ -18,6 +18,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 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" #include "wine/test.h"
static LPVOID (WINAPI *pCreateFiber)(SIZE_T,LPFIBER_START_ROUTINE,LPVOID); static LPVOID (WINAPI *pCreateFiber)(SIZE_T,LPFIBER_START_ROUTINE,LPVOID);
...@@ -32,6 +37,7 @@ static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION); ...@@ -32,6 +37,7 @@ static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
static BOOL (WINAPI *pFlsFree)(DWORD); static BOOL (WINAPI *pFlsFree)(DWORD);
static PVOID (WINAPI *pFlsGetValue)(DWORD); static PVOID (WINAPI *pFlsGetValue)(DWORD);
static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID); static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID);
static NTSTATUS (WINAPI *pRtlFlsAlloc)(PFLS_CALLBACK_FUNCTION,DWORD*);
static void *fibers[3]; static void *fibers[3];
static BYTE testparam = 185; static BYTE testparam = 185;
...@@ -44,6 +50,7 @@ static int cbCount = 0; ...@@ -44,6 +50,7 @@ static int cbCount = 0;
static VOID init_funcs(void) static VOID init_funcs(void)
{ {
HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f); #define X(f) p##f = (void*)GetProcAddress(hKernel32, #f);
X(CreateFiber); X(CreateFiber);
...@@ -59,6 +66,11 @@ static VOID init_funcs(void) ...@@ -59,6 +66,11 @@ static VOID init_funcs(void)
X(FlsGetValue); X(FlsGetValue);
X(FlsSetValue); X(FlsSetValue);
#undef X #undef X
#define X(f) p##f = (void*)GetProcAddress(hntdll, #f);
X(RtlFlsAlloc);
#undef X
} }
static VOID WINAPI FiberLocalStorageProc(PVOID lpFlsData) static VOID WINAPI FiberLocalStorageProc(PVOID lpFlsData)
...@@ -171,9 +183,14 @@ static void test_FiberHandling(void) ...@@ -171,9 +183,14 @@ static void test_FiberHandling(void)
if (pIsThreadAFiber) ok(!pIsThreadAFiber(), "IsThreadAFiber reported TRUE\n"); if (pIsThreadAFiber) ok(!pIsThreadAFiber(), "IsThreadAFiber reported TRUE\n");
} }
#define FLS_TEST_INDEX_COUNT 4096
static void test_FiberLocalStorage(void) static void test_FiberLocalStorage(void)
{ {
static DWORD fls_indices[FLS_TEST_INDEX_COUNT];
unsigned int i, count;
DWORD fls, fls_2; DWORD fls, fls_2;
NTSTATUS status;
BOOL ret; BOOL ret;
void* val; void* val;
...@@ -183,6 +200,31 @@ static void test_FiberLocalStorage(void) ...@@ -183,6 +200,31 @@ static void test_FiberLocalStorage(void)
return; 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 /* Test an unallocated index
* FlsFree should fail * FlsFree should fail
* FlsGetValue and FlsSetValue should succeed * FlsGetValue and FlsSetValue should succeed
......
...@@ -1066,38 +1066,8 @@ void WINAPI DECLSPEC_HOTPATCH SwitchToFiber( LPVOID fiber ) ...@@ -1066,38 +1066,8 @@ void WINAPI DECLSPEC_HOTPATCH SwitchToFiber( LPVOID fiber )
DWORD WINAPI DECLSPEC_HOTPATCH FlsAlloc( PFLS_CALLBACK_FUNCTION callback ) DWORD WINAPI DECLSPEC_HOTPATCH FlsAlloc( PFLS_CALLBACK_FUNCTION callback )
{ {
DWORD index; DWORD index;
PEB * const peb = NtCurrentTeb()->Peb;
RtlAcquirePebLock(); if (!set_ntstatus( RtlFlsAlloc( callback, &index ))) return FLS_OUT_OF_INDEXES;
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();
return index; return index;
} }
......
...@@ -666,6 +666,7 @@ ...@@ -666,6 +666,7 @@
@ stdcall RtlFindSetRuns(ptr ptr long long) @ stdcall RtlFindSetRuns(ptr ptr long long)
@ stdcall RtlFirstEntrySList(ptr) @ stdcall RtlFirstEntrySList(ptr)
@ stdcall RtlFirstFreeAce(ptr ptr) @ stdcall RtlFirstFreeAce(ptr ptr)
@ stdcall RtlFlsAlloc(ptr ptr)
@ stub RtlFlushPropertySet @ stub RtlFlushPropertySet
# @ stub RtlFlushSecureMemoryCache # @ stub RtlFlushSecureMemoryCache
@ stdcall RtlFormatCurrentUserKeyPath(ptr) @ stdcall RtlFormatCurrentUserKeyPath(ptr)
......
...@@ -246,3 +246,46 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void) ...@@ -246,3 +246,46 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
{ {
return NtCurrentTeb()->ActiveFrame; 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;
}
...@@ -3371,6 +3371,7 @@ NTSYSAPI ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP,ULONG,ULONG); ...@@ -3371,6 +3371,7 @@ NTSYSAPI ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP,ULONG,ULONG);
NTSYSAPI ULONG WINAPI RtlFindSetBitsAndClear(PRTL_BITMAP,ULONG,ULONG); NTSYSAPI ULONG WINAPI RtlFindSetBitsAndClear(PRTL_BITMAP,ULONG,ULONG);
NTSYSAPI ULONG WINAPI RtlFindSetRuns(PCRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN); NTSYSAPI ULONG WINAPI RtlFindSetRuns(PCRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN);
NTSYSAPI BOOLEAN WINAPI RtlFirstFreeAce(PACL,PACE_HEADER *); NTSYSAPI BOOLEAN WINAPI RtlFirstFreeAce(PACL,PACE_HEADER *);
NTSYSAPI NTSTATUS WINAPI RtlFlsAlloc(PFLS_CALLBACK_FUNCTION,ULONG *);
NTSYSAPI NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(PUNICODE_STRING); NTSYSAPI NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(PUNICODE_STRING);
NTSYSAPI NTSTATUS WINAPI RtlFormatMessage(LPCWSTR,ULONG,BOOLEAN,BOOLEAN,BOOLEAN,__ms_va_list *,LPWSTR,ULONG,ULONG*); 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); NTSYSAPI NTSTATUS WINAPI RtlFormatMessageEx(LPCWSTR,ULONG,BOOLEAN,BOOLEAN,BOOLEAN,__ms_va_list *,LPWSTR,ULONG,ULONG*,ULONG);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment