ReactOS 0.4.16-dev-1946-g52006dd
ExResource.c File Reference
#include <kmt_test.h>
#include <debug.h>
Include dependency graph for ExResource.c:

Go to the source code of this file.

Classes

struct  THREAD_DATA
 

Macros

#define CheckResourceFields(Res, Reinit)
 
#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
 

Typedefs

typedef BOOLEAN(NTAPIPACQUIRE_FUNCTION) (PERESOURCE, BOOLEAN)
 
typedef struct THREAD_DATAPTHREAD_DATA
 

Functions

static _IRQL_requires_max_ (APC_LEVEL)
 
static VOID TestResourceSharedAccess (IN PERESOURCE Res)
 
static VOID TestResourceExclusiveAccess (IN PERESOURCE Res)
 
static VOID TestResourceUndocumentedShortcuts (IN PERESOURCE Res, IN BOOLEAN AreApcsDisabled)
 
static VOID NTAPI AcquireResourceThread (PVOID Context)
 
static VOID InitThreadDataEx (PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction, PKSTART_ROUTINE StartRoutine)
 
static VOID InitThreadData (PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction)
 
static NTSTATUS StartThread (PTHREAD_DATA ThreadData, PLARGE_INTEGER Timeout, BOOLEAN Wait, BOOLEAN RetExpected)
 
static VOID FinishThread (PTHREAD_DATA ThreadData)
 
static VOID TestResourceWithThreads (IN PERESOURCE Res)
 
static VOID NTAPI TestOwnerRes (PVOID Context)
 
static VOID TestResourceWithOwner (IN PERESOURCE Res)
 
 START_TEST (ExResource)
 

Variables

 ERESOURCE_2K3
 
PERESOURCE_2K3
 

Macro Definition Documentation

◆ CheckResourceFields

#define CheckResourceFields (   Res,
  Reinit 
)
Value:
do \
{ \
ok_eq_pointer((Res)->SystemResourcesList.Flink->Blink, &(Res)->SystemResourcesList); \
ok_eq_pointer((Res)->SystemResourcesList.Blink->Flink, &(Res)->SystemResourcesList); \
if (!Reinit) ok_eq_pointer((Res)->OwnerTable, NULL); \
ok_eq_int((Res)->ActiveCount, 0); \
ok_eq_uint((Res)->Flag, 0); \
if (!Reinit) ok_eq_pointer((Res)->SharedWaiters, NULL); \
if (!Reinit) ok_eq_pointer((Res)->ExclusiveWaiters, NULL); \
ok_eq_ulongptr((Res)->OwnerThreads[0].OwnerThread, 0); \
ok_eq_ulong((Res)->OwnerThreads[0].TableSize, 0LU); \
ok_eq_ulongptr((Res)->OwnerThreads[1].OwnerThread, 0); \
ok_eq_ulong((Res)->OwnerThreads[1].TableSize, 0LU); \
ok_eq_ulong((Res)->ContentionCount, 0LU); \
ok_eq_uint((Res)->NumberOfSharedWaiters, 0); \
ok_eq_uint((Res)->NumberOfExclusiveWaiters, 0); \
ok_eq_pointer((Res)->Address, NULL); \
ok_eq_ulongptr((Res)->SpinLock, 0); \
} while (0)
#define ok_eq_pointer(value, expected)
Definition: apitest.h:116
#define NULL
Definition: types.h:112
static WCHAR Address[46]
Definition: ping.c:68
Definition: xml2sdb.h:97
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
Definition: wdfsync.h:228
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:4330

Definition at line 78 of file ExResource.c.

◆ CheckResourceStatus

#define CheckResourceStatus (   Res,
  Exclusive,
  Shared,
  ExclusiveWaiters,
  SharedWaiters 
)
Value:
do \
{ \
if (Exclusive) \
ok_bool_true(ExIsResourceAcquiredExclusiveLite(Res), "ExIsResourceAcquiredExclusiveLite returned"); \
else \
ok_bool_false(ExIsResourceAcquiredExclusiveLite(Res), "ExIsResourceAcquiredExclusiveLite returned"); \
ok_eq_ulong(ExIsResourceAcquiredSharedLite(Res), Shared); \
ok_eq_ulong(ExGetExclusiveWaiterCount(Res), ExclusiveWaiters); \
ok_eq_ulong(ExGetSharedWaiterCount(Res), SharedWaiters); \
} while (0)
__in PWDFDEVICE_INIT __in BOOLEAN Exclusive
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1624
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1663
ULONG NTAPI ExGetSharedWaiterCount(IN PERESOURCE Resource)
Definition: resource.c:1563
ULONG NTAPI ExGetExclusiveWaiterCount(IN PERESOURCE Resource)
Definition: resource.c:1540

