Protecting control dependencies with volatile_if()
Protecting control dependencies with volatile_if()
Posted Jun 20, 2021 0:08 UTC (Sun) by tialaramex (subscriber, #21167)In reply to: Protecting control dependencies with volatile_if() by Paf
Parent article: Protecting control dependencies with volatile_if()
Today, volatile is rightly imagined as a property of actions, not variables. "volatile write variable -> $address " => "Literally write this to memory, even though it seems as though we're never reading that memory and so needn't bother, I promise that's actually what must happen". "volatile read $address -> variable" => Literally read this from memory, even though it seems as though we already know the value, I promise that's actually what must be done". Whereas "volatile variable" is too vague.
On some hardware, there may be very fine memory mapping, such that you can actually read or write a smaller value than the natural machine word to special memory regions, maybe the normal word size is 32 bits, but for a small range of "memory" it actually matters whether you use the 16-bit move instruction or the 32-bit one because they behave differently. In some cases this gets finer than a single byte, maybe there's a flag in the bottom bit of address 0x0037 and you can actually read or write that single bit, from machine code and it has completely different behaviour from if you were to try to read or write the whole 0x0037 byte on that hardware.
So, because volatile is defined so openly in C, your compiler vendor can say OK, we make this compiler for this weird hardware, and we promise if you say that this is a _volatile_ byte pointer to 0x0037 and then you use |= 0x01 we will actually emit the machine code for the single bit write, even though that's not how it would be implemented for other occurrences of |= 0x01
But the language standard can't say anything about these platform specific details, so it just leaves that to your the compiler vendor, and with the exception of specialist compiler vendors who care very much about this stuff, the compiler vendor says as little about it as possible, hoping you will go away.
Probably what _ought_ to happen if C was designed from scratch today is that these platforms provide a special intrinsic function and if you actually need to poke the bottom bit of address 0x0037 you call some intrinsic like __foocorp_bit_poke(0x0037, 0, 1) and how that's actually implemented is only a problem for the platform compiler developer. Anybody who needs the intrinsic (e.g. someone porting Linux to the platform) uses it, everybody else is blissfully unaware. But at the time they just added this "volatile" qualifier to the C language as a dumping ground for all features about hardware memory reads/ writes and called it a day.