Open System Services Porting Guide (G06.29+, H06.06+, J06.03+)
Standards Are Used” (page 24). When porting code that uses extensions, use functional equivalents
from the POSIX standards to avoid propagating extensions to the OSS environment.
Memory Mapping
Mapped files provide a mechanism for a process to access files by directly incorporating file data
into the address space of the process. After a file is mapped into a process address space, the
data can be manipulated as memory. If more than one process maps a file, its contents are shared
among them. The mmap() function is specified in IEEE Std. 1003.1, 2004. The facility maps a
file or some other object into a range of virtual memory addresses. Some form of the function is
provided in most UNIX and Linux implementations. It is not part of the original POSIX.1 or XPG4
standards, and is not implemented in OSS.
Some programs use mmap() as a memory-management feature rather than a file-access feature.
The standard does not specify, but many implementations provide, “anonymous” mmap(), in which
the memory is mapped to a portion of the system swap space rather than a specific file.
Many UNIX programmers do not use this feature, but if your program does use mmap(), you will
have to redesign it to use an alternative mechanism.
A memory mapping can be characterized as temporary or permanent, and as shared or private.
In a temporary mapping, the initial values of the addressed memory are zero or undefined, and
the final values are discarded when the last process accessing the memory range unmaps it or
terminates. Such a mapping occurs with anonymous mmap() or mmap() using a temporary file
or a permanent file whose contents are treated as immaterial. In a permanent mapping, the data
resides in a file and persists: the initial values of the addressed memory are read from the file, and
(when the mapping is shared and write is enabled) final values are written to the file.
The standard states that in a private mapping, changes made by the process do not affect the
underlying object; in a shared mapping they do. The standard is less explicit about simultaneous
access by multiple processes, but typically the memory contents are shared, so mmap() is an
alternative to shmget() and shmat().
For a temporary, private mapping, a portable alternative is to use the malloc() function, assuming
there is enough address space available in the process heap.
For any temporary mapping, an alternative is to use the shm*() set of functions, or to use a
Guardian flat segment created with the SEGMENT_ALLOCATE_ or SEGMENT_ALLOCATE64_
procedure. Be aware that once a process has successfully called shmget(), the segment persists
until explicitly removed through the shmctl() function or the ipcrm utility; it is not removed by
termination of the last process sharing the segment. Both shm*() and (by default)
SEGMENT_ALLOCATE* create memory segments backed by the Kernel-Managed Swap Facility
(KMSF), so the mapping is anonymous.
For a permanent mapping, facilities similar to mmap() are provided by SEGMENT_ALLOCATE_
and SEGMENT_ALLOCATE64_, using a permanent swap file. The contents of the file are mapped
into the virtual address space of the process. By default, revised contents are updated to the file.
There are significant restrictions in memory mapping using Guardian memory segments compared
to mmap(), including:
• For a file-backed segment, the backing file must be in the Guardian file system—not an arbitrary
OSS regular file.
• A Guardian segment mapping begins at the start of the file; mmap() permits specifying an
offset into the file.
• The address range of the segment is contiguous and must remain so; the entire segment can
be de-allocated, or a Guardian segment can be resized smaller. By contrast, munmap() can
unmap a portion of a previously mapped range, and mmap() can implicitly unmap and remap
a portion of already-mapped memory.
• Any swap file must reside on the local NonStop node—not across a network.
86 OSS Porting Considerations