blob: 2f5f7988094e0ffea1066ad09510c12f5fdc0a36 [file] [log] [blame]
<!--
Documentation/_templates/layout.html
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership. The
ASF licenses this file to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
-->
<!DOCTYPE html>
<html class="writer-html5" lang="en">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Shared Memory Support &mdash; NuttX latest documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/css/theme.css" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="shortcut icon" href="../../_static/favicon.ico"/>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/doctools.js"></script>
<script src="../../_static/sphinx_highlight.js"></script>
<script src="../../_static/clipboard.min.js"></script>
<script src="../../_static/copybutton.js"></script>
<script src="../../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<link rel="next" title="Syscall Layer" href="../syscall.html" />
<link rel="prev" title="Memory Management" href="index.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../../index.html" class="icon icon-home"> NuttX
</a>
<!-- this version selector is quite ugly, should be probably replaced by something
more modern -->
<div class="version-selector">
<select onchange="javascript:location.href = this.value;">
<option value="../../../latest" selected="selected">latest</option>
<option value="../../../10.0.0" >10.0.0</option>
<option value="../../../10.0.1" >10.0.1</option>
<option value="../../../10.1.0" >10.1.0</option>
<option value="../../../10.2.0" >10.2.0</option>
<option value="../../../10.3.0" >10.3.0</option>
<option value="../../../11.0.0" >11.0.0</option>
<option value="../../../12.0.0" >12.0.0</option>
<option value="../../../12.1.0" >12.1.0</option>
<option value="../../../12.2.0" >12.2.0</option>
<option value="../../../12.2.1" >12.2.1</option>
<option value="../../../12.3.0" >12.3.0</option>
<option value="../../../12.4.0" >12.4.0</option>
<option value="../../../12.5.0" >12.5.0</option>
<option value="../../../12.5.1" >12.5.1</option>
<option value="../../../12.6.0" >12.6.0</option>
<option value="../../../12.7.0" >12.7.0</option>
<option value="../../../12.8.0" >12.8.0</option>
<option value="../../../12.9.0" >12.9.0</option>
<option value="../../../12.10.0" >12.10.0</option>
<option value="../../../12.11.0" >12.11.0</option>
</select>
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Table of Contents</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../index.html">Home</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../introduction/index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../quickstart/index.html">Getting Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../contributing/index.html">Contributing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../introduction/inviolables.html">The Inviolable Principles of NuttX</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../platforms/index.html">Supported Platforms</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../index.html">OS Components</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../binfmt.html">Binary Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../drivers/index.html">Device Drivers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../nxflat.html">NXFLAT</a></li>
<li class="toctree-l2"><a class="reference internal" href="../nxgraphics/index.html">NX Graphics Subsystem</a></li>
<li class="toctree-l2"><a class="reference internal" href="../paging.html">On-Demand Paging</a></li>
<li class="toctree-l2"><a class="reference internal" href="../audio/index.html">Audio Subsystem</a></li>
<li class="toctree-l2"><a class="reference internal" href="../filesystem/index.html">NuttX File System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../libs/index.html">NuttX libraries</a></li>
<li class="toctree-l2"><a class="reference internal" href="../net/index.html">Network Support</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html">Memory Management</a><ul class="current">
<li class="toctree-l3 current"><a class="current reference internal" href="#">Shared Memory Support</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#prerequisites">Prerequisites</a></li>
<li class="toctree-l4"><a class="reference internal" href="#concepts">Concepts</a></li>
<li class="toctree-l4"><a class="reference internal" href="#relevant-header-files">Relevant header files</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="index.html#standard-memory-management-functions">Standard Memory Management Functions</a></li>
<li class="toctree-l3"><a class="reference internal" href="index.html#granule-allocator">Granule Allocator</a></li>
<li class="toctree-l3"><a class="reference internal" href="index.html#page-allocator">Page Allocator</a></li>
<li class="toctree-l3"><a class="reference internal" href="index.html#shared-memory-management">Shared Memory Management</a></li>
<li class="toctree-l3"><a class="reference internal" href="index.html#i-o-buffers">I/O Buffers</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../syscall.html">Syscall Layer</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tools/index.html"><code class="docutils literal notranslate"><span class="pre">/tools</span></code> Host Tools</a></li>
<li class="toctree-l2"><a class="reference internal" href="../arch/index.html">Architecture-Specific Code</a></li>
<li class="toctree-l2"><a class="reference internal" href="../boards.html">Boards Support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cmake.html">CMake Support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../openamp.html">OpenAMP Support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../video.html">Video Subsystem</a></li>
<li class="toctree-l2"><a class="reference internal" href="../crypto.html">Crypto API Subsystem</a></li>
<li class="toctree-l2"><a class="reference internal" href="../wireless.html">Wireless Subsystem</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../applications/index.html">Applications</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../implementation/index.html">Implementation Details</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference/index.html">API Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../faq/index.html">FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../guides/index.html">Guides</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../logos/index.html">NuttX Logos</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">NuttX</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="../index.html">OS Components</a></li>
<li class="breadcrumb-item"><a href="index.html">Memory Management</a></li>
<li class="breadcrumb-item active">Shared Memory Support</li>
<li class="wy-breadcrumbs-aside">
<a href="../../_sources/components/mm/shm.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="shared-memory-support">
<h1>Shared Memory Support<a class="headerlink" href="#shared-memory-support" title="Permalink to this heading"></a></h1>
<section id="prerequisites">
<h2>Prerequisites<a class="headerlink" href="#prerequisites" title="Permalink to this heading"></a></h2>
<p>These features must be enabled before shared memory support can be
provided:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_ADDRENV=y</span></code> - Support for per-task address environment using a
MMU.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_BUILD_KERNEL=y</span></code> - Support for protected kernel-/user-space memory
regions must be provided by the MMU.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_GRAN=y</span></code> - The granule allocation is the allocation underlying all
paged allocations.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_MM_PGALLOC=y</span></code> - Enables the physical page allocator</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_MM_PGSIZE</span></code> - Determines the size of one page that can be mapped by
the MMU.</p></li>
</ul>
<p>And then finally:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_MM_SHM=y</span></code> - Enables shared memory support</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_SHM_VBASE</span></code> - The virtual address of the beginning of the
shared memory region.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_SHM_MAXREGIONS</span></code> - The maximum number of regions that can
allocated for the shared memory space. This hard-coded value permits
static allocation of the shared memory data structures and serves no
other purpose. Default is 1.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_SHM_NPAGES</span></code> - The maximum number of pages that can allocated
for the shared memory region. Default is 1.</p></li>
</ul>
<p>The size of the virtual shared memory address space is then determined by
the product of the maximum number of regions, the maximum number of pages
per region, and the configured size of each page.</p>
</section>
<section id="concepts">
<h2>Concepts<a class="headerlink" href="#concepts" title="Permalink to this heading"></a></h2>
<p>Each process has a task group structure, struct task_group_s, that holds
information common to all threads in the group. If <code class="docutils literal notranslate"><span class="pre">CONFIG_MM_SHM=y</span></code>, then
this includes data structures for the per-process shared memory virtual
page allocator.</p>
<p>A memory region is accessed using:</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">shmget</span><span class="p">(</span><span class="kt">key_t</span><span class="w"> </span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">size</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">shmflg</span><span class="p">);</span>
</pre></div>
</div>
<p>by a lookup using internal shared memory data sets with key as the lookup
match value. On success, shmget returns the shared memory identifier for
the match – in this implementation that identifier is simply the table
index of the match.</p>
<p>If the memory region does not exist, it may also be created by shmget (if
the IPC_CREAT bit is set in the shmflag). When a shared memory region is
created, the following things happen:</p>
<ul class="simple">
<li><p>A new entry is set aside in the internal data set. The key value is
assigned to the entry and the table index is the new shared memory
identifier.</p></li>
<li><p>The requested size is rounded up to rounded up to full pages, each of
size <code class="docutils literal notranslate"><span class="pre">CONFIG_MM_PGSIZE</span></code>.</p></li>
<li><p>A set of physical pages are allocated and the physical address of
these pages is retained in the internal data set.</p></li>
</ul>
<p>Now the key maps to and shared memory identifier (the table index) and
the table index provides access to the list of physical pages making up
the shared memory region.</p>
<p>NOTE: An improved implementation my perform a “lazy” back up of the
physical memory, i.e., do not allocate the physical memory until the
memory is required, for example, when a page fault occurs when a
application tries to allocate the memory.</p>
<p>A shared memory region is destroyed via:</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">shmctl</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">shmid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">cmd</span><span class="p">,</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">shmid_ds</span><span class="w"> </span><span class="o">*</span><span class="n">buf</span><span class="p">);</span>
</pre></div>
</div>
<p>In order for a process to make use of the memory region, it must be
“attached” the process using:</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="n">FAR</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">shmat</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">shmid</span><span class="p">,</span><span class="w"> </span><span class="n">FAR</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">shmaddr</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">shmflg</span><span class="p">);</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">shmat()</span></code> returns the virtual address where the shared memory can be found
in the user process. Attaching the shared memory region involves the
following steps:</p>
<ul class="simple">
<li><p>Use the shmid as a table index to look up the mapping in the shared
memory internal data structures.</p></li>
<li><p>Allocate a virtual address spaces of the same size as the physical
address space using the per-process virtual shared memory virtual
page allocator that can be found in the calling process’s task group
structure.</p></li>
<li><p>Use platform specific interfaces to mapy the physical memory to the
selected virtual address space, and</p></li>
<li><p>Return the allocated virtual base address to the caller.</p></li>
</ul>
<p>The memory region can be detached from the user process using:</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">shmdt</span><span class="p">(</span><span class="n">FAR</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">shmaddr</span><span class="p">);</span>
</pre></div>
</div>
</section>
<section id="relevant-header-files">
<h2>Relevant header files<a class="headerlink" href="#relevant-header-files" title="Permalink to this heading"></a></h2>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">include/sys/shm.h</span></code> - Shared memory interface declarations</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">include/sys/ipc.h</span></code> - Provides additional definitions used by the shared
memory interfaces</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">include/nuttx/addrenv.h</span></code> - Defines the virtual address space of the
process.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">include/nuttx/pgalloc.h</span></code> - Page allocator interfaces</p></li>
<li><dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">mm/shm/shm.h</span></code> - Internal shared memory definitions. This includes the</dt><dd><p>definitions of the internal shared memory data structures.</p>
</dd>
</dl>
</li>
</ul>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="index.html" class="btn btn-neutral float-left" title="Memory Management" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="../syscall.html" class="btn btn-neutral float-right" title="Syscall Layer" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2023, The Apache Software Foundation.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>