ReactOS 0.4.15-dev-8116-gf69e256
RtlCriticalSection.c File Reference
#include "precomp.h"
#include <pseh/pseh2.h>
Include dependency graph for RtlCriticalSection.c:

Go to the source code of this file.

Typedefs

typedef NTSTATUS NTAPI FN_RtlInitializeCriticalSectionEx(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount, _In_ ULONG Flags)
 

Functions

static void Test_Init (void)
 
static DWORD WINAPI ThreadProc1 (_In_ LPVOID lpParameter)
 
static DWORD WINAPI ThreadProc2 (_In_ LPVOID lpParameter)
 
static void Test_Acquire (void)
 
 START_TEST (RtlCriticalSection)
 

Variables

SYSTEM_INFO g_SysInfo
 
OSVERSIONINFOEXA g_VerInfo
 
ULONG g_Version
 
ULONG g_DefaultSpinCount
 
FN_RtlInitializeCriticalSectionExpfnRtlInitializeCriticalSectionEx
 
RTL_CRITICAL_SECTION CritSect
 
HANDLE hEventThread1Ready
 
HANDLE hEventThread1Cont
 
HANDLE hEventThread2Ready
 
HANDLE hEventThread2Cont
 

Typedef Documentation

◆ FN_RtlInitializeCriticalSectionEx

typedef NTSTATUS NTAPI FN_RtlInitializeCriticalSectionEx(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount, _In_ ULONG Flags)

Definition at line 19 of file RtlCriticalSection.c.

Function Documentation

◆ START_TEST()

START_TEST ( RtlCriticalSection  )

Definition at line 383 of file RtlCriticalSection.c.

384{
385 HMODULE hmodNtDll = GetModuleHandleA("ntdll.dll");
387 GetProcAddress(hmodNtDll, "RtlInitializeCriticalSectionEx");
388
392 printf("g_VerInfo: %lu.%lu.%lu ('%s')\n ",
398 printf("g_SysInfo.dwNumberOfProcessors = %lu\n", g_SysInfo.dwNumberOfProcessors);
399
401 {
402 g_DefaultSpinCount = 0x20007d0;
403 }
404 else
405 {
407 }
408
409 Test_Init();
410 Test_Acquire();
411}
FN_RtlInitializeCriticalSectionEx * pfnRtlInitializeCriticalSectionEx
static void Test_Acquire(void)
NTSTATUS NTAPI FN_RtlInitializeCriticalSectionEx(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount, _In_ ULONG Flags)
SYSTEM_INFO g_SysInfo
static void Test_Init(void)
OSVERSIONINFOEXA g_VerInfo
ULONG g_Version
ULONG g_DefaultSpinCount
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
BOOL WINAPI GetVersionExA(IN LPOSVERSIONINFOA lpVersionInformation)
Definition: version.c:69
#define printf
Definition: freeldr.h:97
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
ULONG dwMajorVersion
Definition: rtltypes.h:256
ULONG dwMinorVersion
Definition: rtltypes.h:257
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:255
ULONG dwBuildNumber
Definition: rtltypes.h:258
CHAR szCSDVersion[128]
Definition: rtltypes.h:260
DWORD dwNumberOfProcessors
Definition: winbase.h:1177

◆ Test_Acquire()

static void Test_Acquire ( void  )
static

Definition at line 277 of file RtlCriticalSection.c.

278{
279 DWORD dwThreadId1, dwThreadId2;
281
283
284 // Acquire once
291
292 // Acquire recursively
299
304
305 // Create thread 1 and wait to it time to try to acquire the critical section
306 hThread1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, &dwThreadId1);
307
308 // Wait up to 10 s
309 for (ULONG i = 0; (CritSect.LockCount == -2) && (i < 1000); i++)
310 {
311 Sleep(10);
312 }
313
317 //ok_ptr(CritSect.LockSemaphore, LongToPtr(-1)); // TODO: this behaves differently on different OS versions
319
320 // Create thread 2 and wait to it time to try to acquire the critical section
321 hThread2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, &dwThreadId2);
322
323 // Wait up to 10 s
324 for (ULONG i = 0; (CritSect.LockCount == -6) && (i < 1000); i++)
325 {
326 Sleep(10);
327 }
328
332 //ok_ptr(CritSect.LockSemaphore, LongToPtr(-1));
334
339
340 // Wait until thread 1 has acquired the critical section
342
346 //ok_ptr(CritSect.LockSemaphore, LongToPtr(-1));
347 if (g_DefaultSpinCount != 0)
348 {
349 ok(CritSect.SpinCount <= g_DefaultSpinCount, "SpinCount increased\n");
350 }
351 else
352 {
354 }
355
357
358 // Release thread 1, wait for thread 2 to acquire the critical section
361
365 //ok_ptr(CritSect.LockSemaphore, LongToPtr(-1));
366 if (g_DefaultSpinCount != 0)
367 {
368 ok(CritSect.SpinCount <= g_DefaultSpinCount, "SpinCount increased\n");
369 }
370 else
371 {
373 }
374
375 // Release thread 2
377
378 // To make Thomas happy :)
381}
HANDLE hEventThread1Ready
RTL_CRITICAL_SECTION CritSect
HANDLE hEventThread2Ready
static DWORD WINAPI ThreadProc1(_In_ LPVOID lpParameter)
static DWORD WINAPI ThreadProc2(_In_ LPVOID lpParameter)
HANDLE hEventThread2Cont
HANDLE hEventThread1Cont
static HANDLE hThread2
static HANDLE hThread1
#define ok_long(expression, result)
Definition: atltest.h:133
#define ok(value,...)
Definition: atltest.h:57
#define ok_size_t(expression, result)
Definition: atltest.h:115
#define ok_ptr(expression, result)
Definition: atltest.h:108
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
#define INFINITE
Definition: serial.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
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
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
uint32_t ULONG
Definition: typedefs.h:59
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define CreateEvent
Definition: winbase.h:3748

