ReactOS  0.4.15-dev-1384-g878186b
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)
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
Definition: wdfsync.h:225
static WCHAR Address[46]
Definition: ping.c:68
Definition: xml2sdb.h:79
#define NULL
Definition: types.h:112
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:4306

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"); \
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)
ULONG NTAPI ExGetExclusiveWaiterCount(IN PERESOURCE Resource)
Definition: resource.c:1535
#define ok_bool_false(value, desc)
Definition: kmt_test.h:257
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
ULONG NTAPI ExGetSharedWaiterCount(IN PERESOURCE Resource)
Definition: resource.c:1558
__in PWDFDEVICE_INIT __in BOOLEAN Exclusive
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1658

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;
64  USHORT Flag;
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 {
72  PVOID Address;
73  ULONG_PTR CreatorBackTraceIndex;
Definition: extypes.h:210
#define _ANONYMOUS_UNION
Definition: ntbasedef.h:30
#define DUMMYUNIONNAME
Definition: ntbasedef.h:32
uint32_t ULONG_PTR
Definition: typedefs.h:65
short SHORT
Definition: pedump.c:59
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
Definition: wdfsync.h:225
static WCHAR Address[46]
Definition: ping.c:68
Definition: xml2sdb.h:79
Definition: typedefs.h:119
unsigned short USHORT
Definition: pedump.c:61
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
* PERESOURCE_2K3
Definition: ExResource.c:76
unsigned int ULONG
Definition: retypes.h:1
ERESOURCE_2K3
Definition: ExResource.c:76

◆ 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 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define ok_bool_false(value, desc)
Definition: kmt_test.h:257
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
#define ExReleaseResource(R)
Definition: exfuncs.h:257
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define NULL
Definition: types.h:112
struct tagContext Context
Definition: acpixf.h:1034
#define ok_eq_hex(value, expected)
#define STATUS_SUCCESS
Definition: shellext.h:65

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 }
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
HANDLE Handle
Definition: drwtsn32.h:25
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NULL
Definition: types.h:112
#define ok_eq_hex(value, expected)
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22

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 }
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:87
#define FALSE
Definition: types.h:117
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477

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 
549  KeLowerIrql(Irql);
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);
568  KeLowerIrql(Irql);
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 
580  TestResourceWithOwner(&Res);
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 TestResourceUndocumentedShortcuts(IN PERESOURCE Res, IN BOOLEAN AreApcsDisabled)
Definition: ExResource.c:175
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
NTSTATUS NTAPI ExReinitializeResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1756
#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
Definition: ExResource.c:98
#define CheckResourceFields(Res, Reinit)
Definition: ExResource.c:78
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
_Out_ PKIRQL Irql
Definition: csq.h:179
_SEH2_TRY
Definition: create.c:4226
#define ok_bool_false(value, desc)
Definition: kmt_test.h:257
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
static VOID TestResourceSharedAccess(IN PERESOURCE Res)
Definition: ExResource.c:111
static VOID TestResourceWithOwner(IN PERESOURCE Res)
Definition: ExResource.c:498
static VOID TestResourceWithThreads(IN PERESOURCE Res)
Definition: ExResource.c:371
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
static const WCHAR L[]
Definition: oid.c:1250
BOOLEAN NTAPI KeAreApcsDisabled(VOID)
Definition: apc.c:958
_SEH2_END
Definition: create.c:4400
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
static VOID TestResourceExclusiveAccess(IN PERESOURCE Res)
Definition: ExResource.c:144
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
* PERESOURCE_2K3
Definition: ExResource.c:76
ULONG ERESOURCE
Definition: env_spec_w32.h:594
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ok_eq_hex(value, expected)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
ERESOURCE_2K3
Definition: ExResource.c:76
#define memset(x, y, z)
Definition: compat.h:39
#define APC_LEVEL
Definition: env_spec_w32.h:695

