ReactOS 0.4.15-dev-7953-g1f49173
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:59
#define NULL
Definition: types.h:112
static WCHAR Address[46]
Definition: ping.c:68
Definition: xml2sdb.h:80
_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:4327

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 263 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: ntbasedef.h:32
#define _ANONYMOUS_UNION
Definition: ntbasedef.h:30
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 281 of file ExResource.c.

283{
286 BOOLEAN Ret;
287
289 Ret = ThreadData->AcquireResource(ThreadData->Res, ThreadData->Wait);
290 if (ThreadData->RetExpected)
291 ok_bool_true(Ret, "AcquireResource returned");
292 else
293 ok_bool_false(Ret, "AcquireResource returned");
294
295 ok_bool_false(KeSetEvent(&ThreadData->OutEvent, 0, TRUE), "KeSetEvent returned");
298
299 if (Ret)
302}
unsigned char BOOLEAN
#define ok_eq_hex(value, expected)
Definition: apitest.h:77
#define ok_bool_false(value, desc)
Definition: apitest.h:79
#define ok_bool_true(value, desc)
Definition: apitest.h:78
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:34
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExReleaseResource(R)
Definition: exfuncs.h:257
@ Executive
Definition: ketypes.h:415

Referenced by InitThreadData().

◆ FinishThread()

static VOID FinishThread ( PTHREAD_DATA  ThreadData)
static

Definition at line 353 of file ExResource.c.

355{
357
358 KeSetEvent(&ThreadData->InEvent, 0, TRUE);
361
365 KeClearEvent(&ThreadData->InEvent);
366 KeClearEvent(&ThreadData->OutEvent);
367}
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 321 of file ExResource.c.

325{
326 InitThreadDataEx(ThreadData, Res, AcquireFunction, AcquireResourceThread);
327}
static VOID InitThreadDataEx(PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction, PKSTART_ROUTINE StartRoutine)
Definition: ExResource.c:306
static VOID NTAPI AcquireResourceThread(PVOID Context)
Definition: ExResource.c:281

Referenced by TestResourceWithThreads().

◆ InitThreadDataEx()

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

Definition at line 306 of file ExResource.c.

311{
312 ThreadData->Res = Res;
315 ThreadData->AcquireResource = AcquireFunction;
316 ThreadData->StartRoutine = StartRoutine;
317}
#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:91

Referenced by InitThreadData(), and TestResourceWithOwner().

◆ START_TEST()

START_TEST ( ExResource  )

Definition at line 521 of file ExResource.c.

522{
524 ERESOURCE Res;
525 KIRQL Irql;
526
527 pExEnterCriticalRegionAndAcquireResourceShared = KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireResourceShared");
528 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive = KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireSharedWaitForExclusive");
529 pExEnterCriticalRegionAndAcquireResourceExclusive = KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireResourceExclusive");
530 pExReleaseResourceAndLeaveCriticalRegion = KmtGetSystemRoutineAddress(L"ExReleaseResourceAndLeaveCriticalRegion");
531 pKeAreAllApcsDisabled = KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
532
533 if (skip(pKeAreAllApcsDisabled != NULL, "KeAreAllApcsDisabled unavailable\n"))
534 {
535 /* We can live without this function here */
536 }
537
538 /* this must be true even with the different structure versions */
539 ASSERT(sizeof(ERESOURCE) == sizeof(ERESOURCE_2K3));
540
541 /* functional tests & internals */
546
550
551 memset(&Res, 0x55, sizeof Res);
555
556 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
557
559 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
560
562 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
563
565 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
569 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
570 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
571
573
574 /* ExReinitializeResourceLite cleans up after us */
578 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
579
581 CheckResourceStatus(&Res, FALSE, 0LU, 0LU, 0LU);
582
585
586 /* parameter checks */
588 _SEH2_TRY {
592 } _SEH2_END;
594
595 /* these bugcheck
596 ExDeleteResourceLite(NULL);
597 Status = ExDeleteResourceLite(&Res);*/
598}
static VOID TestResourceWithThreads(IN PERESOURCE Res)
Definition: ExResource.c:371
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:498
#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
Definition: ExResource.c:98
#define skip(...)
Definition: atltest.h:64
_Out_ PKIRQL Irql
Definition: csq.h:179
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
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:68
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
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 STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define L(x)
Definition: ntvdm.h:50
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define memset(x, y, z)
Definition: compat.h:39

