Atomic updates: Difference between revisions

Add Swift
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}}==