Share
Embed
Transcript
74 slides
-
͑ͦ͏ͳͭ • Swift Atomics (apple/swift-atomics) • Synchronization (swiftlang/swift/blob/main/stdlib/public/Synchronization/) • Grand
Central Dispatch (apple/swift-corelibs-libdispatch) 6 -
Swift Atomics ⚛︎ ︎ • ༁ɿຊύοέʔδSwift༻ͷatomicsϥΠϒϥϦΛ࣮͢ΔɻϙΠϯλ ΛؚΉ༷ʑͳSwiftͷܕʹෆՄૢ࡞Λఏڙ͢Δɻతɺ༐ͳ։ൃऀ͕ SwiftͰʹಉظߏΛߏஙͰ͖ΔΑ͏ʹ͢Δ͜ͱͰ͋Δɻ • ࠷৽όʔδϣϯͷϦϦʔε͕202310݄ɺ࠷৽ίϛοτ͕20247݄
• ManagedAtomicsͱUnsafeAtomics͘Β͍͔͠ͳ͍ 7 https://github.com/apple/swift-atomics -
Synchronization framework • ༁ɿਫ४ͷϓϦϛςΟϒͳૢ࡞Λ༻͍ͯಉظߏΛߏங͢Δɻ • iOS 18.0+ɺmacOS 15.0+ • AtomicͱMutex͕͋Δ
• SE-0410: Low-Level Atomic Operations (Swift 6.0) • swift-atomicsΛେ͍ʹࢀߟʹͯ͠࡞ͬͨΈ͍ͨ • SE-0433: Synchronous Mutual Exclusion Lock (Swift 6.0) 8 https://developer.apple.com/documentation/synchronization -
10 • Α͘ͳ͍ͷͰɺconcurrency checkΛ༗ޮʹ͢ΔͱΤϥʔʹͳΔ Α͘ͳ͍ιʔείʔυͷྫ var counter = 0 DispatchQueue.concurrentPerform(iterations:
10) { _ in for _ in 0 ..< 1_000_000 { counter += 1 } } print(counter) Mutation of captured var ‘counter’ in concurrently-executing code 👈Swift 5Ͱ࣮ߦ͢Δͱ10_000_000ʹͳΒͳ͍ -
11 • Atomicʹੜ͍͑ͯΔϝιουΛͬͯΛಡΈॻ͖͢Δ SynchronizationͷAtomic<Value>ͷ༻ྫ let counter = Atomic<Int>(0) DispatchQueue.concurrentPerform(iterations: 10)
{ _ in for _ in 0 ..< 1_000_000 { counter.wrappingAdd(1, ordering: .relaxed) } } print(counter.load(ordering: .relaxed)) 👈10_000_000ʹͳΔʂ https://github.com/swiftlang/swift-evolution/blob/.../proposals/0410-atomics.md#proposed-solution -
12 • Atomicʹੜ͍͑ͯΔϝιουΛͬͯΛಡΈॻ͖͢Δ SynchronizationͷAtomic<Value>ͷ༻ྫ let counter = Atomic<Int>(0) DispatchQueue.concurrentPerform(iterations: 10)
{ _ in for _ in 0 ..< 1_000_000 { counter.wrappingAdd(1, ordering: .relaxed) } } print(counter.load(ordering: .relaxed)) https://github.com/swiftlang/swift-evolution/blob/.../proposals/0410-atomics.md#proposed-solution -
Atomicʹੜ͑ͯΔϝιουͨͪ • addɺsubtractɿΦʔόʔϑϩʔͪ͠Ό͏ • wrapping(Add|Subtract)ɿϥοϓΞϥϯυͯ͘͠ΕΔ • bitwise(And|Or|Xor)ɿIntಉ࢜ • logical(And|Or|Xor)ɿBoolಉ࢜ •
maxɺminɿͦͷ·Μ· • compareExchangeɿڧ͍൛ • weakCompareExchangeɿऑ͍൛ʢspurious failureΛڐ༰͢Δʣ • exchange(_ desired: consuming Value, ordering: AtomicUpdateOrdering) -> Valueɿcompare͠ͳ͍ • load(ordering: AtomicLoadOrdering) -> ValueɿಡΉ • store(_ desired: consuming Value, ordering: AtomicStoreOrdering)ɿॻ͘ 13 ※தʹΑͬͯ͑ΔϝιουҟͳΓ·͢ -
Mutex<Value> • DarwinͰϩοΫʹos_unfair_lockΛ༻ • LinuxWindowsWebAssembly༻ͷ࣮͋Δʢࡉ͔͍ڍಈҟͳΔʣ • os.OSAllocatedUnfairLock<State>ͱͷҧ͍ • Mutexʹ~Copyableͳͷ͔ͤ͠ͳ͍ 15
https://github.com/swiftlang/swift-evolution/blob/.../proposals/0433-mutex.md https://github.com/swiftlang/swift/blob/.../stdlib/public/Synchronization/Mutex/Mutex.swift https://developer.apple.com/documentation/os/osallocatedunfairlock -
struct Atomic<Value: AtomicRepresentable> • AtomicRepresentable • static func decodeAtomicRepresentation( consuming
Self.AtomicRepresentation ) -> Self • static func encodeAtomicRepresentation( consuming Self ) -> Self.AtomicRepresentation 19 https://developer.apple.com/documentation/synchronization/atomicrepresentable -
ඪ४ͰAtomicRepresentationͳօ͞Μ • UIntͷօ͞Μ • Intͷօ͞Μ • struct WordPair • double
wide atomicsରԠͷڥԼͰ2ͭͷUIntΛ·ͱΊͯѻ͏ 21 https://developer.apple.com/documentation/synchronization/wordpair https://github.com/swiftlang/swift/blob/.../lib/Basic/LangOptions.cpp#L313-L409 Ҏ্ʂ -
AtomicIntegers.swift.gyb Ұ෦ൈਮ͓ͯ͠ૹΓ͓ͯ͠Γ·͢ • LLVMͷΞτϛοΫ໋ྩΛ͏·͘ϥοϓͯ͠Δ͚ͩ 22 public func ${lowerFirst(name)}( _ operand:
${intType}, ordering: AtomicUpdateOrdering ) -> (oldValue: ${intType}, newValue: ${intType}) { Builtin.atomicrmw_${atomicOperationName(intType, builtinName)}_${llvmOrder}_Int64( _rawAddress, operand._value ) } https://github.com/swiftlang/swift/blob/.../stdlib/public/Synchronization/Atomics/AtomicIntegers.swift.gyb#L95-L157 https://github.com/swiftlang/swift/blob/.../utils/SwiftAtomics.py#L71-L82 https://llvm.org/docs/LangRef.html#atomicrmw-instruction -
public func ${lowerFirst(name)}( _ operand: ${intType}, ordering: AtomicUpdateOrdering ) ->
(oldValue: ${intType}, newValue: ${intType}) { Builtin.atomicrmw_${atomicOperationName(intType, builtinName)}_${llvmOrder}_Int64( _rawAddress, operand._value ) } AtomicIntegers.swift.gyb Ұ෦ൈਮ͓ͯ͠ૹΓ͓ͯ͠Γ·͢ • LLVMͷΞτϛοΫ໋ྩΛ͏·͘ϥοϓͯ͠Δ͚ͩ 23 integerOperations = [ # Swift name, llvm name, operator, doc name ("WrappingAdd", "add", "&+", "wrapping add"), ("WrappingSubtract", "sub", "&-", "wrapping subtract"), … https://github.com/swiftlang/swift/blob/.../stdlib/public/Synchronization/Atomics/AtomicIntegers.swift.gyb#L95-L157 https://github.com/swiftlang/swift/blob/.../utils/SwiftAtomics.py#L71-L82 https://llvm.org/docs/LangRef.html#atomicrmw-instruction -
IntҎ֎Atomic<Value>ʹ͍ͨ͠ʂ • σʔλͷ͕͞64bitҎʹऩ·ΔͳΒ࣮࣭Int64ͳͷͰηʔϑ • UnsafePointerIntͬͯݴͬͯΔ • WordPairͳΒUIntΛಉ࣌ʹ2ͭѻ͓͑ͯಘ • ྫɿIntܕϓϩύςΟ͕2ͭ͋ΔߏମΛAtomicRepresentableʹ͢Δ 24
https://github.com/swiftlang/swift/blob/.../stdlib/public/Synchronization/Atomics/AtomicPointers.swift#L40-L42 Int.encodeAtomicRepresentation( Int(bitPattern: value) ) -
27 • swift-atomicsͱҟͳΓ~Copyable͕͍͍ͭͯΔ ݫ͍͠ᶃɿSynchronizationͰ~Copyable // Synchronization struct Atomic<Value: AtomicRepresentable>: ~Copyable
struct Mutex<Value: ~Copyable>: ~Copyable // swift-atomics class ManagedAtomic<Value: AtomicValue> -
ݫ͍͠ᶄɿletଋറͰએݴ͠ͳ͚ΕͳΒͳ͍ • AtomicMutexvarͰએݴͰ͖ͳ͍ • swift-atomicsͷAtomicͳΒvar͕ڐ͞Εͨ 28 https://github.com/swiftlang/swift/blob/.../stdlib/public/Synchronization/Atomics/Atomic.swift#L16-L20 https://github.com/swiftlang/swift/blob/.../stdlib/public/Synchronization/Mutex/Mutex.swift#L34-L37 @available(SwiftStdlib 6.0,
*) @frozen @_rawLayout(like: Value.AtomicRepresentation) @_staticExclusiveOnly public struct Atomic<Value: AtomicRepresentable>: ~Copyable 👈͍ͭ͜ͷ͍ͤʂ -
@_staticExclusiveOnly • -enable-experimental-feature͕ඞཁ • ~Copyableͳܕʹ͔͚ͭ͠ΒΕͳ͍ • Atomic͕~Copyableͳͷ͜ΕͷͨΊ…ͳͷ͔ͳ͋…ʁ • NGߦҝɿίϐʔɺvarɺinout 29
https://github.com/swiftlang/swift/blob/.../stdlib/public/Synchronization/CMakeLists.txt#L75 https://github.com/swiftlang/swift/blob/.../test/attr/attr_static_exclusive_only.swift#L3 -
@_staticExclusiveOnlyʹΑΔ֬ೝ • varΛͬͯͳ͍͔ͷ֬ೝ • void visitBoundVariable(VarDecl *VD)ͷ్த • inoutͰ͞Εͯͳ͍͔ͷ֬ೝ •
TypeResolver::resolveASTFunctionTypeParams(...)ͷ్த 30 https://github.com/swiftlang/swift/blob/.../lib/Sema/TypeCheckType.cpp#L3853-L3860 https://github.com/swiftlang/swift/blob/.../lib/Sema/TypeCheckDeclPrimary.cpp#L2672-L2695 SD->getAttrs().hasAttribute<StaticExclusiveOnlyAttr>() -
@_rawLayout(like: Value.AtomicRepresentation) • ݴޠʹΑΔཧΛʢ΄΅ʣ͠ͳ͍raw storageΛ࣋ͭ • ΞτϛοΫͳͲͷಛघͳΞΫηεΛߦ͏σʔλߏͷετϨʔδ • ~Copyableͳܕʹ͔͚ͭ͠ΒΕͣɺstored propertyΛ࣋ͭ͜ͱ͕Ͱ͖ͳ͘ͳΔ
• ϥΠϑλΠϜશମʹΘͨΓ҆ఆͨ͠ΞυϨεΛ࣋ͭ • ܕͷαΠζͱΞϥΠϯϝϯτlike: Tͱಉ͡ 31 https://github.com/swiftlang/swift/blob/.../docs/ReferenceGuides/UnderscoredAttributes.md#_rawlayout https://github.com/swiftlang/swift/blob/.../test/Sema/raw_layout.swift -
൫ੴͳਞʂ • ~Copyableɺ@_staticExclusiveOnlyɺ@_rawLayout͕ἧͬͯڧͦ͏ 32 let counter = Atomic<Int>(0) 👆ͨͩ1ͭͷॴ༗ݖ ಛఆͷAtomicΦϒδΣΫτ͚ͩΛࢦ͢👆
@_staticExclusiveOnly ~Copyable 👆ΞυϨε͕҆ఆ -
the Law of Exclusivity • มͷมߋͱมΞΫηεഉଞతͰͳ͚ΕͳΒͳ͍ • ੩తஅಈతஅΛͯ͠ҧ͕ͳ͍͔ࢹ͍ͯ͠Δ • letଋറͳͲͷෆมͷϝϞϦॻ͖ࠐΈ͕ൃੜͤͣಈతͳνΣοΫ͕ෆཁ
• letͳΒ࣮ߦ࣌ʹΦʔόʔϔου͕ൃੜ͠ͳ͍ʂ 33 https://www.swift.org/blog/swift-5-exclusivity/ https://github.com/swiftlang/swift-evolution/blob/.../proposals/0176-enforce-exclusive-access-to-memory.md -
ݫ͍͠ᶅɿΦʔμϦϯάίϯύΠϧఆͰʂ • ΦʔμϦϯάʢޙड़ʣΛࢦఆͰ͖Δ͕ɺఆͰࢦఆ͠ͳ͍ͱΤϥʔʹͳΔ • swift-atomicsಉ༷ɹͭ·Γ👇݁ߏલ͔Β͋Δ • @_semantics("atomics.requires_constant_orderings")Ͱ࣮ݱ 34 var ordering
= AtomicUpdateOrdering.relaxed atomic.add(1, ordering: ordering) Ordering argument must be a static method or property of ‘… 👆ઐ༻ͷΤϥʔϝοηʔδ͕͋Δ https://github.com/swiftlang/swift/blob/.../stdlib/public/Synchronization/Atomics/AtomicIntegers.swift.gyb#L110 https://github.com/apple/swift-atomics/blob/.../Sources/Atomics/Types/ManagedAtomic.swift#L58 https://github.com/swiftlang/swift/blob/.../test/Sema/diag_constantness_check.swift https://github.com/swiftlang/swift/blob/.../include/swift/AST/DiagnosticsSema.def#L7470-L7472 -
@_semantics("...") • SwiftΦϓςΟϚΠβͰΑ͘ΘΕͯΔΒ͍͠ • ༁ɿߴਫ४ͳ࠷దԽʢߴਫ४ݴޠͰҰൠతʣͱਫ४ͷ࠷దԽͷ྆ํ Λ࣮ݱ͢ΔͨΊɺ ඪ४ϥΠϒϥϦͷҰ෦ʹΞϊςʔγϣϯΛ͚ͭɺ Swiftඪ ४ϥΠϒϥϦͷσʔλܕʹ͓͚ΔυϝΠϯݻ༗ͷߴਫ४ͳૢ࡞ͷηϚϯ ςΟΫεΛهड़͢Δɻ
• ΦϓςΟϚΠβλάʹԠͨ͡ॲཧΛߦ͏ • ArrayStringDictionaryͳͲͰΘΕ͍ͯΔ 35 https://github.com/swiftlang/swift/blob/.../include/swift/AST/SemanticAttrs.def#L92 https://github.com/swiftlang/swift/blob/.../docs/HighLevelSILOptimizations.rst -
HighLevelSILOptimizations.rstʹॻ͍ͯ͋ͬͨ͜ͱ • ࠷దԽͷύΠϓϥΠϯ 1. ·ͣhigh-levelͳ࠷దԽΛ͠·͢ 2. ͜͜ͰॳΊͯ@_semanticsͷ͍ͭͨؔΛΠϯϥΠϯԽ͠·͢ • ઌʹΠϯϥΠϯԽ͢ΔͱpassϞδϡʔϧ͕ͨͪ1. ͰࠔͬͪΌ͏͔Β
3. ΠϯϥΠϯԽޙʹlow-levelͳ࠷దԽΛ͠·͢ 36 https://github.com/swiftlang/swift/blob/.../docs/HighLevelSILOptimizations.rst ⚠Atomicͱؔͳ͍Έ͍ͨ⚠ -
݁ہ͍ͭΦʔμϦϯάҾΛνΣοΫͯ͠Δͷ͔ • static Expr *checkConstantness(Expr *expr)ͷத • ḷ͍ͬͯ͘ͱTypeCheckConstraints.cppʹḷΓண͘ʢ͋Εʁʣ • Sema
checkͱͯͬͯ͠Δ 37 https://github.com/swiftlang/swift/blob/.../lib/Sema/ConstantnessSemaDiagnostics.cpp#L334 ↑ https://github.com/swiftlang/swift/blob/.../lib/Sema/MiscDiagnostics.cpp#L6233 ↑ https://github.com/swiftlang/swift/blob/.../lib/Sema/TypeCheckConstraints.cpp#L338-L342 hasSemanticsAttr(funcDecl, semantics::ATOMICS_REQUIRES_CONSTANT_ORDERINGS) -
lock-free, single-consumer stackΛ࡞Δ • ෦తʹlinked listͷߏ • UnsafeMutablePointerͰͭͳ͕ͬͯΔ • push()͢Δͱϊʔυ͕૿͑ͯpop()͢Δͱϊʔυ͕ݮΔ
• ෳεϨου͔ΒͲΜͲΜpush()ͯ͠Α͍ • pop()ͷ࠷தʹผεϨου͔Βpop()͢ΔͷNGʢsingle-consumerʣ 42 ɿUnsafeMutablePointer Stack Node Node Node Node -
Atomicͷ͍Ͳ͜Ζ2Օॴ • ελοΫ͔ΒϊʔυͷUnsafeMutablePointer • pop()࡞ۀதͷconsumerͷ 43 Stack Node Node Node
Node Atomic<UnsafeMutablePointer<Node>?> pop()தͷ consumer͕ Nਓ Atomic<Int> -
private let _consumerCount = Atomic<Int>(0) • pop()಄Ͱ+1ɺdeferͰ-1 • ಄Ͱ+1͢Δ͍ͭͰʹɺpreconditionͰ͕0Ͱ͋Δ͜ͱΛ͔֬ΊΔ 44
ଞͷਓ͕pop()ͯ͠ͳ͍ t εϨουA ࠓͷΛ ಡΉ औಘͨ͠ʹ +1ͨ͠Λ ॻ͘ ࠓͷΛ ಡΉ औಘͨ͠ʹ -1ͨ͠Λ ॻ͘ popͷ࡞ۀத… +1 -1 -
private let _consumerCount = Atomic<Int>(0) • pop()಄Ͱ+1ɺdeferͰ-1 • ಄Ͱ+1͢Δ͍ͭͰʹɺpreconditionͰ͕0Ͱ͋Δ͜ͱΛ͔֬ΊΔ 45
ଞͷਓ͕pop()ͯ͠ͳ͍ t εϨουA ࠓͷΛ ಡΉ औಘͨ͠ʹ +1ͨ͠Λ ॻ͘ ࠓͷΛ ಡΉ औಘͨ͠ʹ -1ͨ͠Λ ॻ͘ t Count 0 0 1 -
զʑʹඞཁͳͷ • happens before ʢ ʣͷॱ൪ΛकͬͯΒ͏ͨΊͷΈ • ʮΠϕϯτ Πϕϯτ ͷલʹى͜Δʢى͜Βͳ͚ΕͳΒͳ͍ʣʯ
• ॱংؔ • Atomic*Orderingͱ͍͏ΦϓγϣϯͰࢦఆՄೳ a b a → b a b 53 -
54 • ॱ൪Λकͬͯ΄͍͠Օॴదʹࢦఆ͢Δ ΦʔμϦϯάΛࢦࣔ͢Δ͜ͱͰղܾ εϨουA ϊʔυૢ࡞ͯ͠ Χϯτ0ʹ͢Δ 👆 ଞͷมΞΫηεͷ ޙʹ࣮ߦ͍ͨ͠
ʢ.releasingʣ 👆 ଞͷมΞΫηεͷ લʹ࣮ߦ͍ͨ͠ ʢ.acquiringʣ precondition(_consumerCount.wrappingAdd(1, ordering: .acquiring)以下略) defer { _consumerCount.wrappingSubtract(1, ordering: .releasing) } -
ϝϞϦΦʔμϦϯά 55 Swift Atomic*Ordering C++ std::memory_order S_Shimotoriͷཧղ .sequentiallyConsistent seq_cst Ϟσϧɿஞ࣍Ұ؏ੑ
͍ .acquiringͱ.releasing acquireͱrelease ϞσϧɿϦϦʔεҰ؏ੑ .relaxed relaxed Ͳ͏ͳͬͯߏΘΜ .acquiringAndReleasingͱ͍͏ͷ͋ΔΑ ݫ͍͠ ΏΔ͍ -
ΦʔμϦϯάͷѻ͍ʹݫ͍͠ • ϝιουͷorderingҾʹσϑΥϧτ͕ͳ͍ • ͪΌΜͱ໌هͯ͠ίʔυϨϏϡʔʹ͔͚ͯ΄͍͠ • .sequentiallyConsistent͍ͷͰܰʑͬͯ͘͠΄͘͠ͳ͍ • ΦʔμϦϯάίϯύΠϧ࣌ఆͰ͞ͳ͍ͱ͍͚ͳ͍ •
࣮ߦ࣌ʹܾ·Δ = switchจʹΑΔذ͕Δ = ͘ͳΔ 56 -
Atomic<Value>ͱSendable • Conforms when Value conforms to Sendable and AtomicRepresentable.
60 let counter = Atomic(MyCounter(0)) DispatchQueue.concurrentPerform(iterations: 10) { _ in for _ in 0 ..< 1_000_000 { counter } } public struct MyCounter: AtomicRepresentable {...} Capture of 'counter' with non-sendable type 'Atomic<MyCounter>' in a `@Sendable` closure -
func version1() async • ඇಉظؔͷݺͼग़͠φγͷ߹ 63 func version1() async {
let counter = Atomic<Int>(0) let updatedCount = counter.load(...) } Stack … version1()ʹ தஅϙΠϯτ͕ͳ͍ͷͰ ྆ํͱ stackʹ͍Δ Heap … version1 ⚛︎︎ -
func version2() async • version2()͕caller͔ΒݺΕΔલ 64 func version2() async {
let counter = Atomic<Int>(0) let updater = Updater() await updater.update(counter) let updatedCount = counter.load(...) } Stack (caller) Heap … … (caller) -
func version2() async • version2()͕caller͔ΒݺΕͨ 65 func version2() async {
let counter = Atomic<Int>(0) let updater = Updater() await updater.update(counter) let updatedCount = counter.load(...) } Stack version2 Heap … … (caller) (caller) ϛ version2 ⚛︎︎ -
func version2() async • version2()͕caller͔ΒݺΕͨ 66 func version2() async {
let counter = Atomic<Int>(0) let updater = Updater() await updater.update(counter) let updatedCount = counter.load(...) } Stack version2 Heap … … (caller) version2 தஅϙΠϯτͷޙ͚ͩͳͷͰͬͪ͜ தஅϙΠϯτͷલޙͰͬͯΔͷͰ ⚛︎︎ -
func version2() async • update()ΛݺΜͩ 67 func version2() async {
let counter = Atomic<Int>(0) let updater = Updater() await updater.update(counter) let updatedCount = counter.load(...) } Stack update Heap … … (caller) version2 ϛ version2 update ⚛︎︎ -
func version2() async • update()͔Βversion2()ʹ͖ͬͯͨ 68 func version2() async {
let counter = Atomic<Int>(0) let updater = Updater() await updater.update(counter) let updatedCount = counter.load(...) } Stack version2 Heap … … (caller) version2 ⚛︎︎ -
func version2() async • load()࡞ۀʹҠΔ 69 func version2() async {
let counter = Atomic<Int>(0) let updater = Updater() await updater.update(counter) let updatedCount = counter.load(...) } Stack version2 Heap … … (caller) version2 load ⚛︎︎ -
func version2() async • load()ऴΘΓ 70 func version2() async {
let counter = Atomic<Int>(0) let updater = Updater() await updater.update(counter) let updatedCount = counter.load(...) } Stack version2 Heap … … (caller) version2 ⚛︎︎ -
func version3() async 71 func version3() async { let counter
= Atomic<Int>(0) let updater = Updater() await updater.doOtherWork() let updatedCount = counter.load(...) } Stack Heap … … version3 (caller) (caller) ϛ version3 ⚛︎︎ தஅϙΠϯτͷલޙͰͬͯΔͷͰ -
ࢀߟจݙ • What’s new in Swift - WWDC24 - Videos
- Apple Developer • https://developer.apple.com/videos/play/wwdc2024/10136/ • Var of Atomic type is not an error? - #2 by MahdiBM - Using Swift - Swift Forums • https://forums.swift.org/t/var-of-atomic-type-is-not-an-error/69885/2 • ಉظ • https://www.hpcs.cs.tsukuba.ac.jp/~tatebe/lecture/h27/dsys/5-sync.pdf • ϝϞϦϞσϧೖʢSequential ConsistencyͱTotal Store OrderΛཧղ͢Δʣ • https://techblog.lycorp.co.jp/ja/20231216a • Swift ʹಋೖ༧ఆͷ Ownership ػೳͷհ #swtws - Qiita • https://qiita.com/omochimetaru/items/c5f0eabde516e4713367 • How to develop SIL Optimizer in Swift Language • https://gist.github.com/freddi-kit/459297734b37cb51bfb08f74ce944cab • swift-ownership-jp/0176-enforce-exclusive-access-to-memory.md at master · omochi/swift-ownership-jp • https://github.com/omochi/swift-ownership-jp/blob/master/0176-enforce-exclusive-access-to-memory.md 74