◆ StartThread()

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

Definition at line 331 of file ExResource.c.

336{
339
340 ThreadData->Wait = Wait;
341 ThreadData->RetExpected = RetExpected;
347
349}
#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 474 of file ExResource.c.

476{
479 BOOLEAN Ret;
480
482 Ret = ThreadData->AcquireResource(ThreadData->Res, ThreadData->Wait);
483 if (ThreadData->RetExpected)
484 ok_bool_true(Ret, "AcquireResource returned");
485 else
486 ok_bool_false(Ret, "AcquireResource returned");
488
490
491 ok_bool_false(KeSetEvent(&ThreadData->OutEvent, 0, TRUE), "KeSetEvent returned");
494}
#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
182 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
183 if (pKeAreAllApcsDisabled)
184 ok_eq_uint(pKeAreAllApcsDisabled(), AreApcsDisabled);
185
186 if (skip(pExEnterCriticalRegionAndAcquireResourceShared &&
187 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive &&
188 pExEnterCriticalRegionAndAcquireResourceExclusive &&
189 pExReleaseResourceAndLeaveCriticalRegion, "No shortcuts\n"))
190 {
191 return;
192 }
193 /* ExEnterCriticalRegionAndAcquireResourceShared, ExEnterCriticalRegionAndAcquireSharedWaitForExclusive */
194 Count = 0;
195 Ret = pExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
196 ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
197 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
198 if (pKeAreAllApcsDisabled)
199 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
200 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
201
202 Ret = pExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
203 ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
204 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
205 if (pKeAreAllApcsDisabled)
206 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
207 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
208
209 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive(Res); ++Count;
210 ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
211 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
212 if (pKeAreAllApcsDisabled)
213 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
214 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
215
216 while (Count-- > 1)
217 {
218 pExReleaseResourceAndLeaveCriticalRegion(Res);
219 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
220 if (pKeAreAllApcsDisabled)
221 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
222 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
223 }
224
225 pExReleaseResourceAndLeaveCriticalRegion(Res);
226 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
227 if (pKeAreAllApcsDisabled)
228 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
229 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
230
231 /* ExEnterCriticalRegionAndAcquireResourceExclusive */
232 Count = 0;
233 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
234 if (pKeAreAllApcsDisabled)
235 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
236 Ret = pExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
237 ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
238 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
239 if (pKeAreAllApcsDisabled)
240 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
241 CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
242
243 Ret = pExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
244 ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
245 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
246 if (pKeAreAllApcsDisabled)
247 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
248 CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
249
250 pExReleaseResourceAndLeaveCriticalRegion(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_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
258 if (pKeAreAllApcsDisabled)
259 ok_eq_uint(pKeAreAllApcsDisabled(), AreApcsDisabled);
260 CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
261}
#define ok_eq_uint(value, expected)
Definition: apitest.h:61
#define ok_eq_bool(value, expected)
Definition: apitest.h:80
#define KeGetCurrentThread
Definition: hal.h:55

Referenced by START_TEST().

◆ TestResourceWithOwner()

static VOID TestResourceWithOwner ( IN PERESOURCE  Res)
static

Definition at line 498 of file ExResource.c.

500{
502 THREAD_DATA ThreadDataOwner;
503
505
507 ok_bool_true(ExAcquireResourceExclusiveLite(Res, FALSE), "ExAcquireResourceExclusiveLite returned");
510
511 ok_bool_true(ExAcquireResourceExclusiveLite(Res, FALSE), "ExAcquireResourceExclusiveLite returned");
512 ExSetResourceOwnerPointer(Res, (PVOID)((ULONG_PTR)Res | 3));
514
515 Status = StartThread(&ThreadDataOwner, NULL, FALSE, FALSE);
517
518 FinishThread(&ThreadDataOwner);
519}
static VOID FinishThread(PTHREAD_DATA ThreadData)
Definition: ExResource.c:353
static VOID NTAPI TestOwnerRes(PVOID Context)
Definition: ExResource.c:474
static NTSTATUS StartThread(PTHREAD_DATA ThreadData, PLARGE_INTEGER Timeout, BOOLEAN Wait, BOOLEAN RetExpected)
Definition: ExResource.c:331
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 371 of file ExResource.c.