Referenced by START_TEST().

◆ Test_Init()

static void Test_Init ( void  )
static

Definition at line 31 of file RtlCriticalSection.c.

32{
34 BOOL HasDebugInfo = (g_Version <= _WIN32_WINNT_VISTA);
35
37 {
40 }
42 {
44 }
47
55 if (HasDebugInfo)
56 {
57 ok(CritSect.DebugInfo != NULL, "DebugInfo is %p\n", CritSect.DebugInfo);
58 ok(CritSect.DebugInfo != LongToPtr(-1), "DebugInfo is %p\n", CritSect.DebugInfo);
59 }
60 else
61 {
62 ok(CritSect.DebugInfo == LongToPtr(-1), "DebugInfo is %p\n", CritSect.DebugInfo);
63 }
64
72 if (HasDebugInfo)
73 {
74 ok(CritSect.DebugInfo != NULL, "DebugInfo is %p\n", CritSect.DebugInfo);
75 ok(CritSect.DebugInfo != LongToPtr(-1), "DebugInfo is %p\n", CritSect.DebugInfo);
76 }
77 else
78 {
79 ok(CritSect.DebugInfo == LongToPtr(-1), "DebugInfo is %p\n", CritSect.DebugInfo);
80 }
81
85
89
91 {
93 {
96 }
98 {
100 }
101 _SEH2_END;
103
111 if (HasDebugInfo)
112 {
113 ok(CritSect.DebugInfo != NULL, "DebugInfo is %p\n", CritSect.DebugInfo);
114 ok(CritSect.DebugInfo != LongToPtr(-1), "DebugInfo is %p\n", CritSect.DebugInfo);
115 if ((CritSect.DebugInfo != NULL) && (CritSect.DebugInfo != LongToPtr(-1)))
116 {
121 ok(CritSect.DebugInfo->ProcessLocksList.Flink != NULL, "Flink is NULL\n");
122 ok(CritSect.DebugInfo->ProcessLocksList.Blink != NULL, "Blink is NULL\n");
125 {
130 }
135 }
136 }
137 else
138 {
139 ok(CritSect.DebugInfo == LongToPtr(-1), "DebugInfo is %p\n", CritSect.DebugInfo);
140 }
141
144
147
150
152 {
154 }
156 {
158 }
159 _SEH2_END;
161
162 for (ULONG i = 0; i < 32; i++)
163 {
164 ULONG Flags = 1UL << i;
165 ULONG AllowedFlags = 0x07FFFFFF;
166 if (g_Version >= _WIN32_WINNT_WIN7) AllowedFlags |= 0x18000000;
167 NTSTATUS ExpectedStatus = (Flags & ~AllowedFlags) ?
170 ok(Status == ExpectedStatus, "Wrong Status (0x%lx) for Flags 0x%lx\n",
171 Status, Flags);
172 if (NT_SUCCESS(Status))
173 {
174 ULONG SetFlags = Flags & 0x08000000;
175 if (g_Version >= _WIN32_WINNT_WIN7) SetFlags |= (Flags & 0x03000000);
177 }
178 }
179
183 {
185 }
187 {
189 }
190 _SEH2_END;
192
193 Status = pfnRtlInitializeCriticalSectionEx(&CritSect, 0x12345678, 0xFFFFFFFF);
195
198 {
200 ok(CritSect.DebugInfo != NULL, "DebugInfo is %p\n", CritSect.DebugInfo);
201 ok(CritSect.DebugInfo != LongToPtr(-1), "DebugInfo is %p\n", CritSect.DebugInfo);
202 if ((CritSect.DebugInfo != NULL) && (CritSect.DebugInfo != LongToPtr(-1)))
203 {
208 ok(CritSect.DebugInfo->ProcessLocksList.Flink != NULL, "Flink is NULL\n");
209 ok(CritSect.DebugInfo->ProcessLocksList.Blink != NULL, "Blink is NULL\n");
212 {
217 }
222 }
223 }
224 else
225 {
227 }
228 }
229 else
230 {
231 skip("RtlInitializeCriticalSectionEx not available.\n");
232 }
233}
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define skip(...)
Definition: atltest.h:64
#define ok_int(expression, result)
Definition: atltest.h:134
LONG NTSTATUS
Definition: precomp.h:26
#define LongToPtr(l)
Definition: basetsd.h:91
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount(_In_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount)
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _RTL_CRITICAL_SECTION * CriticalSection
Definition: rtltypes.h:1422
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1431
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1089
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by START_TEST().

