Sebastian Lackner : kernel32/tests: Add tests for RtlInterlockedPushListSList[Ex].

Alexandre Julliard julliard at wine.codeweavers.com
Tue Apr 12 06:45:24 CDT 2016


Module: wine
Branch: stable
Commit: bdfd2dfaa2c6644f025e4cfd2e534e4b221fbe2c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bdfd2dfaa2c6644f025e4cfd2e534e4b221fbe2c

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Thu Feb 11 03:53:49 2016 +0100

kernel32/tests: Add tests for RtlInterlockedPushListSList[Ex].

Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 32f72989b6bec7f79f434bffc2d4b10358b18a8c)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/kernel32/tests/sync.c | 126 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
index e2aa3a1..325e1ff 100644
--- a/dlls/kernel32/tests/sync.c
+++ b/dlls/kernel32/tests/sync.c
@@ -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();




More information about the wine-cvs mailing list