shmat Subroutine

Purpose

Attaches a shared memory segment or a mapped file to the current process.

Library

Standard C Library (libc.a)

Syntax

#include <sys/shm.h>
void *shmat (SharedMemoryID, SharedMemoryAddress, SharedMemoryFlag)
int SharedMemoryID,  SharedMemoryFlag;
const void * SharedMemoryAddress;

Description

The shmat subroutine attaches the shared memory segment or mapped file specified by the SharedMemoryID parameter (returned by the shmget subroutine), or file descriptor specified by the SharedMemoryID parameter (returned by the openx subroutine) to the address space of the calling process.

A call to the shmat subroutine on a file descriptor that identifies an open shared memory object fails with EINVAL.

To learn more about the limits that apply to shared memory, see the Inter-Process Communication (IPC) Limits article in General Programming Concepts.

An extended shmat capability is available. If an environment variable EXTSHM=ON is defined then processes executing in that environment will be able to create and attach more than eleven shared memory segments.

The segments can be of size from 1 byte to 2 GB. The process can attach segments larger than 256MB into the address space for the size of the segment. Another segment could be attached at the end of the first one in the same 256MB segment region. The address at which a process can attach is at page boundaries - a multiple of SHMLBA_EXTSHM bytes. For segments larger than 256MB in size, if EXTSHM=ON is not defined, the address at which a process can attach is at 256MB boundaries, which is a multiple of SHMLBA bytes.

The segments can be of size from 1 byte to 256MB. The process can attach these segments into the address space for the size of the segment. Another segment could be attached at the end of the first one in the same 256MB segment region. The address at which a process can attach will be at page boundaries - a multiple of SHMLBA_EXTSHM bytes.

The maximum address space available for shared memory with or without the environment variable and for memory mapping is 2.75GB. An additional segment register "0xE" is available so that the address space is from 0x30000000 to 0xE0000000. However, a 256MB region starting from 0xD0000000 will be used by the shared libraries and is therefore unavailable for shared memory regions or mmapped regions.

On a 32-bit process running with the very large address space model has up to 3.25 GB of address space available for the shmat and mmap memory mappings. For a 32-bit process with the very large address space model, the address space available for mappings is from 0x30000000 to 0xFFFFFFFF. This extended address range applies to both extended shmat and standard shmat. For more information on how to use the very large address space model, see the Understanding the Very Large Address-Space Model article in General Programming Concepts.

There are some restrictions on the use of the extended shmat feature. These shared memory regions can not be used as I/O buffers where the unpinning of the buffer occurs in an interrupt handler. The restrictions on the use are the same as that of mmap buffers.

The smaller region sizes are not supported for mapping files. Regardless of whether EXTSHM=ON or not, mapping a file will consume at least 256MB of address space.

The SHM_SIZE shmctl command is not supported for segments created with EXTSHM=ON.

A segment created with EXTSHM=ON can be attached by a process without EXTSHM=ON. This will consume an area of address space that is a multiple of 256MB in size, regardless of the size of the shared memory region.

A segment created without EXTSHM=ON can be attached by a process with EXTSHM=ON. This will consume an area of address space that is a multiple of 256MB in size, regardless of the size of the shared memory region.

The environment variable provides the option of executing an application either with the additional functionality of attaching more than 11 segments when EXTSHM=ON, or the higher-performance access to 11 or fewer segments when the environment variable is not set.

The EXTSHM environment variable supports two additional values, EXTSHM=1SEG and EXTSHM=MSEG. All three options let users create more than 11 segments.

The EXTSHM=1SEG option defaults to the same behavior as EXTSHM=ON, which is to make memory mapped segments (type MMAP) of shared memories less than 256 MB, and SHMAT'ed segments (type WORKING) of shared memories greater than or equal to 256 MB. The EXTSHM=MSEG option creates memory mapped segments of all shared memories, regardless of size. This option provides better use of memory space.

Parameters

