Using mmap() to allocate from typed memory objects
The POSIX way to allocate memory from typed memory is as follows:
- Use posix_typed_mem_open() to open the memory pool.
- Call mmap(), which gives you a virtual address.
- If you want to share that address, call shm_ctl(), specifying SHMCTL_PHYS and the physical address.
When you map in a typed memory object, you usually pass an offset to mmap(). The offset is the physical address of the location in the object where the mapping should commence. The offset is appropriate only when opening the object with a tflag of 0 or POSIX_TYPED_MEM_MAP_ALLOCATABLE. If you opened the typed memory object with POSIX_TYPED_MEM_ALLOCATE or POSIX_TYPED_MEM_ALLOCATE_CONTIG, a nonzero offset causes the call to mmap() to fail with an error of EINVAL.
The following general cases of allocations and mapping are considered for typed memory:
- If you specify POSIX_TYPED_MEM_ALLOCATE or POSIX_TYPED_MEM_ALLOCATE_CONTIG
when you call posix_typed_mem_open(), then when you call mmap(),
the typed memory pool is explicitly allocated from.
This case is just like a normal MAP_SHARED of an anonymous object:
mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, NOFD, 0);
The memory is allocated and not available for other allocations, but if you fork the process, the child processes can access it as well. The memory is released when the last mapping to it is removed.
Note that like somebody doing mem_offset() and then a MAP_PHYS to gain access to previously allocated memory, somebody else could open the typed memory object with POSIX_TYPED_MEM_MAP_ALLOCATABLE (or with no flags) and gain access to the same physical memory that way.
POSIX_TYPED_MEM_ALLOCATE_CONTIG is like
MAP_ANON | MAP_SHARED
, in that it causes a contiguous allocation. - If you specify POSIX_TYPED_MEM_MAP_ALLOCATABLE when you call posix_typed_mem_open(), then when you call mmap(), it creates a mapping to an object without allocation or deallocation. This is equivalent to a shared mapping to physical memory.
You should use only MAP_SHARED mappings, since a write to a MAP_PRIVATE mapping will (as normal) create a private copy for the process in normal anonymous memory.
If you specify no flag, or you specify POSIX_TYPED_MEM_MAP_ALLOCATABLE, the offset parameter to mmap() specifies the starting physical address in the typed memory region; if the typed memory region is discontiguous (multiple asinfo entries), the allowed offset values are also discontiguous and don't start at zero as they do for shared memory objects. If you specify a [paddr, paddr + size) region that falls outside the allowed addresses for the typed memory object, mmap() fails with ENXIO.