◆ ThreadProc1()

static DWORD WINAPI ThreadProc1 ( _In_ LPVOID  lpParameter)
static

Definition at line 238 of file RtlCriticalSection.c.

240{
241 printf("ThreadProc1 starting\n");
243
245
246 printf("ThreadProc1 waiting\n");
248 printf("ThreadProc1 returned from wait\n");
249
251
252 return 0;
253}

Referenced by Test_Acquire().

◆ ThreadProc2()

static DWORD WINAPI ThreadProc2 ( _In_ LPVOID  lpParameter)
static

Definition at line 258 of file RtlCriticalSection.c.

260{
261 printf("ThreadProc2 starting\n");
263
265
266 printf("ThreadProc2 waiting\n");
268 printf("ThreadProc2 returned from wait\n");
269
271
272 return 0;
273}

Referenced by Test_Acquire().

Variable Documentation

◆ CritSect

◆ g_DefaultSpinCount

ULONG g_DefaultSpinCount

Definition at line 14 of file RtlCriticalSection.c.

Referenced by START_TEST(), Test_Acquire(), and Test_Init().

◆ g_SysInfo

SYSTEM_INFO g_SysInfo

Definition at line 11 of file RtlCriticalSection.c.

Referenced by START_TEST(), and Test_Init().

◆ g_VerInfo

OSVERSIONINFOEXA g_VerInfo

Definition at line 12 of file RtlCriticalSection.c.

Referenced by START_TEST().

◆ g_Version

ULONG g_Version

Definition at line 13 of file RtlCriticalSection.c.

Referenced by START_TEST(), and Test_Init().

◆ hEventThread1Cont

HANDLE hEventThread1Cont

Definition at line 26 of file RtlCriticalSection.c.

Referenced by Test_Acquire(), and ThreadProc1().

◆ hEventThread1Ready

HANDLE hEventThread1Ready

Definition at line 26 of file RtlCriticalSection.c.

Referenced by Test_Acquire(), and ThreadProc1().

◆ hEventThread2Cont

HANDLE hEventThread2Cont

Definition at line 27 of file RtlCriticalSection.c.

Referenced by Test_Acquire(), and ThreadProc2().

◆ hEventThread2Ready

HANDLE hEventThread2Ready

Definition at line 27 of file RtlCriticalSection.c.

Referenced by Test_Acquire(), and ThreadProc2().

◆ pfnRtlInitializeCriticalSectionEx

FN_RtlInitializeCriticalSectionEx* pfnRtlInitializeCriticalSectionEx

Definition at line 24 of file RtlCriticalSection.c.

Referenced by START_TEST(), and Test_Init().