Definition at line 98 of file ExResource.c.

Typedef Documentation

◆ PACQUIRE_FUNCTION

typedef BOOLEAN(NTAPI * PACQUIRE_FUNCTION) (PERESOURCE, BOOLEAN)

Definition at line 271 of file ExResource.c.

◆ PTHREAD_DATA

Function Documentation

◆ _IRQL_requires_max_()

static _IRQL_requires_max_ ( APC_LEVEL  )
static

Definition at line 14 of file ExResource.c.

60 {
61 LIST_ENTRY SystemResourcesList;
62 POWNER_ENTRY OwnerTable;
63 SHORT ActiveCount;
65 volatile PKSEMAPHORE SharedWaiters;
66 volatile PKEVENT ExclusiveWaiters;
67 OWNER_ENTRY OwnerThreads[2];
68 ULONG ContentionCount;
69 USHORT NumberOfSharedWaiters;
70 USHORT NumberOfExclusiveWaiters;
71 _ANONYMOUS_UNION union {
73 ULONG_PTR CreatorBackTraceIndex;
ERESOURCE_2K3
Definition: ExResource.c:76
* PERESOURCE_2K3
Definition: ExResource.c:76
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define DUMMYUNIONNAME
Definition: pecoff.h:91
#define _ANONYMOUS_UNION
Definition: pecoff.h:89
short SHORT
Definition: pedump.c:59
unsigned short USHORT
Definition: pedump.c:61
Definition: typedefs.h:120
Definition: extypes.h:210
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59

◆ AcquireResourceThread()

static VOID NTAPI AcquireResourceThread ( PVOID  Context)
static

Definition at line 289 of file ExResource.c.

291{
294 BOOLEAN Ret;
295
297 Ret = ThreadData->AcquireResource(ThreadData->Res, ThreadData->Wait);
298 if (ThreadData->RetExpected)
299 ok_bool_true(Ret, "AcquireResource returned");
300 else
301 ok_bool_false(Ret, "AcquireResource returned");
302
303 ok_bool_false(KeSetEvent(&ThreadData->OutEvent, 0, TRUE), "KeSetEvent returned");
306
307 if (Ret)
310}
unsigned char BOOLEAN
#define ok_eq_hex(value, expected)
Definition: apitest.h:134
#define ok_bool_false(value, desc)
Definition: apitest.h:136
#define ok_bool_true(value, desc)
Definition: apitest.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
Status
Definition: gdiplustypes.h:25
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KernelMode
Definition: asm.h:38
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExReleaseResource(R)
Definition: exfuncs.h:257
@ Executive
Definition: ketypes.h:467

Referenced by InitThreadData().

◆ FinishThread()

static VOID FinishThread ( PTHREAD_DATA  ThreadData)
static

Definition at line 361 of file ExResource.c.

363{
365
366 KeSetEvent(&ThreadData->InEvent, 0, TRUE);
369
373 KeClearEvent(&ThreadData->InEvent);
374 KeClearEvent(&ThreadData->OutEvent);
375}
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
HANDLE Handle
Definition: drwtsn32.h:25
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by TestResourceWithOwner(), and TestResourceWithThreads().

◆ InitThreadData()

static VOID InitThreadData ( PTHREAD_DATA  ThreadData,
PERESOURCE  Res,
PACQUIRE_FUNCTION  AcquireFunction 
)
static

Definition at line 329 of file ExResource.c.

333{
334 InitThreadDataEx(ThreadData, Res, AcquireFunction, AcquireResourceThread);
335}
static VOID InitThreadDataEx(PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction, PKSTART_ROUTINE StartRoutine)
Definition: ExResource.c:314
static VOID NTAPI AcquireResourceThread(PVOID Context)
Definition: ExResource.c:289

Referenced by TestResourceWithThreads().

◆ InitThreadDataEx()

static VOID InitThreadDataEx ( PTHREAD_DATA  ThreadData,
PERESOURCE  Res,
PACQUIRE_FUNCTION  AcquireFunction,
PKSTART_ROUTINE  StartRoutine 
)
static

Definition at line 314 of file ExResource.c.

319{
320 ThreadData->Res = Res;
323 ThreadData->AcquireResource = AcquireFunction;
324 ThreadData->StartRoutine = StartRoutine;
325}
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
@ NotificationEvent
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:92

Referenced by InitThreadData(), and TestResourceWithOwner().

◆ START_TEST()

START_TEST ( ExResource  )

Definition at line 545 of file ExResource.c.

546{
548 ERESOURCE Res;
549 KIRQL Irql;
550
551 pExEnterCriticalRegionAndAcquireResourceShared = KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireResourceShared");
552 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive = KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireSharedWaitForExclusive");
553 pExEnterCriticalRegionAndAcquireResourceExclusive = KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireResourceExclusive");
554 pExReleaseResourceAndLeaveCriticalRegion = KmtGetSystemRoutineAddress(L"ExReleaseResourceAndLeaveCriticalRegion");
555 pKeAreAllApcsDisabled = KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
556
557 if (skip(pKeAreAllApcsDisabled != NULL, "KeAreAllApcsDisabled unavailable\n"))
558 {
559 /* We can live without this function here */
560 }
561
562 /* this must be true even with the different structure versions */
563 ASSERT(sizeof(ERESOURCE) == sizeof(ERESOURCE_2K3));
564
565 /* functional tests & internals */
570
574
575 memset(&Res, 0x55, sizeof Res);
579
580 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
581
583 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
584
586 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
587
589 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
594 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
595
596 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
597
599
600 /* ExReinitializeResourceLite cleans up after us */
604 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
605
607 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
608
611
612 /* parameter checks */
614 _SEH2_TRY {
618 } _SEH2_END;
620
621 /* these bugcheck
622 ExDeleteResourceLite(NULL);
623 Status = ExDeleteResourceLite(&Res);*/
624}
static VOID TestResourceWithThreads(IN PERESOURCE Res)
Definition: ExResource.c:379
static VOID TestResourceExclusiveAccess(IN PERESOURCE Res)
Definition: ExResource.c:144
static VOID TestResourceSharedAccess(IN PERESOURCE Res)
Definition: ExResource.c:111
#define CheckResourceFields(Res, Reinit)
Definition: ExResource.c:78
static VOID TestResourceUndocumentedShortcuts(IN PERESOURCE Res, IN BOOLEAN AreApcsDisabled)
Definition: ExResource.c:175
static VOID TestResourceWithOwner(IN PERESOURCE Res)
Definition: ExResource.c:522
#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
Definition: ExResource.c:98
#define GetNTVersion()
Definition: apitest.h:17
#define skip(...)
Definition: atltest.h:64
_Out_ PKIRQL Irql
Definition: csq.h:179
#define L(x)
Definition: resources.c:13
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
ULONG ERESOURCE
Definition: env_spec_w32.h:594
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:68
#define STATUS_ACCESS_VIOLATION
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS NTAPI ExReinitializeResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1761
BOOLEAN NTAPI KeAreApcsDisabled(VOID)
Definition: apc.c:958
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define memset(x, y, z)
Definition: compat.h:39
#define _WIN32_WINNT_WIN8
Definition: sdkddkver.h:29

◆ StartThread()

static NTSTATUS StartThread ( PTHREAD_DATA  ThreadData,
PLARGE_INTEGER  Timeout,
BOOLEAN  Wait,
BOOLEAN  RetExpected 
)
static

Definition at line 339 of file ExResource.c.

344{
347
348 ThreadData->Wait = Wait;
349 ThreadData->RetExpected = RetExpected;
355
357}
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define SYNCHRONIZE
Definition: nt_native.h:61
#define GENERIC_ALL
Definition: nt_native.h:92
POBJECT_TYPE PsThreadType
Definition: thread.c:20
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
static ULONG Timeout
Definition: ping.c:61
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

Referenced by TestResourceWithOwner(), and TestResourceWithThreads().

◆ TestOwnerRes()

static VOID NTAPI TestOwnerRes ( PVOID  Context)
static

Definition at line 498 of file ExResource.c.

500{
503 BOOLEAN Ret;
504
506 Ret = ThreadData->AcquireResource(ThreadData->Res, ThreadData->Wait);
507 if (ThreadData->RetExpected)
508 ok_bool_true(Ret, "AcquireResource returned");
509 else
510 ok_bool_false(Ret, "AcquireResource returned");
512
514
515 ok_bool_false(KeSetEvent(&ThreadData->OutEvent, 0, TRUE), "KeSetEvent returned");
518}
#define ExReleaseResourceForThreadLite(res, thrdID)
Definition: env_spec_w32.h:635

Referenced by TestResourceWithOwner().

◆ TestResourceExclusiveAccess()

static VOID TestResourceExclusiveAccess ( IN PERESOURCE  Res)
static

Definition at line 144 of file ExResource.c.

146{
147 LONG Count = 0;
148
150 ok_bool_true(ExAcquireResourceExclusiveLite(Res, FALSE), "ExAcquireResourceExclusiveLite returned"); ++Count;
151
152 CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
153
154 ok_bool_true(ExAcquireResourceExclusiveLite(Res, TRUE), "ExAcquireResourceExclusiveLite returned"); ++Count;
155 CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
156
157 ok_bool_true(ExAcquireResourceSharedLite(Res, FALSE), "ExAcquireResourceSharedLite returned"); ++Count;
158 ok_bool_true(ExAcquireResourceSharedLite(Res, TRUE), "ExAcquireResourceSharedLite returned"); ++Count;
159 ok_bool_true(ExAcquireSharedStarveExclusive(Res, FALSE), "ExAcquireSharedStarveExclusive returned"); ++Count;
160 ok_bool_true(ExAcquireSharedStarveExclusive(Res, TRUE), "ExAcquireSharedStarveExclusive returned"); ++Count;
161 ok_bool_true(ExAcquireSharedWaitForExclusive(Res, FALSE), "ExAcquireSharedWaitForExclusive returned"); ++Count;
162 ok_bool_true(ExAcquireSharedWaitForExclusive(Res, TRUE), "ExAcquireSharedWaitForExclusive returned"); ++Count;
163 CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
164
166 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
167
168 while (Count--)
171}
#define ExConvertExclusiveToSharedLite(res)
Definition: env_spec_w32.h:652
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
int Count
Definition: noreturn.cpp:7
BOOLEAN NTAPI ExAcquireSharedWaitForExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1222
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1068
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
long LONG
Definition: pedump.c:60

Referenced by START_TEST().

◆ TestResourceSharedAccess()

static VOID TestResourceSharedAccess ( IN PERESOURCE  Res)
static

Definition at line 111 of file ExResource.c.

113{
114 LONG Count = 0;
115
117 ok_bool_true(ExAcquireResourceSharedLite(Res, FALSE), "ExAcquireResourceSharedLite returned"); ++Count;
118 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
119
120 ok_bool_true(ExAcquireResourceSharedLite(Res, FALSE), "ExAcquireResourceSharedLite returned"); ++Count;
121 ok_bool_true(ExAcquireResourceSharedLite(Res, TRUE), "ExAcquireResourceSharedLite returned"); ++Count;
122 ok_bool_true(ExAcquireSharedStarveExclusive(Res, FALSE), "ExAcquireSharedStarveExclusive returned"); ++Count;
123 ok_bool_true(ExAcquireSharedStarveExclusive(Res, TRUE), "ExAcquireSharedStarveExclusive returned"); ++Count;
124 ok_bool_true(ExAcquireSharedWaitForExclusive(Res, FALSE), "ExAcquireSharedWaitForExclusive returned"); ++Count;
125 ok_bool_true(ExAcquireSharedWaitForExclusive(Res, TRUE), "ExAcquireSharedWaitForExclusive returned"); ++Count;
126 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
127
128 /* this one fails, TRUE would deadlock */
129 ok_bool_false(ExAcquireResourceExclusiveLite(Res, FALSE), "ExAcquireResourceExclusiveLite returned");
130 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
131
132 /* this asserts */
135 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
136
137 while (Count--)
140}
BOOLEAN KmtIsCheckedBuild

Referenced by START_TEST().

◆ TestResourceUndocumentedShortcuts()

static VOID TestResourceUndocumentedShortcuts ( IN PERESOURCE  Res,
IN BOOLEAN  AreApcsDisabled 
)
static

Definition at line 175 of file ExResource.c.

178{
179 PVOID Ret;
180 LONG Count = 0;
181
183 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
184
185 if (pKeAreAllApcsDisabled)
186 ok_eq_uint(pKeAreAllApcsDisabled(), AreApcsDisabled);
187
188 if (skip(pExEnterCriticalRegionAndAcquireResourceShared &&
189 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive &&
190 pExEnterCriticalRegionAndAcquireResourceExclusive &&
191 pExReleaseResourceAndLeaveCriticalRegion, "No shortcuts\n"))
192 {
193 return;
194 }
195 /* ExEnterCriticalRegionAndAcquireResourceShared, ExEnterCriticalRegionAndAcquireSharedWaitForExclusive */
196 Count = 0;
197 Ret = pExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
199 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
200 if (pKeAreAllApcsDisabled)
201 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
202 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
203
204 Ret = pExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
206 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
207 if (pKeAreAllApcsDisabled)
208 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
209 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
210
211 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive(Res); ++Count;
213 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
214 if (pKeAreAllApcsDisabled)
215 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
216 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
217
218 while (Count-- > 1)
219 {
220 pExReleaseResourceAndLeaveCriticalRegion(Res);
221 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
222 if (pKeAreAllApcsDisabled)
223 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
224 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
225 }
226
227 pExReleaseResourceAndLeaveCriticalRegion(Res);
229 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
230
231 if (pKeAreAllApcsDisabled)
232 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
233 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
234
235 /* ExEnterCriticalRegionAndAcquireResourceExclusive */
236 Count = 0;
238 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
239
240 if (pKeAreAllApcsDisabled)
241 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
242 Ret = pExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
244 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
245 if (pKeAreAllApcsDisabled)
246 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
247 CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
248
249 Ret = pExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
251 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
252 if (pKeAreAllApcsDisabled)
253 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
254 CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
255
256 pExReleaseResourceAndLeaveCriticalRegion(Res); --Count;
257 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
258 if (pKeAreAllApcsDisabled)
259 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
260 CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
261
262 pExReleaseResourceAndLeaveCriticalRegion(Res); --Count;
264 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
265
266 if (pKeAreAllApcsDisabled)
267 ok_eq_uint(pKeAreAllApcsDisabled(), AreApcsDisabled);
268 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
269}
#define ok_eq_uint(value, expected)
Definition: apitest.h:118
#define ok_eq_bool(value, expected)
Definition: apitest.h:137
#define KeGetCurrentThread
Definition: hal.h:55
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23

Referenced by START_TEST().

◆ TestResourceWithOwner()

static VOID TestResourceWithOwner ( IN PERESOURCE  Res)
static

Definition at line 522 of file ExResource.c.

524{
526 THREAD_DATA ThreadDataOwner;
527
529
531 ok_bool_true(ExAcquireResourceExclusiveLite(Res, FALSE), "ExAcquireResourceExclusiveLite returned");
534
535 ok_bool_true(ExAcquireResourceExclusiveLite(Res, FALSE), "ExAcquireResourceExclusiveLite returned");
536 ExSetResourceOwnerPointer(Res, (PVOID)((ULONG_PTR)Res | 3));
538
539 Status = StartThread(&ThreadDataOwner, NULL, FALSE, FALSE);
541
542 FinishThread(&ThreadDataOwner);
543}
static VOID FinishThread(PTHREAD_DATA ThreadData)
Definition: ExResource.c:361
static VOID NTAPI TestOwnerRes(PVOID Context)
Definition: ExResource.c:498
static NTSTATUS StartThread(PTHREAD_DATA ThreadData, PLARGE_INTEGER Timeout, BOOLEAN Wait, BOOLEAN RetExpected)
Definition: ExResource.c:339
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
Definition: resource.c:2050

Referenced by START_TEST().

◆ TestResourceWithThreads()

static VOID TestResourceWithThreads ( IN PERESOURCE  Res)
static

Definition at line 379 of file ExResource.c.

381{
383 THREAD_DATA ThreadDataShared;
384 THREAD_DATA ThreadDataShared2;
385 THREAD_DATA ThreadDataExclusive;
386 THREAD_DATA ThreadDataSharedStarve;
387 THREAD_DATA ThreadDataSharedWait;
389 Timeout.QuadPart = -10 * 1000 * 10; /* 10 ms */
390
391 InitThreadData(&ThreadDataShared, Res, ExAcquireResourceSharedLite);
392 InitThreadData(&ThreadDataShared2, Res, ExAcquireResourceSharedLite);
393 InitThreadData(&ThreadDataExclusive, Res, ExAcquireResourceExclusiveLite);
394 InitThreadData(&ThreadDataSharedStarve, Res, ExAcquireSharedStarveExclusive);
395 InitThreadData(&ThreadDataSharedWait, Res, ExAcquireSharedWaitForExclusive);
396
397 /* have a thread acquire the resource shared */
398 Status = StartThread(&ThreadDataShared, NULL, FALSE, TRUE);
400 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
401 ok_eq_int(Res->ActiveCount, 1);
402
403 /* a second thread should be able to acquire the resource shared */
404 Status = StartThread(&ThreadDataShared2, NULL, FALSE, TRUE);
406 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
408 {
409 ok_eq_int(Res->ActiveCount, 2);
410 }
411 else
412 {
413 ok_eq_int(Res->ActiveCount, 1);
414 ok_eq_int(Res->ActiveEntries, 2);
415 }
416 FinishThread(&ThreadDataShared2);
417 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
418 ok_eq_int(Res->ActiveCount, 1);
419
420 /* now have a thread that tries to acquire the resource exclusive -- it should fail */
421 Status = StartThread(&ThreadDataExclusive, NULL, FALSE, FALSE);
423 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
424 ok_eq_int(Res->ActiveCount, 1);
425 FinishThread(&ThreadDataExclusive);
426 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
427 ok_eq_int(Res->ActiveCount, 1);
428
429 /* as above, but this time it should block */
430 Status = StartThread(&ThreadDataExclusive, &Timeout, TRUE, TRUE);
432 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
433 ok_eq_int(Res->ActiveCount, 1);
434
435 /* now try another shared one -- it should fail */
436 Status = StartThread(&ThreadDataShared2, NULL, FALSE, FALSE);
438 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
439 ok_eq_int(Res->ActiveCount, 1);
440 FinishThread(&ThreadDataShared2);
441
442 /* same for ExAcquireSharedWaitForExclusive */
443 Status = StartThread(&ThreadDataSharedWait, NULL, FALSE, FALSE);
445 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
446 ok_eq_int(Res->ActiveCount, 1);
447 FinishThread(&ThreadDataSharedWait);
448
449 /* ExAcquireSharedStarveExclusive must get access though! */
450 Status = StartThread(&ThreadDataSharedStarve, NULL, TRUE, TRUE);
452 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
454 {
455 ok_eq_int(Res->ActiveCount, 2);
456 }
457 else
458 {
459 ok_eq_int(Res->ActiveCount, 1);
460 ok_eq_int(Res->ActiveEntries, 2);
461 }
462 FinishThread(&ThreadDataSharedStarve);
463 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
464 ok_eq_int(Res->ActiveCount, 1);
465
466 /* block another shared one */
467 Status = StartThread(&ThreadDataShared2, &Timeout, TRUE, TRUE);
469 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 1LU);
470 ok_eq_int(Res->ActiveCount, 1);
471
472 /* finish the very first one */
473 FinishThread(&ThreadDataShared);
474
475 /* now the blocked exclusive one should get the resource */
478 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 1LU);
479 ok_eq_int(Res->ActiveCount, 1);
480 ok_eq_uint((Res->Flag & ResourceOwnedExclusive) != 0, 1);
481
482 FinishThread(&ThreadDataExclusive);
483 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
484
485 /* now the blocked shared one should resume */
488 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
489 ok_eq_int(Res->ActiveCount, 1);
490 FinishThread(&ThreadDataShared2);
491 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
492 ok_eq_int(Res->ActiveCount, 0);
493}
static VOID InitThreadData(PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction)
Definition: ExResource.c:329
#define ok_eq_int(value, expected)
Definition: apitest.h:117
#define U(x)
Definition: wordpad.c:45
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define ResourceOwnedExclusive
Definition: dldetect.h:32
KEVENT OutEvent
Definition: ExFastMutex.c:152

Referenced by START_TEST().

Variable Documentation

◆ ERESOURCE_2K3

ERESOURCE_2K3

Definition at line 76 of file ExResource.c.

Referenced by START_TEST().

◆ PERESOURCE_2K3

* PERESOURCE_2K3

Definition at line 76 of file ExResource.c.

Referenced by START_TEST().