ReactOS  0.4.14-dev-583-g2a1ba2c
KeMutex.c File Reference
#include <kmt_test.h>
Include dependency graph for KeMutex.c:

Go to the source code of this file.

Macros

#define ULONGS_PER_POINTER   (sizeof(PVOID) / sizeof(ULONG))
 
#define MUTANT_SIZE   (2 + 6 * ULONGS_PER_POINTER)
 
#define CheckMutex(Mutex, State, New, ExpectedApcDisable)
 
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql)
 

Functions

static _IRQL_requires_min_ (PASSIVE_LEVEL)
 
static VOID TestMutex (VOID)
 
 START_TEST (KeMutex)
 

Macro Definition Documentation

◆ CheckApcs

#define CheckApcs (   KernelApcsDisabled,
  SpecialApcsDisabled,
  AllApcsDisabled,
  Irql 
)
Value:
do \
{ \
ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
if (pKeAreAllApcsDisabled) \
ok_eq_bool(pKeAreAllApcsDisabled(), AllApcsDisabled); \
ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
ok_irql(Irql); \
} while (0)
_Out_ PKIRQL Irql
Definition: csq.h:179
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
BOOLEAN NTAPI KeAreApcsDisabled(VOID)
Definition: apc.c:958

◆ CheckMutex

#define CheckMutex (   Mutex,
  State,
  New,
  ExpectedApcDisable 
)

◆ MUTANT_SIZE

#define MUTANT_SIZE   (2 + 6 * ULONGS_PER_POINTER)

◆ ULONGS_PER_POINTER

#define ULONGS_PER_POINTER   (sizeof(PVOID) / sizeof(ULONG))

Function Documentation

◆ _IRQL_requires_min_()

static _IRQL_requires_min_ ( PASSIVE_LEVEL  )
static

Definition at line 11 of file KeMutex.c.

