Hi,
Put simply, are reading and writing to Bools both atomic operations in Swift (3)?
you don't get a guarantee for that as Swift at the moment lacks both, a memory and a concurrency model.
Obviously, something reading and then assigning assuming the value doesn't change between is not correct, but would something like the following be fine:
var myBool = false
// Thread 1
while true {
if randomEvent() {
myBool = true
}
}
// Thread 2
while true {
if myBool {
print("Was set to true")
} else {
print("Not set")
}
}
I understand that in thread 2, the value of myBool can change between the check and the print statements, but that's fine. What I want to confirm for my team is that `myBool` can never be in some weird "third" state?
As far as I know, you don't get a guarantee for that. But worse (and just like in C/C++/...) you most importantly don't get the guarantee that Thread 2 will ever see the change of Thread 1. The compiler could also optimise the code in Thread 2 to
while true {
// if false {
// print("Was set to true")
// } else {
print("Not set")
// }
}
ie. the compiler could 'prove' that `myBool` is never written (legally) and therefore delete all the code that assumes myBool != false.
I'm not saying the compiler is doing this today but AFAIK it could do so if it wanted.
From what I can tell, behind the scenes, Bool uses a Builtin.Int1 for storage. I can't find the definition for this type anywhere so I can't check what it is really doing. My assumption is that it uses something like a C++ unsigned char behind the scenes, which would be fine with the above code on x86 and ARM as far as I'm aware.
In C/C++ you'd need the new _Atomic variables to get that guarantee.
[...]
Again, I'm not saying the compiler does do that but AFAIK it could do so legally. But one of the compiler people can answer these questions much better than I can.
Cheers,
Johannes