[KMTESTS/EX]
authorThomas Faber <thomas.faber@reactos.org>
Mon, 25 Jul 2011 20:12:44 +0000 (20:12 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Mon, 25 Jul 2011 20:12:44 +0000 (20:12 +0000)
- add quick'n'dirty tests for interlocked single/double list functions

svn path=/branches/GSoC_2011/KMTestSuite/; revision=52870

kmtests/CMakeLists.txt
kmtests/kmtest_drv.rbuild
kmtests/kmtest_drv/testlist.c
kmtests/ntos_ex/ExDoubleList.c [new file with mode: 0644]
kmtests/ntos_ex/ExSingleList.c [new file with mode: 0644]

index b32e0da..00f2fe3 100644 (file)
@@ -15,10 +15,12 @@ list(APPEND KMTEST_DRV_SOURCE
 
     example/Example.c
     example/KernelType.c
+    ntos_ex/ExDoubleList.c
     ntos_ex/ExHardError.c
     ntos_ex/ExInterlocked.c
     ntos_ex/ExPools.c
     ntos_ex/ExResource.c
+    ntos_ex/ExSingleList.c
     ntos_ex/ExTimer.c
     ntos_fsrtl/FsRtlExpression.c
     ntos_io/IoDeviceInterface.c
index ad76a2d..7cb01ca 100644 (file)
                <file>KernelType.c</file>
        </directory>
        <directory name="ntos_ex">
+               <file>ExDoubleList.c</file>
                <file>ExHardError.c</file>
                <file>ExInterlocked.c</file>
                <file>ExPools.c</file>
                <file>ExResource.c</file>
+               <file>ExSingleList.c</file>
                <file>ExTimer.c</file>
        </directory>
        <directory name="ntos_fsrtl">
index 3e90a7e..65e6a61 100644 (file)
@@ -9,11 +9,13 @@
 #include <kmt_test.h>
 
 KMT_TESTFUNC Test_Example;
+KMT_TESTFUNC Test_ExDoubleList;
 KMT_TESTFUNC Test_ExHardError;
 KMT_TESTFUNC Test_ExHardErrorInteractive;
 KMT_TESTFUNC Test_ExInterlocked;
 KMT_TESTFUNC Test_ExPools;
 KMT_TESTFUNC Test_ExResource;
+KMT_TESTFUNC Test_ExSingleList;
 KMT_TESTFUNC Test_ExTimer;
 KMT_TESTFUNC Test_FsRtlExpression;
 KMT_TESTFUNC Test_IoDeviceInterface;
@@ -28,11 +30,13 @@ KMT_TESTFUNC Test_ObCreate;
 
 const KMT_TEST TestList[] =
 {
+    { "ExDoubleList",                       Test_ExDoubleList },
     { "ExHardError",                        Test_ExHardError },
     { "-ExHardErrorInteractive",            Test_ExHardErrorInteractive },
     { "ExInterlocked",                      Test_ExInterlocked },
     { "ExPools",                            Test_ExPools },
     { "ExResource",                         Test_ExResource },
+    { "ExSingleList",                       Test_ExSingleList },
     { "ExTimer",                            Test_ExTimer },
     { "Example",                            Test_Example },
     { "FsRtlExpression",                    Test_FsRtlExpression },
diff --git a/kmtests/ntos_ex/ExDoubleList.c b/kmtests/ntos_ex/ExDoubleList.c
new file mode 100644 (file)
index 0000000..f582257
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite Doubly-linked list test
+ * PROGRAMMER:      Thomas Faber <thfabba@gmx.de>
+ */
+
+struct _LIST_ENTRY;
+struct _LIST_ENTRY *__stdcall ExInterlockedInsertHeadList(struct _LIST_ENTRY *, struct _LIST_ENTRY *, unsigned long *);
+struct _LIST_ENTRY *__stdcall ExInterlockedInsertTailList(struct _LIST_ENTRY *, struct _LIST_ENTRY *, unsigned long *);
+struct _LIST_ENTRY *__stdcall ExInterlockedRemoveHeadList(struct _LIST_ENTRY *, unsigned long *);
+
+#include <ntddk.h>
+#include <kmt_test.h>
+
+LIST_ENTRY Entries[5];
+
+#define ok_eq_free(Value, Expected) do              \
+{                                                   \
+    if (KmtIsCheckedBuild)                          \
+        ok_eq_pointer(Value, (PVOID)0x0BADD0FF);    \
+    else                                            \
+        ok_eq_pointer(Value, Expected);             \
+} while (0)
+
+#define ok_eq_free2(Value, Expected) do              \
+{                                                   \
+    if (KmtIsCheckedBuild)                          \
+        ok_eq_pointer(Value, (PVOID)0xBADDD0FF);    \
+    else                                            \
+        ok_eq_pointer(Value, Expected);             \
+} while (0)
+
+START_TEST(ExDoubleList)
+{
+    KSPIN_LOCK SpinLock;
+    LIST_ENTRY ListHead;
+    PLIST_ENTRY Ret;
+    
+    KeInitializeSpinLock(&SpinLock);
+    
+    memset(&ListHead, 0x55, sizeof ListHead);
+    InitializeListHead(&ListHead);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &Entries[0]);
+    ok_eq_pointer(ListHead.Blink, &Entries[0]);
+    ok_eq_pointer(Entries[0].Flink, &ListHead);
+    ok_eq_pointer(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_eq_free(Entries[0].Flink, &ListHead);
+    ok_eq_free(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_eq_free(Entries[0].Flink, &ListHead);
+    ok_eq_free(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &Entries[0]);
+    ok_eq_pointer(ListHead.Blink, &Entries[0]);
+    ok_eq_pointer(Entries[0].Flink, &ListHead);
+    ok_eq_pointer(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_eq_free(Entries[0].Flink, &ListHead);
+    ok_eq_free(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_eq_free(Entries[0].Flink, &ListHead);
+    ok_eq_free(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &Entries[0]);
+    ok_eq_pointer(ListHead.Blink, &Entries[0]);
+    ok_eq_pointer(Entries[0].Flink, &ListHead);
+    ok_eq_pointer(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[1], &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Flink, &Entries[1]);
+    ok_eq_pointer(ListHead.Blink, &Entries[0]);
+    ok_eq_pointer(Entries[0].Flink, &ListHead);
+    ok_eq_pointer(Entries[0].Blink, &Entries[1]);
+    ok_eq_pointer(Entries[1].Flink, &Entries[0]);
+    ok_eq_pointer(Entries[1].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    memset(Entries, 0x55, sizeof Entries);
+#undef ExInterlockedInsertHeadList
+#undef ExInterlockedInsertTailList
+#undef ExInterlockedRemoveHeadList
+
+    memset(&ListHead, 0x55, sizeof ListHead);
+    InitializeListHead(&ListHead);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &Entries[0]);
+    ok_eq_pointer(ListHead.Blink, &Entries[0]);
+    ok_eq_pointer(Entries[0].Flink, &ListHead);
+    ok_eq_pointer(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_eq_free2(Entries[0].Flink, &ListHead);
+    ok_eq_free2(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_eq_free2(Entries[0].Flink, &ListHead);
+    ok_eq_free2(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &Entries[0]);
+    ok_eq_pointer(ListHead.Blink, &Entries[0]);
+    ok_eq_pointer(Entries[0].Flink, &ListHead);
+    ok_eq_pointer(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_eq_free2(Entries[0].Flink, &ListHead);
+    ok_eq_free2(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &ListHead);
+    ok_eq_pointer(ListHead.Blink, &ListHead);
+    ok_eq_free2(Entries[0].Flink, &ListHead);
+    ok_eq_free2(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Flink, &Entries[0]);
+    ok_eq_pointer(ListHead.Blink, &Entries[0]);
+    ok_eq_pointer(Entries[0].Flink, &ListHead);
+    ok_eq_pointer(Entries[0].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[1], &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Flink, &Entries[1]);
+    ok_eq_pointer(ListHead.Blink, &Entries[0]);
+    ok_eq_pointer(Entries[0].Flink, &ListHead);
+    ok_eq_pointer(Entries[0].Blink, &Entries[1]);
+    ok_eq_pointer(Entries[1].Flink, &Entries[0]);
+    ok_eq_pointer(Entries[1].Blink, &ListHead);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+    
+    KmtSetIrql(PASSIVE_LEVEL);
+}
diff --git a/kmtests/ntos_ex/ExSingleList.c b/kmtests/ntos_ex/ExSingleList.c
new file mode 100644 (file)
index 0000000..b4b4b3e
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite Singly-linked list test
+ * PROGRAMMER:      Thomas Faber <thfabba@gmx.de>
+ */
+
+struct _SINGLE_LIST_ENTRY;
+struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPushEntryList(struct _SINGLE_LIST_ENTRY *, struct _SINGLE_LIST_ENTRY *, unsigned long *);
+struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPopEntryList(struct _SINGLE_LIST_ENTRY *, unsigned long *);
+
+#include <ntddk.h>
+#include <kmt_test.h>
+
+SINGLE_LIST_ENTRY Entries[5];
+
+#define ok_eq_free2(Value, Expected) do              \
+{                                                   \
+    if (KmtIsCheckedBuild)                          \
+        ok_eq_pointer(Value, (PVOID)0xBADDD0FF);    \
+    else                                            \
+        ok_eq_pointer(Value, Expected);             \
+} while (0)
+
+START_TEST(ExSingleList)
+{
+    KSPIN_LOCK SpinLock;
+    SINGLE_LIST_ENTRY ListHead;
+    PSINGLE_LIST_ENTRY Ret;
+
+    KeInitializeSpinLock(&SpinLock);
+
+    memset(Entries, 0x55, sizeof Entries);
+    ListHead.Next = NULL;
+    Ret = ExInterlockedPushEntryList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Next, &Entries[0]);
+    ok_eq_pointer(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Next, NULL);
+    ok_eq_free2(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Next, NULL);
+    ok_eq_free2(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPushEntryList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Next, &Entries[0]);
+    ok_eq_pointer(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPushEntryList(&ListHead, &Entries[1], &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Next, &Entries[1]);
+    ok_eq_pointer(Entries[1].Next, &Entries[0]);
+    ok_eq_pointer(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, &Entries[1]);
+    ok_eq_pointer(ListHead.Next, &Entries[0]);
+    ok_eq_free2(Entries[1].Next, &Entries[0]);
+    ok_eq_pointer(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+#undef ExInterlockedPushEntryList
+#undef ExInterlockedPopEntryList
+    memset(Entries, 0x55, sizeof Entries);
+    ListHead.Next = NULL;
+    Ret = ExInterlockedPushEntryList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Next, &Entries[0]);
+    ok_eq_pointer(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Next, NULL);
+    ok_eq_free2(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Next, NULL);
+    ok_eq_free2(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPushEntryList(&ListHead, &Entries[0], &SpinLock);
+    ok_eq_pointer(Ret, NULL);
+    ok_eq_pointer(ListHead.Next, &Entries[0]);
+    ok_eq_pointer(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPushEntryList(&ListHead, &Entries[1], &SpinLock);
+    ok_eq_pointer(Ret, &Entries[0]);
+    ok_eq_pointer(ListHead.Next, &Entries[1]);
+    ok_eq_pointer(Entries[1].Next, &Entries[0]);
+    ok_eq_pointer(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
+    ok_eq_pointer(Ret, &Entries[1]);
+    ok_eq_pointer(ListHead.Next, &Entries[0]);
+    ok_eq_free2(Entries[1].Next, &Entries[0]);
+    ok_eq_pointer(Entries[0].Next, NULL);
+    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
+    ok_irql(PASSIVE_LEVEL);
+
+    KmtSetIrql(PASSIVE_LEVEL);
+}