Backoff

public struct Backoff

Helper for implementing spin loops.

An example of a busy-wait loop. The current thread will efficiently spin, yielding control at appropriate times, until ready becomes true.

func waitUntil(_ ready: AtomicBool) {
    var backoff = Backoff()
    while !ready.load() {
        backoff.yield()
    }
}

let ready = AtomicBool(false)
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
    ready.store(true)
}

assert(ready.load() == false)
waitUntil(ready)
assert(ready.load() == true)

An example of retrying an operation until it succeeds.

func fetchMul(_ a: AtomicInt, by b: Int) -> Int {
    var backoff = Backoff()
    while true {
        let value = a.load()
        if a.compareExchangeWeak(value, value * b) == value {
            return value
        }
        backoff.spin()
    }
}

let a = AtomicInt(6)
assert(fetchMul(a, by: 7) == 6)
assert(a.load() == 42)
  • Declaration

    Swift

    @inlinable
    public init()
  • Declaration

    Swift

    @inlinable
    public mutating func reset()
  • Declaration

    Swift

    @discardableResult
    @inlinable
    public mutating func spin() -> Bool

    Return Value

    true if backoff completed and it is no longer useful to loop, indicating contention.

  • Declaration

    Swift

    @discardableResult
    @inlinable
    public mutating func yield() -> Bool

    Return Value

    true if backoff completed and it is no longer useful to loop, indicating contention.