Next | Prev | Up | Top | Contents | Index

The Segment Mapping Function mmap()

The mmap() function (see the mmap(2) reference page) creates shared or unshared segments of memory. The syntax and most basic features of mmap() are compatible with SVR4 and with POSIX 1003.1b. A few features of mmap() are unique to IRIX.

The mmap() function performs many kinds of mappings based on six parameters. The function prototype is:

void * mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off)
The function returns the base address of a new segment, or else -1 to indicate that no segment was created. The size of the new segment is len, rounded up to a page. An attempt to access data beyond that point causes a SIGBUS signal.


Describing the Mapped Object

Three of the mmap() parameters describe the object to be mapped into memory (which is the backing store of the new segment):

fd A file descriptor returned by open() or by the POSIX-defined function shm_open() function (see the open(2) and shm_open(2) reference pages). All mmap() calls require a file descriptor to define the backing store for the mapped segment. The descriptor can represent a file, or it can be based on a pseudo-file that represents kernel memory or a special device file.
offThe offset into the object represented by fd where the mapped data begins. When fd describes a disk file, off is an offset into the file. When fd describes memory, off is an address in that memory. off must be an integral multiple of the memory page size (see "Interrogating the Memory System").
lenThe number of bytes of data from fd to be mapped. The initial size of the segment is len, rounded up to a multiple of whole pages.


Describing the New Segment

Three parameters of mmap() describe the segment to be created:

addrNormally 0 to indicate that IRIX should pick a convenient base address, addr can specify a virtual address to be the base of the segment. See "Choosing a Segment Address".
protAccess control on the new segment. You use constants to specify a combination of read, write, and execute permission. The access control can be changed later (see "Changing Memory Protection").
flagsOptions on how the new segment is to be managed.

The elements of flags determine the way the segment behaves, and are as follows:

MAP_FIXED Take addr literally.
MAP_PRIVATE Changes to the mapped data are visible only to this process.
MAP_SHARED Changes to the mapped data are visible to all processes that map the same object.
MAP_AUTOGROWExtend the object when the process stores beyond its end (not POSIX)
MAP_LOCALMap is not visible to other processes in share group (not POSIX)
MAP_AUTORESRVDelay reserving swap space until a store is done (not POSIX).

The MAP_FIXED element of flags modifies the meaning of addr. Discussion of this is under "Choosing a Segment Address".

The MAP_AUTOGROW element of flags specifies what should happen when a process stores data past the current end of the segment (provided storing is allowed by prot). When flags contains MAP_AUTOGROW, the segment is extended with zero-filled space. Otherwise the initial len value is a permanent limit, and an attempt to store more than len bytes from the base address causes a SIGSEGV signal.

Two elements of flags specify the rules for sharing the segment between two address spaces when the segment is writable:

The difference between MAP_SHARED and MAP_PRIVATE is important only when the segment can be modified. When the prot argument does not include PROT_WRITE, there is no question of modifying or extending the segment, so the backing store is always the mapped object. However, the choice of MAP_SHARED or MAP_PRIVATE does affect how you lock the mapped segment into memory, if you do; see "Locking Program Text and Data".

Processes created with sproc() normally share a single address space, including mapped segments (see the sproc(2) reference page). However, if flags contains MAP_LOCAL, each new process created with sproc() receives a private copy of the mapped segment on a copy-on-write basis.

When the segment is based on a file or on /dev/zero (see "Mapping a Segment of Zeros"), mmap() normally defines all the pages in the segment. This includes allocating swap space for the pages of a segment based on /dev/zero. However, if flags contains MAP_AUTOGROW, the pages are not defined until they are accessed (see "Delayed and Immediate Space Definition").

Note: The MAP_LOCAL and MAP_AUTOGROW flag elements are IRIX features that are not portable to System V.


Next | Prev | Up | Top | Contents | Index