373{
375 THREAD_DATA ThreadDataShared;
376 THREAD_DATA ThreadDataShared2;
377 THREAD_DATA ThreadDataExclusive;
378 THREAD_DATA ThreadDataSharedStarve;
379 THREAD_DATA ThreadDataSharedWait;
381 Timeout.QuadPart = -10 * 1000 * 10; /* 10 ms */
382
383 InitThreadData(&ThreadDataShared, Res, ExAcquireResourceSharedLite);
384 InitThreadData(&ThreadDataShared2, Res, ExAcquireResourceSharedLite);
385 InitThreadData(&ThreadDataExclusive, Res, ExAcquireResourceExclusiveLite);
386 InitThreadData(&ThreadDataSharedStarve, Res, ExAcquireSharedStarveExclusive);
387 InitThreadData(&ThreadDataSharedWait, Res, ExAcquireSharedWaitForExclusive);
388
389 /* have a thread acquire the resource shared */
390 Status = StartThread(&ThreadDataShared, NULL, FALSE, TRUE);
392 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
393 ok_eq_int(Res->ActiveCount, 1);
394
395 /* a second thread should be able to acquire the resource shared */
396 Status = StartThread(&ThreadDataShared2, NULL, FALSE, TRUE);
398 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
399 ok_eq_int(Res->ActiveCount, 2);
400 FinishThread(&ThreadDataShared2);
401 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
402 ok_eq_int(Res->ActiveCount, 1);
403
404 /* now have a thread that tries to acquire the resource exclusive -- it should fail */
405 Status = StartThread(&ThreadDataExclusive, NULL, FALSE, FALSE);
407 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
408 ok_eq_int(Res->ActiveCount, 1);
409 FinishThread(&ThreadDataExclusive);
410 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
411 ok_eq_int(Res->ActiveCount, 1);
412
413 /* as above, but this time it should block */
414 Status = StartThread(&ThreadDataExclusive, &Timeout, TRUE, TRUE);
416 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
417 ok_eq_int(Res->ActiveCount, 1);
418
419 /* now try another shared one -- it should fail */
420 Status = StartThread(&ThreadDataShared2, NULL, FALSE, FALSE);
422 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
423 ok_eq_int(Res->ActiveCount, 1);
424 FinishThread(&ThreadDataShared2);
425
426 /* same for ExAcquireSharedWaitForExclusive */
427 Status = StartThread(&ThreadDataSharedWait, NULL, FALSE, FALSE);
429 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
430 ok_eq_int(Res->ActiveCount, 1);
431 FinishThread(&ThreadDataSharedWait);
432
433 /* ExAcquireSharedStarveExclusive must get access though! */
434 Status = StartThread(&ThreadDataSharedStarve, NULL, TRUE, TRUE);
436 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
437 ok_eq_int(Res->ActiveCount, 2);
438 FinishThread(&ThreadDataSharedStarve);
439 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
440 ok_eq_int(Res->ActiveCount, 1);
441
442 /* block another shared one */
443 Status = StartThread(&ThreadDataShared2, &Timeout, TRUE, TRUE);
445 CheckResourceStatus(Res, FALSE, 0LU, 1LU, 1LU);
446 ok_eq_int(Res->ActiveCount, 1);
447
448 /* finish the very first one */
449 FinishThread(&ThreadDataShared);
450
451 /* now the blocked exclusive one should get the resource */
454 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 1LU);
455 ok_eq_int(Res->ActiveCount, 1);
456 ok_eq_uint((Res->Flag & ResourceOwnedExclusive) != 0, 1);
457
458 FinishThread(&ThreadDataExclusive);
459 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
460
461 /* now the blocked shared one should resume */
464 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
465 ok_eq_int(Res->ActiveCount, 1);
466 FinishThread(&ThreadDataShared2);
467 CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
468 ok_eq_int(Res->ActiveCount, 0);
469}
static VOID InitThreadData(PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction)
Definition: ExResource.c:321
#define ok_eq_int(value, expected)
Definition: apitest.h:60
#define U(x)
Definition: wordpad.c:45
#define ResourceOwnedExclusive
Definition: dldetect.h:32
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
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().