Anonymous user
Atomic updates: Difference between revisions
Add Swift
Thundergnat (talk | contribs) m (→{{header|Ring}}: Remove vanity tags) |
(Add Swift) |
||
Line 3,463:
}
</lang>
=={{header|Swift}}==
<lang swift>import Foundation
final class AtomicBuckets: CustomStringConvertible {
var count: Int {
return buckets.count
}
var description: String {
return withBucketsLocked { "\(buckets)" }
}
var total: Int {
return withBucketsLocked { buckets.reduce(0, +) }
}
private let lock = DispatchSemaphore(value: 1)
private var buckets: [Int]
subscript(n: Int) -> Int {
return withBucketsLocked { buckets[n] }
}
init(with buckets: [Int]) {
self.buckets = buckets
}
func transfer(amount: Int, from: Int, to: Int) {
withBucketsLocked {
let transferAmount = buckets[from] >= amount ? amount : buckets[from]
buckets[from] -= transferAmount
buckets[to] += transferAmount
}
}
private func withBucketsLocked<T>(do: () -> T) -> T {
let ret: T
lock.wait()
ret = `do`()
lock.signal()
return ret
}
}
let bucks = AtomicBuckets(with: [21, 39, 40, 20])
let order = DispatchSource.makeTimerSource()
let chaos = DispatchSource.makeTimerSource()
let printer = DispatchSource.makeTimerSource()
printer.setEventHandler {
print("\(bucks) = \(bucks.total)")
}
printer.schedule(deadline: .now(), repeating: .seconds(1))
printer.activate()
order.setEventHandler {
let (b1, b2) = (Int.random(in: 0..<bucks.count), Int.random(in: 0..<bucks.count))
let (v1, v2) = (bucks[b1], bucks[b2])
guard v1 != v2 else {
return
}
if v1 > v2 {
bucks.transfer(amount: (v1 - v2) / 2, from: b1, to: b2)
} else {
bucks.transfer(amount: (v2 - v1) / 2, from: b2, to: b1)
}
}
order.schedule(deadline: .now(), repeating: .milliseconds(5))
order.activate()
chaos.setEventHandler {
let (b1, b2) = (Int.random(in: 0..<bucks.count), Int.random(in: 0..<bucks.count))
bucks.transfer(amount: Int.random(in: 0..<(bucks[b1] + 1)), from: b1, to: b2)
}
chaos.schedule(deadline: .now(), repeating: .milliseconds(5))
chaos.activate()
dispatchMain()</lang>
{{out}}
<pre>[21, 39, 40, 20] = 120
[14, 28, 46, 32] = 120
[25, 17, 38, 40] = 120
[5, 46, 69, 0] = 120
[22, 52, 24, 22] = 120
[11, 70, 20, 19] = 120
[18, 19, 46, 37] = 120</pre>
=={{header|Tcl}}==
|