Item Description
SharedMemoryID Specifies an identifier for the shared memory segment.
SharedMemoryAddress Identifies the segment or file attached at the address specified by the SharedMemoryAddress parameter, as follows:
  • If the SharedMemoryAddress parameter is not equal to 0, and the SHM_RND flag is set in the SharedMemoryFlag parameter, the segment or file is attached at the next lower segment boundary. This address is given by (SharedMemoryAddress -(SharedMemoryAddress modulo SHMLBA_EXTSHM if environment variable EXTSHM=ON or SHMLBA if not). SHMLBA specifies the low boundary address multiple of a segment.
  • If the SharedMemoryAddress parameter is not equal to 0 and the SHM_RND flag is not set in the SharedMemoryFlag parameter, the segment or file is attached at the address given by the SharedMemoryAddress parameter. If this address does not point to a SHMLBA_EXTSHM boundary if the environment variable EXTSHM=ON or SHMLBA boundary if not, the shmat subroutine returns the value -1 and sets the errno global variable to the EINVAL error code. SHMLBA specifies the low boundary address multiple of a segment.
SharedMemoryFlag Specifies several options. Its value is either 0 or is constructed by logically ORing one or more of the following values:
SHM_COPY
Changes an open file to deferred update (see the openx subroutine). Included only for compatibility with previous versions of the operating system.
SHM_MAP
Maps a file onto the address space instead of a shared memory segment. The SharedMemoryID parameter must specify an open file descriptor in this case.
SHM_RDONLY
Specifies read-only mode instead of the default read-write mode.
SHM_RND
Rounds the address given by the SharedMemoryAddress parameter to the next lower segment boundary, if necessary.

The shmat subroutine makes a shared memory segment addressable by the current process. The segment is attached for reading if the SHM_RDONLY flag is set and the current process has read permission. If the SHM_RDONLY flag is not set and the current process has both read and write permission, it is attached for reading and writing.

If the SHM_MAP flag is set, file mapping takes place. In this case, the shmat subroutine maps the file open on the file descriptor specified by the SharedMemoryID onto a segment. The file must be a regular file. The segment is then mapped into the address space of the process. A file of any size can be mapped if there is enough space in the user address space.

When file mapping is requested, the SharedMemoryFlag parameter specifies how the file should be mapped. If the SHM_RDONLY flag is set, the file is mapped read-only. To map read-write, the file must have been opened for writing.

All processes that map the same file read-only or read-write map to the same segment. This segment remains mapped until the last process mapping the file closes it.

A mapped file opened with the O_DEFER update has deferred update. That is, changes to the shared segment do not affect the contents of the file resident in the file system until an fsync subroutine is issued to the file descriptor for which the mapping was requested. Setting the SHM_COPY flag changes the file to the deferred state. The file remains in this state until all processes close it. The SHM_COPY flag is provided only for compatibility with Version 2 of the operating system. New programs should use the O_DEFER open flag.

A file descriptor can be used to map the corresponding file only once. To map a file several times requires multiple file descriptors.

When a file is mapped onto a segment, the file is referenced by accessing the segment. The memory paging system automatically takes care of the physical I/O. References beyond the end of the file cause the file to be extended in page-sized increments. The file cannot be extended beyond the next segment boundary.

Attention: When a file is mapped, use of standard file system calls, such as truncate and write, are discouraged and might produce unexpected results, especially in a multithreaded environment. In particular, the write system call, upon completion, sets the size to the new end-of-file. Any shmat changes that occur concurrently past this new end-of-file might be lost. Concurrent change of the mapped region and use of the write system call are highly discouraged.

Return Values

When successful, the segment start address of the attached shared memory segment or mapped file is returned. Otherwise, the shared memory segment is not attached, the errno global variable is set to indicate the error, and a value of -1 is returned.

Error Codes

The shmat subroutine is unsuccessful and the shared memory segment or mapped file is not attached if one or more of the following are true:

Item Description
EACCES The calling process is denied permission for the specified operation.
EAGAIN The file to be mapped has enforced locking enabled, and the file is currently locked.
EBADF A file descriptor to map does not refer to an open regular file.
EEXIST The file to be mapped has already been mapped.
EINVAL The SHM_RDONLY and SHM_COPY flags are both set.
EINVAL The shmat subroutine was used with a file descriptor obtained from a call to the shm_open subroutine.
EINVAL The SharedMemoryID parameter is not a valid shared memory identifier.
EINVAL The SharedMemoryAddress parameter is not equal to 0, and the value of (SharedMemoryAddress - (SharedMemoryAddress modulo SHMLBA_EXTSHM if the environment variable EXTSHM=ON or SHMLBA if not ) points outside the address space of the process.
EINVAL The SharedMemoryAddress parameter is not equal to 0, the SHM_RND flag is not set in the SharedMemoryFlag parameter, and the SharedMemoryAddress parameter points to a location outside of the address space of the process.
EMFILE The number of shared memory segments attached to the calling process exceeds the system-imposed limit.
ENOMEM The available data space in memory is not large enough to hold the shared memory segment. ENOMEM is always returned if a 32-bit process tries to attach a shared memory segment larger than 2GB.
ENOMEM The available data space in memory is not large enough to hold the mapped file data structure.