Files
swift-mirror/validation-test/Runtime/ConcurrentMetadata.swift
Mike Ash 4ccfdfb72a [Runtime] Fix StableAddressConcurrentReadableHashMap threading crash.
StableAddressConcurrentReadableHashMap::getOrInsert had a race condition in the first lookup, where the snapshot was destroyed before the pointer was extracted from the returned wrapper. Fix this by creating the snapshot outside the if so that it stays alive.

rdar://problem/71932487
2020-12-21 16:52:56 -05:00

57 lines
1.3 KiB
Swift

// RUN: %target-run-simple-swift
// REQUIRES: executable_test
// Exercise the metadata cache from multiple threads to shake out any
// concurrency bugs.
import StdlibUnittest
import SwiftPrivateThreadExtras
struct One {}
struct Two {}
struct Cat<T, U> {}
protocol Growable {}
extension Growable {
func grow() -> (Growable, Growable) {
return (Cat<Self, One>(), Cat<Self, Two>())
}
}
extension One: Growable {}
extension Two: Growable {}
extension Cat: Growable {}
var ConcurrentMetadataTestSuite = TestSuite("ConcurrentMetadata")
ConcurrentMetadataTestSuite.test("ConcurrentMetadata") {
let threadCount = 16
let iterationCount = 10000
func threadFunc() {
var array: [Growable] = [One(), Two()]
for i in 0..<iterationCount {
// Each call to grow() creates a new generic metadata specialization which
// will race with creating that same metadata on the other threads.
let (a, b) = array[i].grow()
array.append(a)
array.append(b)
}
}
let threadIDs = (0..<16).map { _ -> ThreadHandle in
let (ret, threadID) = _stdlib_thread_create_block(threadFunc, ())
expectEqual(0, ret)
return threadID!
}
for threadID in threadIDs {
let (ret, _) = _stdlib_thread_join(threadID, Void.self)
expectEqual(0, ret)
}
}
runAllTests()