Purpose
Controls
shared memory operations.
Library
Standard C Library (libc.a)
Description
The shmctl subroutine
performs a variety of shared-memory control operations as specified
by the Command parameter.
The following limits apply
to shared memory:
- Minimum shared-memory segment size is 64 GB for
64-bit applications.
- Maximum number of shared memory IDs is 131072.
Parameters
Item |
Description |
SharedMemoryID |
Specifies an identifier returned by the shmget subroutine. |
Buffer |
Indicates a pointer to the shmid_ds structure. The shmid_ds structure
is defined in the sys/shm.h file. |
Command |
The following commands are available:
- IPC_STAT
- Obtains status information about the shared memory segment identified
by the SharedMemoryID parameter. This information is stored
in the area pointed to by the Buffer parameter. The calling
process must have read permission to run this command. The shm_pagesize and shm_lba fields
of the shmid_ds data structure pointed to by the Buffer parameter
are not updated by this command.
- IPC_ SET
- Sets the user and group IDs of the owner as well as the access
permissions for the shared memory segment identified by the SharedMemoryID parameter.
This command sets the following fields:
shm_perm.uid /* owning user ID */
shm_perm.gid /* owning group ID */
shm_perm.mode /* permission bits only */
You must
have an effective user ID equal to root or to the value of the shm_perm.cuid or
shm_perm.uid field in the shmid_ds data structure
identified by the SharedMemoryID parameter.
- IPC_RMID
- Removes the shared memory identifier specified by the SharedMemoryID parameter
from the system and erases the shared memory segment and data structure
associated with it. This command is only executed by a process that
has an effective user ID equal either to that of superuser or
to the value of the shm_perm.uid or shm_perm.cuid field
in the data structure identified by the SharedMemoryID parameter.
- SHM_SIZE
- Sets the size of the shared memory segment to the value specified
by the shm_segsz field of the structure specified by the Buffer parameter.
This value can be larger or smaller than the current size. The limit
is the maximum shared-memory segment size. This command is only executed
by a process that has an effective user ID equal either to that of
a process with the appropriate privileges or to the value of the shm_perm.uid or shm_perm.cuid field
in the data structure identified by the SharedMemoryID parameter.
This command is not supported for regions created with the environment
variable EXTSHM=ON. This results in a return value of -1 with errno set
to EINVAL. Attempting to use the SHM_SIZE on a shared
memory region larger than 256MB or attempting to increase the size
of a shared memory region larger than 256MB results in a return value
of -1 with errno set to EINVAL.
|
|
- SHM_BSR
- Backs the shared memory region identified by the SharedMemoryID parameter
with barrier synchronization register (BSR) memory. BSR shared memory
can be used for efficiently implementing barrier synchronization constructs
that are commonly used in highly parallel workloads. The Buffer parameter
must be set to NULL when using this command. This command
can only be used by a process that has an effective user ID equal
to that of superuser or to the value of the shm_perm.uid or shm_perm.cuid
fields in the shmid_ds data structure identified by the SharedMemoryIDparameter.
A non-root user must have the CAP_BYPASS_RAC_VMM capability
in order to allocate BSR memory and PV_KER_RAC privilege if
using RBAC. If insufficient BSR memory is available to satisfy the
request, shmctl() will fail with errno set to ENOMEM.
In order to use BSR memory for a shared memory region, this command
must be used on the shared memory region immediately after it has
been created and before any process has attached to the shared memory
region. This command cannot be used with shared memory regions that
have been created with the SHM_PIN flag or shared memory regions
that have been locked with the SHM_LOCK shmctl() command.
This command also cannot be used on shared memory regions whose page
size has been changed with the SHM_PAGESIZE shmctl() command, as well
as shared memory regions created with the EXTSHM=ON environment
variable.
|
|
- SHM_PAGESIZE
- Sets the page size backing the shared memory segment identified
by the SharedMemoryID parameter. This command will set the
page size backing the specified shared memory segment to the value
of the shm_pagesize field of the shmid_ds structure
specified by the Buffer parameter. The shm_pagesize field
is interpreted as a page size in bytes. This command can only be
used by a process that has an effective user ID with permissions set
equal either to that of superuser or to the value of the shm_perm.uid or shm_perm.cuid field
in the shmid_ds data structure identified by the SharedMemoryID parameter.
In order to change the page size backing a shared memory segment,
this command must be used on the shared memory segment immediately
after it has been created and before any process has attached to the
shared memory segment. Also, this command must be used before pinning
the pages in a shared memory segment. Thus, this command cannot be
used with shared memory segments that have been created with the SHM_PIN flag
or shared memory segments that have been pinned with the SHM_LOCK
shmctl() command. This command cannot be used with shared memory
regions created with the EXTSHM=ON environment variable.
Note: A
system's supported page sizes can be queried by specifying the VM_GETPSIZES command
to the vmgetinfo() system call.
|
Command continued |
The following commands are available:
- SHM_LOCK
- Pins all of the pages in the shared memory segment identified
by the SharedMemoryID parameter. Pinning the pages in a shared
memory segment will ensure that page faults do not occur for memory
references to the shared memory region. This command can only be
used by a process that has an effective user ID equal to that of superuser
or to the value of the shm_perm.uid or shm_perm.cuid field
in the shmid_ds data structure identified by the SharedMemoryID parameter.
A non-superuser user must also have the CAP_BYPASS_RAC_VMM capability
in order to use this command. This command cannot be used with shared
memory regions created with the EXTSHM=ON environment variable
or shared memory regions created with the SHM_PIN flag. The
Buffer parameter must be set to NULL when using this command.
|
|
- SHM_UNLOCK
- Unpins all of the pages in the shared memory segment identified
by the SharedMemoryID parameter. This command can only be
used by a process that has an effective user ID equal either to that
of superuser or to the value of the shm_perm.uid or shm_perm.cuid field
in the shmid_ds data structure identified by the SharedMemoryID parameter.
This command will fail if called on shared memory segments created
with the SHM_PIN flag. Also, this command can only be used
when the specified shared memory segment is not attached by any process,
and there is no outstanding I/O to the shared memory segment. The
Buffer parameter must be set to NULL when using this command.
- SHM_GETLBA
- Obtains the minimum alignment of the address at which the shared
memory segment identified by the SharedMemoryID parameter can
be attached by the shmat() subroutine. This command will store
the minimum alignment in the shm_lba field of the shmid_ds struct
pointed to by the Buffer parameter. The alignment is reported in
bytes. The calling process must have read permission to a shared
memory region in order to use this command.
|
Return Values
When completed
successfully, the shmctl subroutine returns a value of 0. Otherwise,
it returns a value of -1 and the errno global variable is set
to indicate the error.
Error Codes
The shmctl subroutine
is unsuccessful if one or more of the following are true:
Item |
Description |
EACCES |
The Command parameter is equal to the IPC_STAT or SHM_GETLBA value
and read permission is denied to the calling process. |
EFAULT |
The Buffer parameter points to a location outside
the allocated address space of the process. |
EINVAL |
The SharedMemoryID parameter is not a valid shared
memory identifier. |
EINVAL |
The Command parameter is not a valid command. |
EINVAL |
The Command parameter is equal to the SHM_SIZE value
and the value of the shm_segsz field of the structure specified
by the Buffer parameter is not valid. |
EINVAL |
The Command parameter is equal to the SHM_SIZE, SHM_PAGESIZE, SHM_LOCK or SHM_BSR value
and the shared memory region was created with the environment variable EXTSHM=ON. |
EINVAL |
The Command parameter is equal to the SHM_PAGESIZE value
and the value of the shm_pagesize field of the structure
specified by the Buffer parameter is not supported. |
EINVAL |
The Command parameter is equal to SHM_UNLOCK,
and the specified shared memory segment was not previously locked
by a SHM_LOCK operation. |
EINVAL |
The Command parameter is equal to SHM_LOCK SHM_UNLOCK,
or SHM_BSR and the Buffer parameter is not NULL. |
EINVAL |
The Command parameter is equal to SHM_BSR,
and the shared memory region’s page size has previously been changed
via the SHM_PAGESIZE command. |
ENOMEM |
The Command parameter is SHM_BSR, and
there is insufficient BSR memory available to back the entire
shared memory segment. |
ENOMEM |
The Command parameter is equal to the SHM_SIZE value,
and the attempt to change the segment size is unsuccessful because
the system does not have enough memory. |
ENOMEM |
The Command parameter is SHM_LOCK, and
locking the pages in the specified shared memory segment would exceed
the limit on the amount of memory the calling process may lock. |
ENOMEM |
The Command parameter is SHM_PAGESIZE,
and there are insufficient pages of the specified page size to back
the entire shared memory segment. |
EOVERFLOW |
The Command parameter is IPC_STAT and
the size of the shared memory region is greater than or equal to 4G
bytes. This only happens with 32-bit programs. |
EPERM |
The Command parameter is IPC_RMID, SHM_SIZE, SHM_PAGESIZE, SHM_LOCK,
or SHM_UNLOCK, and the effective user ID of the calling process
is not equal to the value of the shm_perm.uid or shm_perm.cuid field
in the data structure identified by the SharedMemoryID parameter.
The effective user ID of the calling process is not the root user
ID. |
EPERM |
The Command parameter is SHM_PAGESIZE,
and the calling process does not have the appropriate privilege to
allocate pages of the specified page size. |
EPERM |
The Command parameter is SHM_LOCK SHM_UNLOCK,
or SHM_BSR and the calling process does not have the appropriate
privilege to perform the requested operation. |
EBUSY |
The Command parameter is SHM_LOCK or SHM_UNLOCK,
and the specified shared memory segment is currently being used for
I/O or is attached by one or more processes. |
EBUSY |
The Command parameter is SHM_PAGESIZE or SHM_BSR and
the specified shared memory segment has already been attached by one
or more processes or has been pinned via SHM_PIN or SHM_LOCK. |
Examples
The following
example allocates a 32MB shared memory region, changes the page size
for the shared memory region to 64K, and then pins all of the pages
in the shared memory region:
int id;
size_t shm_size;
struct shmid_ds shm_buf = { 0 };
psize_t psize_64k;
psize_64k = 64 * 1024;
/* Create a 32MB shared memory region */
shm_size = 32*1024*1024;
/* Allocate the shared memory region */
if ((id = shmget(IPC_PRIVATE, shm_size, IPC_CREAT)) < 0)
{
perror("shmget() failed");
return -1;
}
/* Use 64K pages for the shared memory region */
shm_buf.shm_pagesize = psize_64k;
if (shmctl(id, SHM_PAGESIZE, &shm_buf))
{
perror("shmctl(SHM_PAGESIZE) failed");
}
/* Pin all of the pages in the shared memory region */
if (shmctl(id, SHM_LOCK, NULL))
{
perror("shmctl(SHM_LOCK) failed");
}
The following example allocates a 16MB shared
memory region and determines the minimum alignment of the address
at which an application can shmat() the shared memory region:
int id;
size_t shm_size;
struct shmid_ds shm_buf = { 0 };
/* Create a 16MB shared memory region */
shm_size = 16*1024*1024;
/* Allocate the shared memory region */
if ((id = shmget(IPC_PRIVATE, shm_size, IPC_CREAT)) < 0)
{
perror("shmget() failed");
return -1;
}
/* Determine the address alignment requirements */
if (shmctl(id, SHM_GETLBA, &shm_buf))
{
perror("shmctl(SHM_GETLBA) failed");
}
else
{
printf("shmlba = %08llx\n", shm_buf.shm_lba);
}