Skip to content

Commit 6bf7b9e

Browse files
committed
stdlib: implement _stdlib_create_pthread_block in terms of Windows threaing
Port the block based thread constructor to Windows threading model, and rename it to `_stdlib_create_thread_block`.
1 parent e1d7ee7 commit 6bf7b9e

File tree

4 files changed

+38
-18
lines changed

4 files changed

+38
-18
lines changed

stdlib/private/StdlibUnittest/RaceTest.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -605,21 +605,21 @@ public func runRaceTest<RT : RaceTestWithPerTrialData>(
605605

606606
// Create the master thread.
607607
do {
608-
let (ret, tid) = _stdlib_pthread_create_block(masterThreadBody, ())
608+
let (ret, tid) = _stdlib_thread_create_block(masterThreadBody, ())
609609
expectEqual(0, ret)
610610
testTids.append(tid!)
611611
}
612612

613613
// Create racing threads.
614614
for i in 0..<racingThreadCount {
615-
let (ret, tid) = _stdlib_pthread_create_block(racingThreadBody, i)
615+
let (ret, tid) = _stdlib_thread_create_block(racingThreadBody, i)
616616
expectEqual(0, ret)
617617
testTids.append(tid!)
618618
}
619619

620620
// Create the alarm thread that enforces the timeout.
621621
do {
622-
let (ret, tid) = _stdlib_pthread_create_block(alarmThreadBody, ())
622+
let (ret, tid) = _stdlib_thread_create_block(alarmThreadBody, ())
623623
expectEqual(0, ret)
624624
alarmTid = tid!
625625
}

stdlib/private/SwiftPrivateThreadExtras/SwiftPrivateThreadExtras.swift

+32-12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import Darwin
2020
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku)
2121
import Glibc
22+
#elseif os(Windows)
23+
import MSVCRT
2224
#endif
2325

2426
/// An abstract base class to encapsulate the context necessary to invoke
@@ -59,16 +61,43 @@ internal func invokeBlockContext(
5961
return context.run()
6062
}
6163

64+
#if os(Windows)
65+
public typealias ThreadHandle = HANDLE
66+
#else
67+
public typealias ThreadHandle = pthread_t
68+
69+
#if os(Linux) || os(Android)
70+
internal func _make_pthread_t() -> pthread_t {
71+
return pthread_t()
72+
}
73+
#else
74+
internal func _make_pthread_t() -> pthread_t? {
75+
return nil
76+
}
77+
#endif
78+
#endif
79+
6280
/// Block-based wrapper for `pthread_create`.
63-
public func _stdlib_pthread_create_block<Argument, Result>(
81+
public func _stdlib_thread_create_block<Argument, Result>(
6482
_ start_routine: @escaping (Argument) -> Result,
6583
_ arg: Argument
66-
) -> (CInt, pthread_t?) {
84+
) -> (CInt, ThreadHandle?) {
6785
let context = ThreadBlockContextImpl(block: start_routine, arg: arg)
6886
// We hand ownership off to `invokeBlockContext` through its void context
6987
// argument.
7088
let contextAsVoidPointer = Unmanaged.passRetained(context).toOpaque()
7189

90+
#if os(Windows)
91+
var threadID =
92+
_beginthreadex(nil, 0, { invokeBlockContext($0)!
93+
.assumingMemoryBound(to: UInt32.self).pointee },
94+
contextAsVoidPointer, 0, nil)
95+
if threadID == 0 {
96+
return (errno, nil)
97+
} else {
98+
return (0, UnsafeMutablePointer<ThreadHandle>(&threadID).pointee)
99+
}
100+
#else
72101
var threadID = _make_pthread_t()
73102
let result = pthread_create(&threadID, nil,
74103
{ invokeBlockContext($0) }, contextAsVoidPointer)
@@ -77,17 +106,8 @@ public func _stdlib_pthread_create_block<Argument, Result>(
77106
} else {
78107
return (result, nil)
79108
}
80-
}
81-
82-
#if os(Linux) || os(Android)
83-
internal func _make_pthread_t() -> pthread_t {
84-
return pthread_t()
85-
}
86-
#else
87-
internal func _make_pthread_t() -> pthread_t? {
88-
return nil
89-
}
90109
#endif
110+
}
91111

92112
/// Block-based wrapper for `pthread_join`.
93113
public func _stdlib_pthread_join<Result>(

test/Interpreter/enforce_exclusive_access.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ ExclusiveAccessTestSuite.test("ClosureCaptureReadRead") {
120120
// have overlapping accesses
121121
ExclusiveAccessTestSuite.test("PerThreadEnforcement") {
122122
modifyAndPerform(&globalX) {
123-
let (_, otherThread) = _stdlib_pthread_create_block({ (_ : Void) -> () in
123+
let (_, otherThread) = _stdlib_thread_create_block({ (_ : Void) -> () in
124124
globalX.i = 12 // no-trap
125125
return ()
126126
}, ())

validation-test/stdlib/StringSlicesConcurrentAppend.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ StringTestSuite.test("SliceConcurrentAppend") {
9393
var ret = _stdlib_thread_barrier_init(barrierVar!, 2)
9494
expectEqual(0, ret)
9595

96-
let (createRet1, tid1) = _stdlib_pthread_create_block(
96+
let (createRet1, tid1) = _stdlib_thread_create_block(
9797
sliceConcurrentAppendThread, .Primary)
98-
let (createRet2, tid2) = _stdlib_pthread_create_block(
98+
let (createRet2, tid2) = _stdlib_thread_create_block(
9999
sliceConcurrentAppendThread, .Secondary)
100100

101101
expectEqual(0, createRet1)

0 commit comments

Comments
 (0)