I need to exchange some variables across different processes, and try this via shared memory. The following code is the simplified version of this attempt. The program works as expected, but I want to make sure that the exchange does not only work because of luck.
My main question is, is it sufficient to declare all pointers as volatile, in order to make sure the compiler can't optimize away the memory reads? Or do I need to insert some additional synchronize commands?
#include <sys/mman.h>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <type_traits>
struct Exchange
{
int x;
};
int main()
{
int fd = open("/dev/shm/foobar", O_RDWR | O_CREAT, 0600);
if(fd == -1)
{
std::cerr << "Open failed\n";
return 1;
}
if(ftruncate(fd, sizeof(Exchange)))
{
close(fd);
std::cerr << "Resize failed\n";
return 1;
}
auto xch = static_cast<volatile Exchange*>(
mmap(0, sizeof(Exchange),
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, 0));
if(!xch)
{
std::cerr << "no mapping\n";
return 1;
}
xch->x=23;
while(1)
{
// Do I need to insert some sync instruction here?
std::cout << xch->x << std::endl;
xch->x++;
msync((void*)(xch), sizeof(*xch), MS_SYNC);
sleep(1);
}
}