203 lines
9.1 KiB
ReStructuredText
203 lines
9.1 KiB
ReStructuredText
Shared Memory Interfaces
|
|
************************
|
|
|
|
Shared memory interfaces are only available with the NuttX kernel build
|
|
(``CONFIG_BUILD_KERNEL=y``). These interfaces support user memory
|
|
regions that can be shared between multiple user processes. Shared
|
|
memory interfaces:
|
|
|
|
- :c:func:`shmget`
|
|
- :c:func:`shmat`
|
|
- :c:func:`shmctl`
|
|
- :c:func:`shmdt`
|
|
|
|
Functions
|
|
---------
|
|
|
|
.. c:function:: int shmget(key_t key, size_t size, int shmflg)
|
|
|
|
Returns the shared memory identifier associated with ``key``.
|
|
|
|
A shared memory identifier, associated data structure, and shared memory
|
|
segment of at least size bytes is created for ``key`` if one of the
|
|
following is true:
|
|
|
|
- The argument ``key`` is equal to ``IPC_PRIVATE``.
|
|
|
|
- The argument ``key`` does not already have a shared memory identifier
|
|
associated with it and ``(shmflg & IPC_CREAT)`` is non-zero.
|
|
|
|
Upon creation, the data structure associated with the new shared memory
|
|
identifier will be initialized as follows:
|
|
|
|
- The low-order nine bits of ``shm_perm.mode`` are set equal to the
|
|
low-order nine bits of ``shmflg``.
|
|
|
|
- The value of ``shm_segsz`` is set equal to the value of size.
|
|
|
|
- The values of ``shm_lpid``, ``shm_nattch``, ``shm_atime``, and
|
|
``shm_dtime`` are set equal to 0.
|
|
|
|
- The value of ``shm_ctime`` is set equal to the current time.
|
|
|
|
When the shared memory segment is created, it will be initialized with
|
|
all zero values.
|
|
|
|
:param key: The key that is used to access the unique shared memory
|
|
identifier.
|
|
:param size: The shared memory region that is created will be at least
|
|
this size in bytes.
|
|
:param shmflg: See ``IPC_*`` definitions in ``sys/ipc.h``. Only the
|
|
values ``IPC_PRIVATE`` or ``IPC_CREAT`` are supported.
|
|
|
|
:return: Upon successful completion, ``shmget()`` will return
|
|
a non-negative integer, namely a shared memory identifier; otherwise, it
|
|
will return -1 and set ``errno`` to indicate the error.
|
|
|
|
- ``EACCES``. A shared memory identifier exists for key but operation
|
|
permission as specified by the low-order nine bits of ``shmflg``
|
|
would not be granted.
|
|
- ``EEXIST``. A shared memory identifier exists for the argument key
|
|
but ``(shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)`` are non-zero.
|
|
- ``EINVAL``. A shared memory segment is to be created and the value of
|
|
size is less than the system-imposed minimum or greater than the
|
|
system-imposed maximum.
|
|
- ``EINVAL``. No shared memory segment is to be created and a shared
|
|
memory segment exists for key but the size of the segment associated
|
|
with it is less than size and size is not 0.
|
|
- ``ENOENT``. A shared memory identifier does not exist for the
|
|
argument key and ``(shmflg & IPC_CREAT)`` is 0.
|
|
- ``ENOMEM``. A shared memory identifier and associated shared memory
|
|
segment will be created, but the amount of available physical memory
|
|
is not sufficient to fill the request.
|
|
- ``ENOSPC``. A shared memory identifier is to be created, but the
|
|
system-imposed limit on the maximum number of allowed shared memory
|
|
identifiers system-wide would be exceeded.
|
|
|
|
**POSIX Deviations**
|
|
|
|
- The values of ``shm_perm.cuid``, ``shm_perm.uid``, ``shm_perm.cgid``,
|
|
and ``shm_perm.gid`` should be set equal to the effective user ID and
|
|
effective group ID, respectively, of the calling process. The NuttX
|
|
``ipc_perm`` structure, however, does not support these fields
|
|
because user and group IDs are not yet supported by NuttX.
|
|
|
|
.. c:function:: void *shmat(int shmid, FAR const void *shmaddr, int shmflg)
|
|
|
|
Attaches the shared memory
|
|
segment associated with the shared memory identifier specified by
|
|
``shmid`` to the address space of the calling process. The segment is
|
|
attached at the address specified by one of the following criteria:
|
|
|
|
- If ``shmaddr`` is a null pointer, the segment is attached at the
|
|
first available address as selected by the system.
|
|
|
|
- If ``shmaddr`` is not a null pointer and ``(shmflg & SHM_RND)`` is
|
|
non-zero, the segment is attached at the address given by
|
|
``(shmaddr - ((uintptr_t)shmaddr % SHMLBA))``.
|
|
|
|
- If ``shmaddr`` is not a null pointer and ``(shmflg & SHM_RND)`` is 0,
|
|
the segment is attached at the address given by ``shmaddr``.
|
|
|
|
- The segment is attached for reading if ``(shmflg & SHM_RDONLY)`` is
|
|
non-zero and the calling process has read permission; otherwise, if
|
|
it is 0 and the calling process has read and write permission, the
|
|
segment is attached for reading and writing.
|
|
|
|
:param shmid: Shared memory identifier
|
|
:param smaddr: Determines mapping of the shared memory region
|
|
:param shmflg: See ``SHM_*`` definitions in ``include/sys/shm.h``. Only
|
|
``SHM_RDONLY`` and ``SHM_RND`` are supported.
|
|
|
|
:return: Upon successful completion, ``shmat()`` will
|
|
increment the value of ``shm_nattch`` in the data structure associated
|
|
with the shared memory ID of the attached shared memory segment and
|
|
return the segment's start address. Otherwise, the shared memory segment
|
|
will not be attached, ``shmat()`` will return -1, and ``errno`` will be
|
|
set to indicate the error.
|
|
|
|
- ``EACCES``. Operation permission is denied to the calling process
|
|
- ``EINVAL``. The value of ``shmid`` is not a valid shared memory
|
|
identifier, the ``shmaddr`` is not a null pointer, and the value of
|
|
``(shmaddr -((uintptr_t)shmaddr % SHMLBA))`` is an illegal address
|
|
for attaching shared memory; or the ``shmaddr`` is not a null
|
|
pointer, ``(shmflg & SHM_RND)`` is 0, and the value of ``shmaddr`` is
|
|
an illegal address for attaching shared memory.
|
|
- ``EMFILE``. The number of shared memory segments attached to the
|
|
calling process would exceed the system-imposed limit.
|
|
- ``ENOMEM``. The available data space is not large enough to
|
|
accommodate the shared memory segment.
|
|
|
|
.. c:function:: int shmctl(int shmid, int cmd, FAR struct shmid_ds *buf)
|
|
|
|
Provides a variety of shared
|
|
memory control operations as specified by ``cmd``. The following values
|
|
for ``cmd`` are available:
|
|
|
|
- ``IPC_STAT``. Place the current value of each member of the
|
|
``shmid_ds`` data structure associated with ``shmid`` into the
|
|
structure pointed to by ``buf``.
|
|
|
|
- ``IPC_SET``. Set the value of the ``shm_perm.mode`` member of the
|
|
``shmid_ds`` data structure associated with ``shmid`` to the
|
|
corresponding value found in the structure pointed to by ``buf``.
|
|
|
|
- ``IPC_RMID``. Remove the shared memory identifier specified by
|
|
``shmid`` from the system and destroy the shared memory segment and
|
|
``shmid_ds`` data structure associated with it.
|
|
|
|
:param shmid: Shared memory identifier
|
|
:param cmd: ``shmctl()`` command
|
|
:param buf: Data associated with the ``shmctl()`` command
|
|
|
|
:return: Upon successful completion, ``shmctl()`` will return
|
|
0; otherwise, it will return -1 and set ``errno`` to indicate the error.
|
|
|
|
- ``EACCES``. The argument ``cmd`` is equal to ``IPC_STAT`` and the
|
|
calling process does not have read permission.
|
|
- ``EINVAL``. The value of ``shmid`` is not a valid shared memory
|
|
identifier, or the value of ``cmd``\ is not a valid command.
|
|
- ``EPERM``. The argument ``cmd`` is equal to ``IPC_RMID`` or
|
|
``IPC_SET`` and the effective user ID of the calling process is not
|
|
equal to that of a process with appropriate privileges and it is not
|
|
equal to the value of ``shm_perm.cuid`` or ``shm_perm.uid`` in the
|
|
data structure associated with ``shmid``.
|
|
- ``EOVERFLOW``. The ``cmd`` argument is ``IPC_STAT`` and the ``gid``
|
|
or ``uid`` value is too large to be stored in the structure pointed
|
|
to by the ``buf`` argument.
|
|
|
|
**POSIX Deviations**
|
|
|
|
- ``IPC_SET``. Does not set the ``shm_perm.uid`` or
|
|
``shm_perm.gid``\ members of the ``shmid_ds`` data structure
|
|
associated with ``shmid`` because user and group IDs are not yet
|
|
supported by NuttX
|
|
- ``IPC_SET``. Does not restrict the operation to processes with
|
|
appropriate privileges or matching user IDs in ``shmid_ds`` data
|
|
structure associated with ``shmid``. Again because user IDs and
|
|
user/group privileges are are not yet supported by NuttX
|
|
- ``IPC_RMID``. Does not restrict the operation to processes with
|
|
appropriate privileges or matching user IDs in ``shmid_ds`` data
|
|
structure associated with ``shmid``. Again because user IDs and
|
|
user/group privileges are are not yet supported by NuttX
|
|
|
|
.. c:function:: int shmdt(FAR const void *shmaddr)
|
|
|
|
Detaches the shared memory
|
|
segment located at the address specified by ``shmaddr`` from the address
|
|
space of the calling process.
|
|
|
|
:param shmid: Shared memory identifier
|
|
|
|
:return: Upon successful completion, ``shmdt()`` will
|
|
decrement the value of ``shm_nattch`` in the data structure associated
|
|
with the shared memory ID of the attached shared memory segment and
|
|
return 0.
|
|
|
|
Otherwise, the shared memory segment will not be detached, ``shmdt()``
|
|
will return -1, and ``errno`` will be set to indicate the error.
|
|
|
|
- ``EINVAL``. The value of ``shmaddr`` is not the data segment start
|
|
address of a shared memory segment.
|
|
|