24  { \
25  PKTHREAD Thread = KeGetCurrentThread(); \
26  ok_eq_uint((Mutex)->Header.Type, MutantObject); \
27  ok_eq_uint((Mutex)->Header.Abandoned, 0x55); \
28  ok_eq_uint((Mutex)->Header.Size, MUTANT_SIZE); \
29  ok_eq_uint((Mutex)->Header.DpcActive, 0x55); \
30  ok_eq_pointer((Mutex)->Header.WaitListHead.Flink, \
31  &(Mutex)->Header.WaitListHead); \
32  ok_eq_pointer((Mutex)->Header.WaitListHead.Blink, \
33  &(Mutex)->Header.WaitListHead); \
34  if ((State) <= 0) \
35  { \
36  ok_eq_long((Mutex)->Header.SignalState, State); \
37  ok_eq_pointer((Mutex)->MutantListEntry.Flink, &Thread->MutantListHead); \
38  ok_eq_pointer((Mutex)->MutantListEntry.Blink, &Thread->MutantListHead); \
39  ok_eq_pointer(Thread->MutantListHead.Flink, &(Mutex)->MutantListEntry); \
40  ok_eq_pointer(Thread->MutantListHead.Blink, &(Mutex)->MutantListEntry); \
41  ok_eq_pointer((Mutex)->OwnerThread, Thread); \
42  } \
43  else \
44  { \
45  ok_eq_long((Mutex)->Header.SignalState, State); \
46  if (New) \
47  { \
48  ok_eq_pointer((Mutex)->MutantListEntry.Flink, \
49  (PVOID)0x5555555555555555ULL); \
50  ok_eq_pointer((Mutex)->MutantListEntry.Blink, \
51  (PVOID)0x5555555555555555ULL); \
52  } \
53  ok_eq_pointer(Thread->MutantListHead.Flink, &Thread->MutantListHead); \
54  ok_eq_pointer(Thread->MutantListHead.Blink, &Thread->MutantListHead); \
55  ok_eq_pointer((Mutex)->OwnerThread, NULL); \
56  } \
57  ok_eq_uint((Mutex)->Abandoned, 0); \
58  ok_eq_uint((Mutex)->ApcDisable, ExpectedApcDisable); \
59 } while (0)
60 
61 #define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql) do \
62 { \
63  ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
64  ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
65  if (pKeAreAllApcsDisabled) \
66  ok_eq_bool(pKeAreAllApcsDisabled(), AllApcsDisabled); \
67  ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
68  ok_irql(Irql); \
69 } while (0)
70 
71 static
72 VOID
73 TestMutant(VOID)
74 {
76  KMUTANT Mutant;
77  LONG State;
78  LONG i;
80 
82  RtlFillMemory(&Mutant, sizeof(Mutant), 0x55);
83  KeInitializeMutant(&Mutant, FALSE);
84  CheckMutex(&Mutant, 1L, TRUE, 0);
86 
87  RtlFillMemory(&Mutant, sizeof(Mutant), 0x55);
88  KeInitializeMutant(&Mutant, TRUE);
90  CheckMutex(&Mutant, 0L, TRUE, 0);
91  State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
92  ok_eq_long(State, 0L);
93  CheckMutex(&Mutant, 1L, FALSE, 0);
95 
96  /* Acquire and release */
97  Status = KeWaitForSingleObject(&Mutant,
98  Executive,
99  KernelMode,
100  FALSE,
101  NULL);
103  CheckMutex(&Mutant, 0L, TRUE, 0);
104  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
105 
106  State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
107  ok_eq_long(State, 0L);
108  CheckMutex(&Mutant, 1L, FALSE, 0);
109  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
110 
111  /* Acquire recursively */
112  for (i = 0; i < 8; i++)
113  {
114  KmtStartSeh()
115  Status = KeWaitForSingleObject(&Mutant,
116  Executive,
117  KernelMode,
118  FALSE,
119  NULL);
122  CheckMutex(&Mutant, -i, FALSE, 0);
123  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
124  }
125 
126  for (i = 0; i < 7; i++)
127  {
128  KmtStartSeh()
129  State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
131  ok_eq_long(State, -7L + i);
132  CheckMutex(&Mutant, -6L + i, FALSE, 0);
133  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
134  }
135 
136  State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
137  ok_eq_long(State, 0L);
138  CheckMutex(&Mutant, 1L, FALSE, 0);
139  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
140 
141  /* Pretend to acquire it recursively -MINLONG times */
142  KmtStartSeh()
143  Status = KeWaitForSingleObject(&Mutant,
144  Executive,
145  KernelMode,
146  FALSE,
147  NULL);
150  CheckMutex(&Mutant, 0L, FALSE, 0);
151  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
152 
153  Mutant.Header.SignalState = MINLONG + 1;
154  KmtStartSeh()
155  Status = KeWaitForSingleObject(&Mutant,
156  Executive,
157  KernelMode,
158  FALSE,
159  NULL);
162  CheckMutex(&Mutant, (LONG)MINLONG, FALSE, 0);
163  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
164 
165  KmtStartSeh()
166  KeWaitForSingleObject(&Mutant,
167  Executive,
168  KernelMode,
169  FALSE,
170  NULL);
172  CheckMutex(&Mutant, (LONG)MINLONG, FALSE, 0);
173  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
174 
175  State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
177  CheckMutex(&Mutant, (LONG)MINLONG + 1L, FALSE, 0);
178  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
179 
180  Mutant.Header.SignalState = -1;
181  State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
182  ok_eq_long(State, -1L);
183  CheckMutex(&Mutant, 0L, FALSE, 0);
184  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
185 
186  State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
187  ok_eq_long(State, 0L);
188  CheckMutex(&Mutant, 1L, FALSE, 0);
189  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
190 
191  /* Now release it once too often */
192  KmtStartSeh()
193  KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
195  CheckMutex(&Mutant, 1L, FALSE, 0);
196  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
197 }
#define CheckMutex(Mutex, State, New, ExpectedApcDisable)
#define TRUE
Definition: types.h:120
VOID NTAPI KeInitializeMutant(IN PKMUTANT Mutant, IN BOOLEAN InitialOwner)
Definition: mutex.c:22
LONG NTSTATUS
Definition: precomp.h:26
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:283
#define New(t)
Definition: rtf.h:1086
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql)
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 STATUS_MUTANT_NOT_OWNED
Definition: ntstatus.h:292
Definition: Mutex.h:15
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: Header.h:8
_In_ KPRIORITY _In_ BOOLEAN Abandoned
Definition: kefuncs.h:606
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define for
Definition: utility.h:88
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
static const WCHAR L[]
Definition: oid.c:1250
#define MINLONG
Definition: umtypes.h:115
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KmtStartSeh()
Definition: kmt_test.h:277
Status
Definition: gdiplustypes.h:24
enum State_ State
Definition: pofuncs.h:54
Header(const std::string &filename_)
Definition: Header.h:18
#define ok_eq_hex(value, expected)
#define KeGetCurrentThread
Definition: hal.h:44
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define MUTANT_SIZE
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define ok_eq_long(value, expected)
Definition: kmt_test.h:240
#define STATUS_MUTANT_LIMIT_EXCEEDED
Definition: ntstatus.h:620

