mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
[KMTESTS/EX]
- Add ExSequencedList test and restructure ExSingleList so they can share the test body svn path=/branches/GSoC_2011/KMTestSuite/; revision=53359
This commit is contained in:
@@ -22,6 +22,7 @@ list(APPEND KMTEST_DRV_SOURCE
|
||||
ntos_ex/ExInterlocked.c
|
||||
ntos_ex/ExPools.c
|
||||
ntos_ex/ExResource.c
|
||||
ntos_ex/ExSequencedList.c
|
||||
ntos_ex/ExSingleList.c
|
||||
ntos_ex/ExTimer.c
|
||||
ntos_fsrtl/FsRtlExpression.c
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<file>ExInterlocked.c</file>
|
||||
<file>ExPools.c</file>
|
||||
<file>ExResource.c</file>
|
||||
<file>ExSequencedList.c</file>
|
||||
<file>ExSingleList.c</file>
|
||||
<file>ExTimer.c</file>
|
||||
</directory>
|
||||
|
||||
@@ -15,6 +15,7 @@ KMT_TESTFUNC Test_ExHardErrorInteractive;
|
||||
KMT_TESTFUNC Test_ExInterlocked;
|
||||
KMT_TESTFUNC Test_ExPools;
|
||||
KMT_TESTFUNC Test_ExResource;
|
||||
KMT_TESTFUNC Test_ExSequencedList;
|
||||
KMT_TESTFUNC Test_ExSingleList;
|
||||
KMT_TESTFUNC Test_ExTimer;
|
||||
KMT_TESTFUNC Test_FsRtlExpression;
|
||||
@@ -43,6 +44,7 @@ const KMT_TEST TestList[] =
|
||||
{ "ExInterlocked", Test_ExInterlocked },
|
||||
{ "ExPools", Test_ExPools },
|
||||
{ "ExResource", Test_ExResource },
|
||||
{ "ExSequencedList", Test_ExSequencedList },
|
||||
{ "ExSingleList", Test_ExSingleList },
|
||||
{ "ExTimer", Test_ExTimer },
|
||||
{ "Example", Test_Example },
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test Suite sequenced singly-linked list test
|
||||
* PROGRAMMER: Thomas Faber <[email protected]>
|
||||
*/
|
||||
|
||||
struct _SINGLE_LIST_ENTRY;
|
||||
union _SLIST_HEADER;
|
||||
struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPushEntrySList(union _SLIST_HEADER *, struct _SINGLE_LIST_ENTRY *, unsigned long *);
|
||||
struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPopEntrySList(union _SLIST_HEADER *, unsigned long *);
|
||||
|
||||
#include <kmt_test.h>
|
||||
|
||||
/* TODO: SLIST_HEADER is a lot different for x64 */
|
||||
|
||||
#define CheckSListHeader(ListHead, ExpectedPointer, ExpectedDepth) do \
|
||||
{ \
|
||||
ok_eq_pointer((ListHead)->Next.Next, ExpectedPointer); \
|
||||
/*ok_eq_pointer(FirstEntrySList(ListHead), ExpectedPointer);*/ \
|
||||
ok_eq_uint((ListHead)->Depth, ExpectedDepth); \
|
||||
ok_eq_uint((ListHead)->Sequence, ExpectedSequence); \
|
||||
ok_eq_uint(ExQueryDepthSList(ListHead), ExpectedDepth); \
|
||||
ok_irql(HIGH_LEVEL); \
|
||||
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
|
||||
} while (0)
|
||||
|
||||
#define PXLIST_HEADER PSLIST_HEADER
|
||||
#define PXLIST_ENTRY PSLIST_ENTRY
|
||||
#define PushXList ExInterlockedPushEntrySList
|
||||
#define PopXList ExInterlockedPopEntrySList
|
||||
#define FlushXList ExInterlockedFlushSList
|
||||
#define ok_free_xlist ok_eq_pointer
|
||||
#define CheckXListHeader CheckSListHeader
|
||||
#define TestXListFunctional TestSListFunctional
|
||||
#include "ExXList.h"
|
||||
|
||||
#undef ExInterlockedPushEntrySList
|
||||
#undef ExInterlockedPopEntrySList
|
||||
#define TestXListFunctional TestSListFunctionalExports
|
||||
#include "ExXList.h"
|
||||
|
||||
START_TEST(ExSequencedList)
|
||||
{
|
||||
PSLIST_HEADER ListHead;
|
||||
KSPIN_LOCK SpinLock;
|
||||
USHORT ExpectedSequence = 0;
|
||||
PKSPIN_LOCK pSpinLock = &SpinLock;
|
||||
PCHAR Buffer;
|
||||
PSLIST_ENTRY Entries;
|
||||
SIZE_T EntriesSize = 5 * sizeof *Entries;
|
||||
KIRQL Irql;
|
||||
|
||||
KeInitializeSpinLock(&SpinLock);
|
||||
#ifdef _M_IX86
|
||||
pSpinLock = NULL;
|
||||
#endif
|
||||
|
||||
/* make sure stuff is as un-aligned as possible ;) */
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLqS');
|
||||
ListHead = (PVOID)&Buffer[1];
|
||||
Entries = (PVOID)&ListHead[1];
|
||||
KeRaiseIrql(HIGH_LEVEL, &Irql);
|
||||
|
||||
RtlFillMemory(Entries, EntriesSize, 0x55);
|
||||
RtlFillMemory(ListHead, sizeof *ListHead, 0x55);
|
||||
InitializeSListHead(ListHead);
|
||||
CheckSListHeader(ListHead, NULL, 0);
|
||||
TestSListFunctional(ListHead, Entries, pSpinLock);
|
||||
|
||||
RtlFillMemory(Entries, EntriesSize, 0x55);
|
||||
RtlFillMemory(ListHead, sizeof *ListHead, 0x55);
|
||||
ExInitializeSListHead(ListHead);
|
||||
CheckSListHeader(ListHead, NULL, 0);
|
||||
TestSListFunctionalExports(ListHead, Entries, pSpinLock);
|
||||
|
||||
KeLowerIrql(Irql);
|
||||
ExFreePoolWithTag(Buffer, 'TLqS');
|
||||
}
|
||||
@@ -11,8 +11,6 @@ struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPopEntryList(struct _SINGLE_LI
|
||||
|
||||
#include <kmt_test.h>
|
||||
|
||||
SINGLE_LIST_ENTRY Entries[5];
|
||||
|
||||
#define ok_eq_free2(Value, Expected) do \
|
||||
{ \
|
||||
if (KmtIsCheckedBuild) \
|
||||
@@ -21,107 +19,94 @@ SINGLE_LIST_ENTRY Entries[5];
|
||||
ok_eq_pointer(Value, Expected); \
|
||||
} while (0)
|
||||
|
||||
START_TEST(ExSingleList)
|
||||
PSINGLE_LIST_ENTRY FlushList(PSINGLE_LIST_ENTRY ListHead)
|
||||
{
|
||||
PSINGLE_LIST_ENTRY Ret = ListHead->Next;
|
||||
ListHead->Next = NULL;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
USHORT QueryDepthList(PSINGLE_LIST_ENTRY ListHead)
|
||||
{
|
||||
USHORT Depth = 0;
|
||||
while (ListHead->Next)
|
||||
{
|
||||
++Depth;
|
||||
ListHead = ListHead->Next;
|
||||
}
|
||||
return Depth;
|
||||
}
|
||||
|
||||
PSINGLE_LIST_ENTRY PushEntryListWrapper(PSINGLE_LIST_ENTRY ListHead, PSINGLE_LIST_ENTRY Entry, PKSPIN_LOCK Lock)
|
||||
{
|
||||
KSPIN_LOCK SpinLock;
|
||||
SINGLE_LIST_ENTRY ListHead;
|
||||
PSINGLE_LIST_ENTRY Ret;
|
||||
UNREFERENCED_PARAMETER(Lock);
|
||||
Ret = ListHead->Next;
|
||||
PushEntryList(ListHead, Entry);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
KeInitializeSpinLock(&SpinLock);
|
||||
#define CheckListHeader(ListHead, ExpectedPointer, ExpectedDepth) do \
|
||||
{ \
|
||||
ok_eq_pointer((ListHead)->Next, ExpectedPointer); \
|
||||
ok_eq_uint(QueryDepthList(ListHead), ExpectedDepth); \
|
||||
ok_irql(HIGH_LEVEL); \
|
||||
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
|
||||
} while (0)
|
||||
|
||||
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);
|
||||
#define PXLIST_HEADER PSINGLE_LIST_ENTRY
|
||||
#define PXLIST_ENTRY PSINGLE_LIST_ENTRY
|
||||
#define PushXList ExInterlockedPushEntryList
|
||||
#define PopXList ExInterlockedPopEntryList
|
||||
#define FlushXList FlushList
|
||||
#define ok_free_xlist ok_eq_free2
|
||||
#define CheckXListHeader CheckListHeader
|
||||
#define TestXListFunctional TestListFunctional
|
||||
#include "ExXList.h"
|
||||
|
||||
#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);
|
||||
#define TestXListFunctional TestListFunctionalExports
|
||||
#include "ExXList.h"
|
||||
|
||||
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);
|
||||
#undef PushXList
|
||||
#define PushXList PushEntryListWrapper
|
||||
#undef PopXList
|
||||
#define PopXList(h, s) PopEntryList(h)
|
||||
#undef ok_free_xlist
|
||||
#define ok_free_xlist ok_eq_pointer
|
||||
#define TestXListFunctional TestListFunctionalNoInterlocked
|
||||
#include "ExXList.h"
|
||||
|
||||
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);
|
||||
START_TEST(ExSingleList)
|
||||
{
|
||||
KSPIN_LOCK SpinLock;
|
||||
PSINGLE_LIST_ENTRY ListHead;
|
||||
PSINGLE_LIST_ENTRY Entries;
|
||||
SIZE_T EntriesSize = 5 * sizeof *Entries;
|
||||
PCHAR Buffer;
|
||||
KIRQL Irql;
|
||||
|
||||
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);
|
||||
KeInitializeSpinLock(&SpinLock);
|
||||
|
||||
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);
|
||||
/* make sure stuff is as un-aligned as possible ;) */
|
||||
Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLiS');
|
||||
ListHead = (PVOID)&Buffer[1];
|
||||
Entries = (PVOID)&ListHead[1];
|
||||
KeRaiseIrql(HIGH_LEVEL, &Irql);
|
||||
|
||||
RtlFillMemory(Entries, sizeof Entries, 0x55);
|
||||
ListHead->Next = NULL;
|
||||
TestListFunctional(ListHead, Entries, &SpinLock);
|
||||
|
||||
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);
|
||||
RtlFillMemory(Entries, sizeof Entries, 0x55);
|
||||
ListHead->Next = NULL;
|
||||
TestListFunctionalExports(ListHead, Entries, &SpinLock);
|
||||
|
||||
RtlFillMemory(Entries, sizeof Entries, 0x55);
|
||||
ListHead->Next = NULL;
|
||||
TestListFunctionalNoInterlocked(ListHead, Entries, &SpinLock);
|
||||
|
||||
KeLowerIrql(Irql);
|
||||
ExFreePoolWithTag(Buffer, 'TLiS');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/* used by ExSingleList and ExSequencedList tests */
|
||||
static
|
||||
VOID
|
||||
TestXListFunctional(
|
||||
IN PXLIST_HEADER ListHead,
|
||||
IN PXLIST_ENTRY Entries,
|
||||
IN PKSPIN_LOCK pSpinLock)
|
||||
{
|
||||
USHORT ExpectedSequence = 0;
|
||||
PXLIST_ENTRY Ret;
|
||||
|
||||
Ret = FlushXList(ListHead);
|
||||
ok_eq_pointer(Ret, NULL);
|
||||
CheckXListHeader(ListHead, NULL, 0);
|
||||
|
||||
Ret = PopXList(ListHead, pSpinLock);
|
||||
ok_eq_pointer(Ret, NULL);
|
||||
CheckXListHeader(ListHead, NULL, 0);
|
||||
|
||||
Ret = PushXList(ListHead, &Entries[0], pSpinLock);
|
||||
++ExpectedSequence;
|
||||
ok_eq_pointer(Ret, NULL);
|
||||
ok_eq_pointer(Entries[0].Next, NULL);
|
||||
CheckXListHeader(ListHead, &Entries[0], 1);
|
||||
|
||||
Ret = PushXList(ListHead, &Entries[1], pSpinLock);
|
||||
++ExpectedSequence;
|
||||
ok_eq_pointer(Ret, &Entries[0]);
|
||||
ok_eq_pointer(Entries[0].Next, NULL);
|
||||
ok_eq_pointer(Entries[1].Next, &Entries[0]);
|
||||
CheckXListHeader(ListHead, &Entries[1], 2);
|
||||
|
||||
Ret = PopXList(ListHead, pSpinLock);
|
||||
ok_eq_pointer(Ret, &Entries[1]);
|
||||
ok_eq_pointer(Entries[0].Next, NULL);
|
||||
ok_free_xlist(Entries[1].Next, &Entries[0]);
|
||||
CheckXListHeader(ListHead, &Entries[0], 1);
|
||||
|
||||
Ret = PopXList(ListHead, pSpinLock);
|
||||
ok_eq_pointer(Ret, &Entries[0]);
|
||||
ok_free_xlist(Entries[0].Next, NULL);
|
||||
ok_free_xlist(Entries[1].Next, &Entries[0]);
|
||||
CheckXListHeader(ListHead, NULL, 0);
|
||||
|
||||
Ret = PopXList(ListHead, pSpinLock);
|
||||
ok_eq_pointer(Ret, NULL);
|
||||
ok_free_xlist(Entries[0].Next, NULL);
|
||||
ok_free_xlist(Entries[1].Next, &Entries[0]);
|
||||
CheckXListHeader(ListHead, NULL, 0);
|
||||
|
||||
/* add entries again */
|
||||
Ret = PushXList(ListHead, &Entries[0], pSpinLock);
|
||||
++ExpectedSequence;
|
||||
ok_eq_pointer(Ret, NULL);
|
||||
ok_eq_pointer(Entries[0].Next, NULL);
|
||||
CheckXListHeader(ListHead, &Entries[0], 1);
|
||||
|
||||
Ret = PushXList(ListHead, &Entries[1], pSpinLock);
|
||||
++ExpectedSequence;
|
||||
ok_eq_pointer(Ret, &Entries[0]);
|
||||
ok_eq_pointer(Entries[0].Next, NULL);
|
||||
ok_eq_pointer(Entries[1].Next, &Entries[0]);
|
||||
CheckXListHeader(ListHead, &Entries[1], 2);
|
||||
|
||||
Ret = PopXList(ListHead, pSpinLock);
|
||||
ok_eq_pointer(Ret, &Entries[1]);
|
||||
ok_eq_pointer(Entries[0].Next, NULL);
|
||||
ok_free_xlist(Entries[1].Next, &Entries[0]);
|
||||
CheckXListHeader(ListHead, &Entries[0], 1);
|
||||
|
||||
Ret = PushXList(ListHead, &Entries[1], pSpinLock);
|
||||
++ExpectedSequence;
|
||||
ok_eq_pointer(Ret, &Entries[0]);
|
||||
ok_eq_pointer(Entries[0].Next, NULL);
|
||||
ok_eq_pointer(Entries[1].Next, &Entries[0]);
|
||||
CheckXListHeader(ListHead, &Entries[1], 2);
|
||||
|
||||
Ret = PushXList(ListHead, &Entries[2], pSpinLock);
|
||||
++ExpectedSequence;
|
||||
ok_eq_pointer(Ret, &Entries[1]);
|
||||
ok_eq_pointer(Entries[0].Next, NULL);
|
||||
ok_eq_pointer(Entries[1].Next, &Entries[0]);
|
||||
ok_eq_pointer(Entries[2].Next, &Entries[1]);
|
||||
CheckXListHeader(ListHead, &Entries[2], 3);
|
||||
|
||||
Ret = FlushXList(ListHead);
|
||||
ok_eq_pointer(Ret, &Entries[2]);
|
||||
CheckXListHeader(ListHead, NULL, 0);
|
||||
}
|
||||
|
||||
#undef TestXListFunctional
|
||||
Reference in New Issue
Block a user