kernel32/tests: Add tests for RtlInterlockedPushListSList[Ex].
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
38d0690a2c
commit
32f72989b6
|
@ -28,6 +28,9 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
#undef __fastcall
|
||||
#define __fastcall __stdcall
|
||||
|
||||
static BOOL (WINAPI *pChangeTimerQueueTimer)(HANDLE, HANDLE, ULONG, ULONG);
|
||||
static HANDLE (WINAPI *pCreateTimerQueue)(void);
|
||||
static BOOL (WINAPI *pCreateTimerQueueTimer)(PHANDLE, HANDLE, WAITORTIMERCALLBACK,
|
||||
|
@ -61,6 +64,48 @@ static NTSTATUS (WINAPI *pNtAllocateVirtualMemory)(HANDLE, PVOID *, ULONG, SIZE_
|
|||
static NTSTATUS (WINAPI *pNtFreeVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG);
|
||||
static NTSTATUS (WINAPI *pNtWaitForSingleObject)(HANDLE, BOOLEAN, const LARGE_INTEGER *);
|
||||
static NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*);
|
||||
static PSLIST_ENTRY (__fastcall *pRtlInterlockedPushListSList)(PSLIST_HEADER list, PSLIST_ENTRY first,
|
||||
PSLIST_ENTRY last, ULONG count);
|
||||
static PSLIST_ENTRY (WINAPI *pRtlInterlockedPushListSListEx)(PSLIST_HEADER list, PSLIST_ENTRY first,
|
||||
PSLIST_ENTRY last, ULONG count);
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
#include "pshpack1.h"
|
||||
struct fastcall_thunk
|
||||
{
|
||||
BYTE pop_edx; /* popl %edx (ret addr) */
|
||||
BYTE pop_eax; /* popl %eax (func) */
|
||||
BYTE pop_ecx; /* popl %ecx (param 1) */
|
||||
BYTE xchg[3]; /* xchgl (%esp),%edx (param 2) */
|
||||
WORD jmp_eax; /* jmp *%eax */
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
static void * (WINAPI *call_fastcall_func4)(void *func, const void *a, const void *b, const void *c, const void *d);
|
||||
|
||||
static void init_fastcall_thunk(void)
|
||||
{
|
||||
struct fastcall_thunk *thunk = VirtualAlloc(NULL, sizeof(*thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
thunk->pop_edx = 0x5a; /* popl %edx */
|
||||
thunk->pop_eax = 0x58; /* popl %eax */
|
||||
thunk->pop_ecx = 0x59; /* popl %ecx */
|
||||
thunk->xchg[0] = 0x87; /* xchgl (%esp),%edx */
|
||||
thunk->xchg[1] = 0x14;
|
||||
thunk->xchg[2] = 0x24;
|
||||
thunk->jmp_eax = 0xe0ff; /* jmp *%eax */
|
||||
call_fastcall_func4 = (void *)thunk;
|
||||
}
|
||||
|
||||
#define call_func4(func, a, b, c, d) call_fastcall_func4(func, (const void *)(a), \
|
||||
(const void *)(b), (const void *)(c), (const void *)(d))
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
#define init_fastcall_thunk() do { } while(0)
|
||||
#define call_func4(func, a, b, c, d) func(a, b, c, d)
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
static void test_signalandwait(void)
|
||||
{
|
||||
|
@ -276,6 +321,7 @@ static void test_slist(void)
|
|||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 0, "Expected size == 0, got %u\n", size);
|
||||
|
||||
/* test PushEntry, PopEntry and Flush */
|
||||
entry = InterlockedPushEntrySList(&slist_header, &item1.entry);
|
||||
ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
|
@ -313,6 +359,83 @@ static void test_slist(void)
|
|||
entry = InterlockedPopEntrySList(&slist_header);
|
||||
ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
|
||||
|
||||
/* test RtlInterlockedPushListSList */
|
||||
entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
|
||||
ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
|
||||
entry = call_func4(pRtlInterlockedPushListSList, &slist_header, &item2.entry, &item1.entry, 42);
|
||||
ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
|
||||
item = CONTAINING_RECORD(entry, struct item, entry);
|
||||
ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 43, "Expected size == 43, got %u\n", size);
|
||||
|
||||
entry = InterlockedPopEntrySList(&slist_header);
|
||||
ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
|
||||
item = CONTAINING_RECORD(entry, struct item, entry);
|
||||
ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 42, "Expected size == 42, got %u\n", size);
|
||||
|
||||
entry = InterlockedPopEntrySList(&slist_header);
|
||||
ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
|
||||
item = CONTAINING_RECORD(entry, struct item, entry);
|
||||
ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 41, "Expected size == 41, got %u\n", size);
|
||||
|
||||
entry = InterlockedPopEntrySList(&slist_header);
|
||||
ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
|
||||
item = CONTAINING_RECORD(entry, struct item, entry);
|
||||
ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 40, "Expected size == 40, got %u\n", size);
|
||||
|
||||
entry = InterlockedPopEntrySList(&slist_header);
|
||||
ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 40, "Expected size == 40, got %u\n", size);
|
||||
|
||||
entry = InterlockedFlushSList(&slist_header);
|
||||
ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 40 || broken(size == 0) /* >= Win 8 */, "Expected size == 40, got %u\n", size);
|
||||
|
||||
entry = InterlockedPushEntrySList(&slist_header, &item1.entry);
|
||||
ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
|
||||
entry = InterlockedFlushSList(&slist_header);
|
||||
ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
|
||||
item = CONTAINING_RECORD(entry, struct item, entry);
|
||||
ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 0, "Expected size == 0, got %u\n", size);
|
||||
|
||||
/* test RtlInterlockedPushListSListEx */
|
||||
if (pRtlInterlockedPushListSListEx)
|
||||
{
|
||||
entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
|
||||
ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
|
||||
entry = pRtlInterlockedPushListSListEx(&slist_header, &item2.entry, &item1.entry, 42);
|
||||
ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
|
||||
item = CONTAINING_RECORD(entry, struct item, entry);
|
||||
ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 43, "Expected size == 43, got %u\n", size);
|
||||
|
||||
entry = InterlockedFlushSList(&slist_header);
|
||||
ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
|
||||
item = CONTAINING_RECORD(entry, struct item, entry);
|
||||
ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
|
||||
item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
|
||||
ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
|
||||
item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
|
||||
ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
|
||||
size = QueryDepthSList(&slist_header);
|
||||
ok(size == 0, "Expected size == 0, got %u\n", size);
|
||||
}
|
||||
else
|
||||
win_skip("RtlInterlockedPushListSListEx not available, skipping tests\n");
|
||||
|
||||
/* test with a lot of items */
|
||||
for (i = 0; i < 65536; i++)
|
||||
{
|
||||
item = HeapAlloc(GetProcessHeap(), 0, sizeof(*item));
|
||||
|
@ -2561,6 +2684,8 @@ START_TEST(sync)
|
|||
pNtFreeVirtualMemory = (void *)GetProcAddress(hntdll, "NtFreeVirtualMemory");
|
||||
pNtWaitForSingleObject = (void *)GetProcAddress(hntdll, "NtWaitForSingleObject");
|
||||
pNtWaitForMultipleObjects = (void *)GetProcAddress(hntdll, "NtWaitForMultipleObjects");
|
||||
pRtlInterlockedPushListSList = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSList");
|
||||
pRtlInterlockedPushListSListEx = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSListEx");
|
||||
|
||||
argc = winetest_get_mainargs( &argv );
|
||||
if (argc >= 3)
|
||||
|
@ -2572,6 +2697,7 @@ START_TEST(sync)
|
|||
return;
|
||||
}
|
||||
|
||||
init_fastcall_thunk();
|
||||
test_signalandwait();
|
||||
test_mutex();
|
||||
test_slist();
|
||||
|
|
Loading…
Reference in New Issue