Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dodikk/72348d8485ee893d408a13a20c4a79a2 to your computer and use it in GitHub Desktop.
Save dodikk/72348d8485ee893d408a13a20c4a79a2 to your computer and use it in GitHub Desktop.
Swift Atomic Operators
import Foundation
infix operator +=! { associativity right precedence 90 } // Int32 or Int64
infix operator -=! { associativity right precedence 90 } // Int32 or Int64
postfix operator ++! {} // Int32 or Int64
postfix operator --! {} // Int32 or Int64
infix operator |=! { associativity right precedence 90 } // UInt32
infix operator &=! { associativity right precedence 90 } // UInt32
infix operator ^=! { associativity right precedence 90 } // UInt32
infix operator =! { associativity right precedence 90 } // Int or Int32 or Int64 or UnsafeMutablePointer<Void>
// =! ensures that lhs doesn't change while computing rhs
// Use this if rhs is dependent on the current value of lhs
// Example: x =! x + y is equivalent to x +=! y
func +=!(inout lhs: Int64, rhs: Int64) -> Int64 {
return OSAtomicAdd64(rhs, &lhs)
}
func +=!(inout lhs: Int32, rhs: Int32) -> Int32 {
return OSAtomicAdd32(rhs, &lhs)
}
func -=!(inout lhs: Int64, rhs: Int64) -> Int64 {
return lhs +=! -rhs
}
func -=!(inout lhs: Int32, rhs: Int32) -> Int32 {
return lhs +=! -rhs
}
postfix func ++!(inout value: Int64) -> Int64 {
return OSAtomicIncrement64(&value)
}
postfix func ++!(inout value: Int32) -> Int32 {
return OSAtomicIncrement32(&value)
}
postfix func --!(inout value: Int64) -> Int64 {
return OSAtomicDecrement64(&value)
}
postfix func --!(inout value: Int32) -> Int32 {
return OSAtomicDecrement32(&value)
}
func |=!(inout lhs: UInt32, rhs: UInt32) -> UInt32 {
return UInt32(OSAtomicOr32(rhs, &lhs))
}
func &=!(inout lhs: UInt32, rhs: UInt32) -> UInt32 {
return UInt32(OSAtomicAnd32(rhs, &lhs))
}
func ^=!(inout lhs: UInt32, rhs: UInt32) -> UInt32 {
return UInt32(OSAtomicXor32(rhs, &lhs))
}
func =!(inout lhs: Int32, rhs: @autoclosure () -> Int32) -> Int32 {
var success: Bool
var newValue: Int32!
do {
let original = lhs;
newValue = rhs()
success = OSAtomicCompareAndSwap32(original, newValue, &lhs)
} while(!success);
return newValue
}
func =!(inout lhs: Int64, rhs: @autoclosure () -> Int64) -> Int64 {
var success: Bool
var newValue: Int64!
do {
let original = lhs;
newValue = rhs()
success = OSAtomicCompareAndSwap64(original, newValue, &lhs)
} while(!success);
return newValue
}
func =!(inout lhs: Int, rhs: @autoclosure () -> Int) -> Int {
var success: Bool
var newValue: Int!
do {
let original = lhs;
newValue = rhs()
success = OSAtomicCompareAndSwapLong(original, newValue, &lhs)
} while(!success);
return newValue
}
func =!(inout lhs: UnsafeMutablePointer<Void>, rhs: @autoclosure () -> UnsafeMutablePointer<Void>) -> UnsafeMutablePointer<Void> {
var success: Bool
var newValue: UnsafeMutablePointer<Void>!
do {
let original = lhs;
newValue = rhs()
success = OSAtomicCompareAndSwapPtr(original, newValue, &lhs)
} while(!success);
return newValue
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment