1

Is there a memory model specification for POSIX shared memory (across processes)?

I'm hoping that there's something to comparable to the C++ memory model, in order to answer questions like the following:

  1. Is there a definition of a data race?
  2. Are data races undefined behavior (as in C++)?
  3. Is there something to constrain memory visibility order across processes? I know that a pthread_mutex can be put in shared memory and used by multiple processes, but does that induce a happens before relation?
  4. Do memory barriers play a roll?
Daniel Ricketts
  • 447
  • 2
  • 8
  • 1
    So, because POSIX standard is available online for free, you did do your own research. So what have you found out? – KamilCuk Jun 27 '20 at 17:56
  • I do not understand last two points. `Is there something to constrain memory visibility order across processes?` Is there something that actually allows you to read memory from other process? I do not understand - what exactly do you have in mind with the word "contrain"? `but does that induce a happens before relation?` How else would you use that mutex? `Do memory barriers play a roll?` A roll in what exactly? A memory barrier is a specific cpu instruction, I wouldn't expect POSIX to get into any hardware specific details. – KamilCuk Jun 27 '20 at 18:20
  • Possibly relevant: https://stackoverflow.com/questions/18321244/is-c11-atomict-usable-with-mmap – Paul Sanders Jun 27 '20 at 18:28
  • On linux a POSIX posix shared memory is just a mapping of the same physical memory, exactly as is the case for the entire address space of two threads, so the same memory semantic will apply. – Oliv Jun 27 '20 at 18:35
  • @KamilCuk Re: "I do not understand - what exactly do you have in mind with the word "contrain"?" The C++ memory model (https://en.cppreference.com/w/cpp/atomic/memory_order) states "Absent any constraints on a multi-core system, when multiple threads simultaneously read and write to several variables, one thread can observe the values change in an order different from the order another thread wrote them." It then describes constraints that can be added to a program to ensure that a thread sees memory changes in a certain order. Is there a similar mechanism for memory shared between processes? – Daniel Ricketts Jun 27 '20 at 18:54
  • @Oliv Different programming languages have different memory models. Does that mean that the memory semantics for POSIX shared memory depends on the choice of programming language? That would be great. I personally find the C++ memory model hard enough to understand on its own. Understanding its interaction with a different cross-process memory model would make my head explode. – Daniel Ricketts Jun 27 '20 at 19:01
  • @DanielRicketts Yes this will depend on the programming language. You can expect that every thing that is applicable to the memory shared by threads will be applicable to posix shared memory. With the provision that posix shared memory is always just a memory mapping. On linux this is the case. – Oliv Jun 27 '20 at 19:08
  • @DanielRicketts Just verify that in the posix specification posix shared memory is required to be mapped memory (it would be very surprising if it were not). If this is the case, what is true on linux will be true on all posix compliant platforms. – Oliv Jun 27 '20 at 19:12
  • @Oliv It looks like shared memory is required to be mapped memory: https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_08_03_02. My one remaining concern is that C++ doesn't explicitly specify a cross-process memory model. Do you want to add this as an answer? – Daniel Ricketts Jun 27 '20 at 20:07
  • @DanielRicketts Only the interprocess synchronization through atomics or as you know pthread_mutex (futex system call) will work, after that all the c++ memory model is broken as the two process execute in different address space. – Oliv Jun 28 '20 at 08:01
  • @Oliv My concern was that a C++ compiler that detects a single-threaded program might be free to ignore certain synchronization instructions. This might be allowed if the C++ spec doesn't mention cross process shared memory in its memory model. However, I think such a compiler wouldn't be POSIX-compliant if it ignored pthread_mutex instructions (not sure about atomics). In any case, it seems like sharing memory across processes is not adequately covered by any standards, so one has to rely on certain implementation details like the ones described in your answer. – Daniel Ricketts Jun 28 '20 at 19:27
  • @DanielRicketts Honestly I did not think about such optimization. And I have no idea if they do so. On gcc, we compile only with "-lpthread", which is just a linker flag, so I imagine gcc does never optimize away synchronization instruction. Could such optimization happen with LTO?? – Oliv Jun 28 '20 at 19:32
  • @Oliv Unfortunately, I know almost nothing about compilers (I had to look up the meaning of LTO), so I have no idea if any compilers actually implement such an optimization. Maybe it would be possible with LTO, and based on my understanding, such an optimization would be "correct", at least according to the C++ memory model. Ignoring pthread_mutex instructions on a single-threaded programs might be considered a violation of the POSIX spec (https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_12), since it explicitly defines a thread of control as a thread or process. – Daniel Ricketts Jun 28 '20 at 19:42

1 Answers1

1

According to POSIX specification, a shared memory object is defined as

An object that represents memory that can be mapped concurrently into the address space of more than one process.

On platforms as Linux, the memory object when mapped is equivalent to an anonymous mapping: this is a mapping of the physical RAM (or swap memory) to the virtual address space of the process. This is what is usually the memory of any thread or process.

On such plateforms as Linux you can expect that low memory level synchronization primitive provided by atomic will provide interprocess synchronization. According to your search pthread_mutex will work (probably because they are only implement in term of a compare and exchange loop and the futex system call). But std::mutex may also be broken.

Nevertheless I do not see in the POSIX specification anything that would forbid shared memory to be backed by the file system. On such platform memory synchronization would be broken. But I suppose no such platform exists.

Oliv
  • 17,610
  • 1
  • 29
  • 72