0

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);
    }
}
Rudi
  • 19,366
  • 3
  • 55
  • 77

1 Answers1

1

As you are already using msync in combination with MS_SYNC there should be no more need for further synchronization.

Essential man page parts:

msync() flushes changes made to the in-core copy of a file that was mapped into memory using mmap(2) back to the filesystem.


MS_SYNC: Requests an update and waits for it to complete.


For reading, also no more synchronization should be needed. Using msync the data gets written back to the file, which marks the file's page "dirty", and on the next read the file's page is read again by the mmap mechanism (with the updated value).


FURTHER INFO:

Community
  • 1
  • 1
Markus Weninger
  • 11,931
  • 7
  • 64
  • 137
  • 1
    Not sure this is right. This only relates to syncing the memory to disk. It doesn't prevent data race between processes sharing the same memory that is not privately mapped – Pete Jun 17 '20 at 05:32