Skip to content

Commit 21aeead

Browse files
committed
[Concurrency] Add Win32 implementation for recursive mutex.
We're using `CRITICAL_SECTION` here, as that supports recursion. rdar://113898653
1 parent 6397e30 commit 21aeead

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

include/swift/Threading/Impl/Win32.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,26 @@ inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {
8787
ReleaseSRWLockExclusive(&handle);
8888
}
8989

90+
// .. Recursive mutex support ................................................
91+
92+
using recursive_mutex_handle = SWIFT_CRITICAL_SECTION;
93+
94+
inline void recursive_mutex_init(recursive_mutex_handle &handle,
95+
bool checked = false) {
96+
InitializeCriticalSection(&handle);
97+
}
98+
99+
inline void recursive_mutex_destroy(recursive_mutex_handle &handle) {
100+
DeleteCriticalSection(&handle);
101+
}
102+
103+
inline void recursive_mutex_lock(recursive_mutex_handle &handle) {
104+
EnterCriticalSection(&handle);
105+
}
106+
inline void recursive_mutex_unlock(recursive_mutex_handle &handle) {
107+
LeaveCriticalSection(&handle);
108+
}
109+
90110
// .. ConditionVariable support ..............................................
91111

92112
struct cond_handle {

include/swift/Threading/Impl/Win32/Win32Defs.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ typedef unsigned char BYTE;
3636
typedef BYTE BOOLEAN;
3737
typedef int BOOL;
3838
typedef unsigned long DWORD;
39+
typedef long LONG;
3940
typedef unsigned long ULONG;
41+
typedef unsigned long ULONG_PTR;
42+
typedef PVOID HANDLE;
4043

4144
typedef VOID(NTAPI *PFLS_CALLBACK_FUNCTION)(PVOID lpFlsData);
4245

@@ -46,6 +49,11 @@ typedef PRTL_SRWLOCK PSRWLOCK;
4649
typedef struct _RTL_CONDITION_VARIABLE *PRTL_CONDITION_VARIABLE;
4750
typedef PRTL_CONDITION_VARIABLE PCONDITION_VARIABLE;
4851

52+
typedef struct _RTL_CRITICAL_SECTION_DEBUG *PRTL_CRITICAL_SECTION_DEBUG;
53+
typedef struct _RTL_CRITICAL_SECTION *PRTL_CRITICAL_SECTION;
54+
typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION;
55+
typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;
56+
4957
// These have to be #defines, to avoid problems with <windows.h>
5058
#define RTL_SRWLOCK_INIT {0}
5159
#define SRWLOCK_INIT RTL_SRWLOCK_INIT
@@ -83,6 +91,19 @@ WINBASEAPI BOOL WINAPI SleepConditionVariableSRW(
8391
ULONG Flags
8492
);
8593

94+
WINBASEAPI VOID WINAPI InitializeCriticalSection(
95+
LPCRITICAL_SECTION lpCriticalSection
96+
);
97+
WINBASEAPI VOID WINAPI DeleteCriticalSection(
98+
LPCRITICAL_SECTION lpCriticalSection
99+
);
100+
WINBASEAPI VOID WINAPI EnterCriticalSection(
101+
LPCRITICAL_SECTION lpCriticalSection
102+
);
103+
WINBASEAPI VOID WINAPI LeaveCriticalSection(
104+
LPCRITICAL_SECTION lpCriticalSection
105+
);
106+
86107
WINBASEAPI DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback);
87108
WINBASEAPI PVOID WINAPI FlsGetValue(DWORD dwFlsIndex);
88109
WINBASEAPI BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData);
@@ -140,6 +161,34 @@ inline BOOL SleepConditionVariableSRW(PSWIFT_CONDITION_VARIABLE CondVar,
140161
Flags);
141162
}
142163

164+
// And with CRITICAL_SECTION
165+
#pragma pack(push, 8)
166+
typedef struct SWIFT_CRITICAL_SECTION {
167+
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
168+
LONG LockCount;
169+
LONG RecursionCount;
170+
HANDLE OwningThread;
171+
HANDLE LockSemaphore;
172+
ULONG_PTR SpinCount;
173+
} SWIFT_CRITICAL_SECTION, *PSWIFT_CRITICAL_SECTION;
174+
#pragma pack(pop)
175+
176+
inline VOID InitializeCriticalSection(PSWIFT_CRITICAL_SECTION CritSec) {
177+
::InitializeCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(CritSec));
178+
}
179+
180+
inline VOID DeleteCriticalSection(PSWIFT_CRITICAL_SECTION CritSec) {
181+
::DeleteCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(CritSec));
182+
}
183+
184+
inline VOID EnterCriticalSection(PSWIFT_CRITICAL_SECTION CritSec) {
185+
::EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(CritSec));
186+
}
187+
188+
inline VOID LeaveCriticalSection(PSWIFT_CRITICAL_SECTION CritSec) {
189+
::LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(CritSec));
190+
}
191+
143192
} // namespace threading_impl
144193
} // namespace swift
145194

0 commit comments

Comments
 (0)