@@ -16,6 +16,7 @@ import Darwin
16
16
import Glibc
17
17
#elseif os(Windows)
18
18
import MSVCRT
19
+ import WinSDK
19
20
#endif
20
21
21
22
//
@@ -29,7 +30,10 @@ public var _stdlib_THREAD_BARRIER_SERIAL_THREAD: CInt {
29
30
}
30
31
31
32
public struct _stdlib_thread_barrier_t {
32
- #if os(Cygwin) || os(FreeBSD)
33
+ #if os(Windows)
34
+ var mutex : UnsafeMutablePointer < SRWLOCK > ?
35
+ var cond : UnsafeMutablePointer < CONDITION_VARIABLE > ?
36
+ #elseif os(Cygwin) || os(FreeBSD)
33
37
var mutex : UnsafeMutablePointer < pthread_mutex_t ? > ?
34
38
var cond : UnsafeMutablePointer < pthread_cond_t ? > ?
35
39
#else
@@ -57,6 +61,13 @@ public func _stdlib_thread_barrier_init(
57
61
errno = EINVAL
58
62
return - 1
59
63
}
64
+ #if os(Windows)
65
+ barrier. pointee. mutex = UnsafeMutablePointer . allocate ( capacity: 1 )
66
+ InitializeSRWLock ( barrier. pointee. mutex!)
67
+
68
+ barrier. pointee. cond = UnsafeMutablePointer . allocate ( capacity: 1 )
69
+ InitializeConditionVariable ( barrier. pointee. cond!)
70
+ #else
60
71
barrier. pointee. mutex = UnsafeMutablePointer . allocate ( capacity: 1 )
61
72
if pthread_mutex_init ( barrier. pointee. mutex!, nil ) != 0 {
62
73
// FIXME: leaking memory.
@@ -67,13 +78,18 @@ public func _stdlib_thread_barrier_init(
67
78
// FIXME: leaking memory, leaking a mutex.
68
79
return - 1
69
80
}
81
+ #endif
70
82
barrier. pointee. count = count
71
83
return 0
72
84
}
73
85
74
86
public func _stdlib_thread_barrier_destroy(
75
87
_ barrier: UnsafeMutablePointer < _stdlib_thread_barrier_t >
76
88
) -> CInt {
89
+ #if os(Windows)
90
+ // Condition Variables do not need to be explicitly destroyed
91
+ // Mutexes do not need to be explicitly destroyed
92
+ #else
77
93
if pthread_cond_destroy ( barrier. pointee. cond!) != 0 {
78
94
// FIXME: leaking memory, leaking a mutex.
79
95
return - 1
@@ -82,40 +98,61 @@ public func _stdlib_thread_barrier_destroy(
82
98
// FIXME: leaking memory.
83
99
return - 1
84
100
}
101
+ #endif
85
102
barrier. pointee. cond!. deinitialize ( count: 1 )
86
103
barrier. pointee. cond!. deallocate ( )
104
+
87
105
barrier. pointee. mutex!. deinitialize ( count: 1 )
88
106
barrier. pointee. mutex!. deallocate ( )
107
+
89
108
return 0
90
109
}
91
110
92
111
public func _stdlib_thread_barrier_wait(
93
112
_ barrier: UnsafeMutablePointer < _stdlib_thread_barrier_t >
94
113
) -> CInt {
114
+ #if os(Windows)
115
+ AcquireSRWLockExclusive ( barrier. pointee. mutex!)
116
+ #else
95
117
if pthread_mutex_lock ( barrier. pointee. mutex!) != 0 {
96
118
return - 1
97
119
}
120
+ #endif
98
121
barrier. pointee. numThreadsWaiting += 1
99
122
if barrier. pointee. numThreadsWaiting < barrier. pointee. count {
100
123
// Put the thread to sleep.
124
+ #if os(Windows)
125
+ // TODO(compnerd) modularize rpc.h to get INFIITE (0xffffffff)
126
+ if SleepConditionVariableSRW ( barrier. pointee. cond!, barrier. pointee. mutex!,
127
+ 0xffffffff , 0 ) == 0 {
128
+ return - 1
129
+ }
130
+ ReleaseSRWLockExclusive ( barrier. pointee. mutex!)
131
+ #else
101
132
if pthread_cond_wait ( barrier. pointee. cond!, barrier. pointee. mutex!) != 0 {
102
133
return - 1
103
134
}
104
135
if pthread_mutex_unlock ( barrier. pointee. mutex!) != 0 {
105
136
return - 1
106
137
}
138
+ #endif
107
139
return 0
108
140
} else {
109
141
// Reset thread count.
110
142
barrier. pointee. numThreadsWaiting = 0
111
143
112
144
// Wake up all threads.
145
+ #if os(Windows)
146
+ WakeAllConditionVariable ( barrier. pointee. cond!)
147
+ ReleaseSRWLockExclusive ( barrier. pointee. mutex!)
148
+ #else
113
149
if pthread_cond_broadcast ( barrier. pointee. cond!) != 0 {
114
150
return - 1
115
151
}
116
152
if pthread_mutex_unlock ( barrier. pointee. mutex!) != 0 {
117
153
return - 1
118
154
}
155
+ #endif
119
156
return _stdlib_THREAD_BARRIER_SERIAL_THREAD
120
157
}
121
158
}
0 commit comments