4 ms·
...and just to give a concrete example of a program that can silently "misrun" on x64 (via cacheline straddling - which is undefined behavior due to the misalig
by MaulingMonkey 7y ago
...and just to give a concrete example of a program that can silently "misrun" on x64 (via cacheline straddling - which is undefined behavior due to the misalignment, obviously):
#include <atomic>
#include <thread>
#include <iostream>
#include <cassert>
#include <cstdlib>
int main() {
constexpr size_t target_cacheline_bits = 6;
constexpr size_t target_cacheline_size = (1 << target_cacheline_bits); // 64 bytes
constexpr size_t target_cacheline_straddle_mask = (target_cacheline_size - 1);
char buffer[target_cacheline_size + sizeof(std::atomic<short>)];
std::atomic<short> & straddling = *(std::atomic<short> *)((size_t)buffer | target_cacheline_straddle_mask); // UB due to misalignment
straddling.store(1);
constexpr size_t N = 1000000;
std::thread t1([&](){
for (size_t i=0; i<N; ++i) {
straddling.store(i&1 ? 0x0001 : 0x0100, std::memory_order_relaxed);
}
});
std::thread t2([&](){
for (size_t i=0; i<N; ++i) {
const short value = straddling.load(std::memory_order_relaxed);
if (value != 0x0001 && value != 0x0100) {
std::cerr << "Got value: " << value << "\n";
std::exit(1);
}
}
});
t1.join();
t2.join();
}
https://wandbox.org/permlink/IK43Ou0NfAw9y7us https://wandbox.org/permlink/IK43Ou0NfAw9y7us
Sometimes this will run to completion without triggering anything. Other times the values "0" or "257" (0x0101) will appear in stderr. Feel free to raise "N", or exclude "0" from the error triggering case, to see more values.