◆ 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 GENERIC_ALL
Definition: nt_native.h:92
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
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:496
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
HANDLE Handle
Definition: drwtsn32.h:25
POBJECT_TYPE PsThreadType
Definition: thread.c:20
#define SYNCHRONIZE
Definition: nt_native.h:61
static ULONG Timeout
Definition: ping.c:61
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
#define NULL
Definition: types.h:112
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ok_eq_hex(value, expected)
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

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 TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ok_bool_false(value, desc)
Definition: kmt_test.h:257
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define NULL
Definition: types.h:112
struct tagContext Context
Definition: acpixf.h:1034
VOID NTAPI ExReleaseResourceForThreadLite(IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread)
Definition: resource.c:1844
#define ok_eq_hex(value, expected)
#define STATUS_SUCCESS
Definition: shellext.h:65

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 }
BOOLEAN NTAPI ExAcquireSharedWaitForExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1217
#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
Definition: ExResource.c:98
#define TRUE
Definition: types.h:120
VOID NTAPI ExConvertExclusiveToSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1402
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
int Count
Definition: noreturn.cpp:7
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1063
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885

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 */
133  if (!KmtIsCheckedBuild)
135  CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
136 
137  while (Count--)
140 }
BOOLEAN NTAPI ExAcquireSharedWaitForExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1217
#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
Definition: ExResource.c:98
#define TRUE
Definition: types.h:120
VOID NTAPI ExConvertExclusiveToSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1402
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ok_bool_false(value, desc)
Definition: kmt_test.h:257
BOOLEAN KmtIsCheckedBuild
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
int Count
Definition: noreturn.cpp:7
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1063
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885

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 CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
Definition: ExResource.c:98
#define TRUE
Definition: types.h:120
#define ok_eq_pointer(value, expected)
#define ok_bool_false(value, desc)
Definition: kmt_test.h:257
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
#define ok_eq_bool(value, expected)
Definition: kmt_test.h:258
int Count
Definition: noreturn.cpp:7
BOOLEAN NTAPI KeAreApcsDisabled(VOID)
Definition: apc.c:958
#define skip(...)
Definition: atltest.h:64
#define ok_eq_uint(value, expected)
Definition: kmt_test.h:239
#define KeGetCurrentThread
Definition: hal.h:44

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 NTSTATUS StartThread(PTHREAD_DATA ThreadData, PLARGE_INTEGER Timeout, BOOLEAN Wait, BOOLEAN RetExpected)
Definition: ExResource.c:331
static VOID InitThreadDataEx(PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction, PKSTART_ROUTINE StartRoutine)
Definition: ExResource.c:306
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
#define FALSE
Definition: types.h:117
static VOID FinishThread(PTHREAD_DATA ThreadData)
Definition: ExResource.c:353
Status
Definition: gdiplustypes.h:24
static VOID NTAPI TestOwnerRes(PVOID Context)
Definition: ExResource.c:474
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
Definition: resource.c:2045
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define NULL
Definition: types.h:112
VOID NTAPI ExReleaseResourceForThreadLite(IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread)
Definition: resource.c:1844
#define ok_eq_hex(value, expected)
#define STATUS_SUCCESS
Definition: shellext.h:65

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 */
452  Status = KeWaitForSingleObject(&ThreadDataExclusive.OutEvent, Executive, KernelMode, FALSE, NULL);
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 }
BOOLEAN NTAPI ExAcquireSharedWaitForExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1217
static NTSTATUS StartThread(PTHREAD_DATA ThreadData, PLARGE_INTEGER Timeout, BOOLEAN Wait, BOOLEAN RetExpected)
Definition: ExResource.c:331
#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
Definition: ExResource.c:98
#define TRUE
Definition: types.h:120
#define ok_eq_int(value, expected)
Definition: kmt_test.h:238
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define FALSE
Definition: types.h:117
KEVENT OutEvent
Definition: ExFastMutex.c:152
static VOID FinishThread(PTHREAD_DATA ThreadData)
Definition: ExResource.c:353
Status
Definition: gdiplustypes.h:24
static VOID InitThreadData(PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction)
Definition: ExResource.c:321
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1063
static ULONG Timeout
Definition: ping.c:61
#define NULL
Definition: types.h:112
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define ok_eq_hex(value, expected)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ok_eq_uint(value, expected)
Definition: kmt_test.h:239
#define ResourceOwnedExclusive
Definition: dldetect.h:32

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().