◆ START_TEST()

START_TEST ( KeMutex  )

Definition at line 323 of file KeMutex.c.

324 {
325  pKeAreAllApcsDisabled = KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
326  if (skip(pKeAreAllApcsDisabled != NULL, "KeAreAllApcsDisabled unavailable\n"))
327  {
328  /* We can live without this function here */
329  }
330 
331  TestMutant();
332  TestMutex();
333 }
smooth NULL
Definition: ftsmooth.c:416
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
static const WCHAR L[]
Definition: oid.c:1250
#define skip(...)
Definition: atltest.h:64
static VOID TestMutex(VOID)
Definition: KeMutex.c:201

◆ TestMutex()

static VOID TestMutex ( VOID  )
static

Definition at line 201 of file KeMutex.c.

202 {
204  KMUTEX Mutex;
205  LONG State;
206  LONG i;
208 
209  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
210  RtlFillMemory(&Mutex, sizeof(Mutex), 0x55);
212  CheckMutex(&Mutex, 1L, TRUE, 1);
213  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
214 
215  RtlFillMemory(&Mutex, sizeof(Mutex), 0x55);
216  KeInitializeMutex(&Mutex, 123);
217  CheckMutex(&Mutex, 1L, TRUE, 1);
218  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
219 
220  /* Acquire and release */
222  Executive,
223  KernelMode,
224  FALSE,
225  NULL);
227  CheckMutex(&Mutex, 0L, FALSE, 1);
228  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
229 
231  ok_eq_long(State, 0L);
232  CheckMutex(&Mutex, 1L, FALSE, 1);
233  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
234 
235  /* Acquire recursively */
236  for (i = 0; i < 8; i++)
237  {
238  KmtStartSeh()
240  Executive,
241  KernelMode,
242  FALSE,
243  NULL);
246  CheckMutex(&Mutex, -i, FALSE, 1);
247  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
248  }
249 
250  for (i = 0; i < 7; i++)
251  {
252  KmtStartSeh()
255  ok_eq_long(State, -7L + i);
256  CheckMutex(&Mutex, -6L + i, FALSE, 1);
257  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
258  }
259 
261  ok_eq_long(State, 0L);
262  CheckMutex(&Mutex, 1L, FALSE, 1);
263  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
264 
265  /* Pretend to acquire it recursively -MINLONG times */
266  KmtStartSeh()
268  Executive,
269  KernelMode,
270  FALSE,
271  NULL);
274  CheckMutex(&Mutex, 0L, FALSE, 1);
275  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
276 
277  Mutex.Header.SignalState = MINLONG + 1;
278  KmtStartSeh()
280  Executive,
281  KernelMode,
282  FALSE,
283  NULL);
287  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
288 
289  KmtStartSeh()
291  Executive,
292  KernelMode,
293  FALSE,
294  NULL);
297  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
298 
301  CheckMutex(&Mutex, (LONG)MINLONG + 1L, FALSE, 1);
302  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
303 
304  Mutex.Header.SignalState = -1;
306  ok_eq_long(State, -1L);
307  CheckMutex(&Mutex, 0L, FALSE, 1);
308  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
309 
311  ok_eq_long(State, 0L);
312  CheckMutex(&Mutex, 1L, FALSE, 1);
313  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
314 
315  /* Now release it once too often */
316  KmtStartSeh()
319  CheckMutex(&Mutex, 1L, FALSE, 1);
320  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
321 }
#define CheckMutex(Mutex, State, New, ExpectedApcDisable)
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:283
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql)
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
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 STATUS_MUTANT_NOT_OWNED
Definition: ntstatus.h:292
Definition: Mutex.h:15
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: Header.h:8
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define for
Definition: utility.h:88
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
static const WCHAR L[]
Definition: oid.c:1250
#define MINLONG
Definition: umtypes.h:115
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KmtStartSeh()
Definition: kmt_test.h:277
Status
Definition: gdiplustypes.h:24
enum State_ State
Definition: pofuncs.h:54
static PFAST_MUTEX Mutex
Definition: timer.c:22
#define ok_eq_hex(value, expected)
#define KeGetCurrentThread
Definition: hal.h:44
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define ok_eq_long(value, expected)
Definition: kmt_test.h:240
#define STATUS_MUTANT_LIMIT_EXCEEDED
Definition: ntstatus.h:620

Referenced by START_TEST().