blob: 42efdad0c7610b911c1cbb61874efb19a317903b [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Semaphore &mdash; Apache Mynewt latest documentation</title>
<link rel="shortcut icon" href="../../../_static/mynewt-logo-only-newt32x32.png"/>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/sphinx_theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/bootstrap-3.0.3.min.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/v2.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/restructuredtext.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/overrides.css" type="text/css" />
<link rel="index" title="Index"
href="../../../genindex.html"/>
<link rel="search" title="Search" href="../../../search.html"/>
<link rel="top" title="Apache Mynewt latest documentation" href="../../../index.html"/>
<link rel="up" title="Apache Mynewt Operating System Kernel" href="../mynewt_os.html"/>
<link rel="next" title="Event Queues" href="../event_queue/event_queue.html"/>
<link rel="prev" title="Mutex" href="../mutex/mutex.html"/>
<script src="../../../_static/js/modernizr.min.js"></script>
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="not-front page-documentation" role="document" >
<div id="wrapper">
<div class="container">
<div id="banner" class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="../../../_static/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.11.0, Apache NimBLE 1.6.0 </a> released September 7, 2023)
</div>
</div>
</div>
</div>
<header>
<nav id="navbar" class="navbar navbar-inverse" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li class="important">
<a href="/quick-start/">Quick Start</a>
</li>
<li>
<a href="/about/">About</a>
</li>
<li>
<a href="/talks/">Talks</a>
</li>
<li class="active">
<a href="/documentation/">Documentation</a>
</li>
<li>
<a href="/download/">Download</a>
</li>
<li>
<a href="/community/">Community</a>
</li>
<li>
<a href="/events/">Events</a>
</li>
</ul>
<!-- Search, Navigation and Repo links -->
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
</nav>
</header>
<!-- STARTS MAIN CONTENT -->
<div id="main-content">
<div id="breadcrumb">
<div class="container">
<a href="/documentation/">Docs</a> /
<a href="../../os_user_guide.html">OS User Guide</a> /
<a href="../mynewt_os.html">Apache Mynewt Operating System Kernel</a> /
Semaphore
<div class="sourcelink">
<a href="https://github.com/apache/mynewt-core/edit/master/docs/os/core_os/semaphore/semaphore.rst" class="icon icon-github"
rel="nofollow"> Edit on GitHub</a>
</div>
</div>
</div>
<!-- STARTS CONTAINER -->
<div class="container">
<!-- STARTS .content -->
<div id="content" class="row">
<!-- STARTS .container-sidebar -->
<div class="container-sidebar col-xs-12 col-sm-3">
<div id="docSidebar" class="sticky-container">
<div role="search" class="sphinx-search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search documentation" class="search-documentation" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<!-- Note: only works when deployed -->
<select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest" selected>
Version: latest
</option>
<option value="/v1_11_0" >
Version: 1.11.0
</option>
<option value="/v1_10_0" >
Version: 1.10.0
</option>
<option value="/v1_9_0" >
Version: 1.9.0
</option>
<option value="/v1_8_0" >
Version: 1.8.0
</option>
<option value="/v1_7_0" >
Version: 1.7.0
</option>
<option value="/v1_6_0" >
Version: 1.6.0
</option>
<option value="/v1_5_0" selected="selected" >
Version: 1.5.0
</option>
<option value="/v1_4_0" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" >
Version: 0.9.0
</option>
</select>
<div class="region region-sidebar">
<div class="docs-menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../get_started/index.html">Setup &amp; Get Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../concepts.html">Concepts</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../tutorials/tutorials.html">Tutorials</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../external_links.html">Third-party Resources</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../os_user_guide.html">OS User Guide</a><ul class="current">
<li class="toctree-l2 current"><a class="reference internal" href="../mynewt_os.html">Kernel</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../context_switch/context_switch.html">Scheduler</a></li>
<li class="toctree-l3"><a class="reference internal" href="../task/task.html">Task</a></li>
<li class="toctree-l3"><a class="reference internal" href="../mutex/mutex.html">Mutex</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Semaphore</a></li>
<li class="toctree-l3"><a class="reference internal" href="../event_queue/event_queue.html">Event Queues</a></li>
<li class="toctree-l3"><a class="reference internal" href="../callout/callout.html">Callout</a></li>
<li class="toctree-l3"><a class="reference internal" href="../heap/heap.html">Heap</a></li>
<li class="toctree-l3"><a class="reference internal" href="../memory_pool/memory_pool.html">Memory Pools</a></li>
<li class="toctree-l3"><a class="reference internal" href="../mbuf/mbuf.html">Mbufs</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cputime/os_cputime.html">CPU Time</a></li>
<li class="toctree-l3"><a class="reference internal" href="../time/os_time.html">OS Time</a></li>
<li class="toctree-l3"><a class="reference internal" href="../sanity/sanity.html">Sanity</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/system_modules.html">System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/hal/hal.html">Hardware Abstraction</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/bootloader/bootloader.html">Secure Bootloader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/split/split.html">Split Images</a></li>
<li class="toctree-l2"><a class="reference internal" href="../porting/port_os.html">Porting Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/baselibc.html">Baselibc</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/drivers/driver.html">Drivers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/devmgmt/newtmgr.html">Device Management with Newt Manager</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/imgmgr/imgmgr.html">Image Manager</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/sysinitconfig/sysinitconfig.html">Compile-Time Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/fs/fs.html">File System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/fcb/fcb.html">Flash Circular Buffer</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/sensor_framework/sensor_framework.html">Sensor Framework</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/testutil/testutil.html">Test Utilities</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/json/json.html">JSON</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../network/index.html">BLE User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../newt/index.html">Newt Tool Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../newtmgr/index.html">Newt Manager Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mynewt_faq/index.html">Mynewt FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../misc/index.html">Appendix</a></li>
</ul>
</div>
</div>
</div>
<!-- ENDS STICKY CONTAINER -->
</div>
<!-- ENDS .container-sidebar -->
<div class="col-xs-12 col-sm-9">
<div class="alert alert-warning">
<p>
Version 1.5.0 is not the most recent version of the
Apache Mynewt documentation. Click <a href="/latest">here</a> to
read the latest version.
</p>
</div>
<div class="">
<div class="rst-content">
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="semaphore">
<h1>Semaphore<a class="headerlink" href="#semaphore" title="Permalink to this headline"></a></h1>
<p>A semaphore is a structure used for gaining exclusive access (much like
a mutex), synchronizing task operations and/or use in a
“producer/consumer” roles. Semaphores like the ones used by the myNewt
OS are called “counting” semaphores as they are allowed to have more
than one token (explained below).</p>
<div class="section" id="description">
<h2>Description<a class="headerlink" href="#description" title="Permalink to this headline"></a></h2>
<p>A semaphore is a fairly simple construct consisting of a queue for
waiting tasks and the number of tokens currently owned by the semaphore.
A semaphore can be obtained as long as there are tokens in the
semaphore. Any task can add tokens to the semaphore and any task can
request the semaphore, thereby removing tokens. When creating the
semaphore, the initial number of tokens can be set as well.</p>
<p>When used for exclusive access to a shared resource the semaphore only
needs a single token. In this case, a single task “creates” the
semaphore by calling <a class="reference internal" href="#c.os_sem_init" title="os_sem_init"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_sem_init()</span></code></a> with a value of one (1) for the
token. When a task desires exclusive access to the shared resource it
requests the semaphore by calling <a class="reference internal" href="#c.os_sem_pend" title="os_sem_pend"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_sem_pend()</span></code></a>. If there is a token
the requesting task will acquire the semaphore and continue operation.
If no tokens are available the task will be put to sleep until there is
a token. A common “problem” with using a semaphore for exclusive access
is called <em>priority inversion</em>. Consider the following scenario: a high
and low priority task both share a resource which is locked using a
semaphore. If the low priority task obtains the semaphore and then the
high priority task requests the semaphore, the high priority task is now
blocked until the low priority task releases the semaphore. Now suppose
that there are tasks between the low priority task and the high priority
task that want to run. These tasks will preempt the low priority task
which owns the semaphore. Thus, the high priority task is blocked
waiting for the low priority task to finish using the semaphore but the
low priority task cannot run since other tasks are running. Thus, the
high priority tasks is “inverted” in priority; in effect running at a
much lower priority as normally it would preempt the other (lower
priority) tasks. If this is an issue a mutex should be used instead of a
semaphore.</p>
<p>Semaphores can also be used for task synchronization. A simple example
of this would be the following. A task creates a semaphore and
initializes it with no tokens. The task then waits on the semaphore, and
since there are no tokens, the task is put to sleep. When other tasks
want to wake up the sleeping task they simply add a token by calling
<a class="reference internal" href="#c.os_sem_release" title="os_sem_release"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_sem_release()</span></code></a>. This will cause the sleeping task to wake up
(instantly if no other higher priority tasks want to run).</p>
<p>The other common use of a counting semaphore is in what is commonly
called a “producer/consumer” relationship. The producer adds tokens (by
calling <a class="reference internal" href="#c.os_sem_release" title="os_sem_release"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_sem_release()</span></code></a>) and the consumer consumes them by calling
<a class="reference internal" href="#c.os_sem_pend" title="os_sem_pend"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_sem_pend()</span></code></a>. In this relationship, the producer has work for the
consumer to do. Each token added to the semaphore will cause the
consumer to do whatever work is required. A simple example could be the
following: every time a button is pressed there is some work to do (ring
a bell). Each button press causes the producer to add a token. Each
token consumed rings the bell. There will exactly the same number of
bell rings as there are button presses. In other words, each call to
<a class="reference internal" href="#c.os_sem_pend" title="os_sem_pend"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_sem_pend()</span></code></a> subtracts exactly one token and each call to
<a class="reference internal" href="#c.os_sem_release" title="os_sem_release"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_sem_release()</span></code></a> adds exactly one token.</p>
</div>
<div class="section" id="api">
<h2>API<a class="headerlink" href="#api" title="Permalink to this headline"></a></h2>
<dl class="c function">
<dt id="c.os_sem_init">
<span class="target" id="group___o_s_sem_1ga8f44f453e0bb9447272d67bce13c9f34"></span><span class="pre">os_error_t</span> <code class="sig-name descname"><span class="pre">os_sem_init</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_sem" title="os_sem"><span class="pre">os_sem</span></a> <span class="pre">*</span><em><span class="pre">sem</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">tokens</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_sem_init" title="Permalink to this definition"></a><br /></dt>
<dd><p>Initialize a semaphore. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>os_error_t OS_INVALID_PARM Semaphore passed in was NULL. OS_OK no error. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">sem</span></code>: Pointer to semaphore tokens: # of tokens the semaphore should contain initially.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_sem_release">
<span class="target" id="group___o_s_sem_1ga909a7fa9280e8871cba64e3dce5d6768"></span><span class="pre">os_error_t</span> <code class="sig-name descname"><span class="pre">os_sem_release</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_sem" title="os_sem"><span class="pre">os_sem</span></a> <span class="pre">*</span><em><span class="pre">sem</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_sem_release" title="Permalink to this definition"></a><br /></dt>
<dd><p>Release a semaphore. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>os_error_t OS_INVALID_PARM Semaphore passed in was NULL. OS_OK No error </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">sem</span></code>: Pointer to the semaphore to be released</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_sem_pend">
<span class="target" id="group___o_s_sem_1gab224058f433cc1a54c92dfe0bde092d9"></span><span class="pre">os_error_t</span> <code class="sig-name descname"><span class="pre">os_sem_pend</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_sem" title="os_sem"><span class="pre">os_sem</span></a> <span class="pre">*</span><em><span class="pre">sem</span></em>, <a class="reference internal" href="../time/os_time.html#c.os_time_t" title="os_time_t"><span class="pre">os_time_t</span></a> <em><span class="pre">timeout</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_sem_pend" title="Permalink to this definition"></a><br /></dt>
<dd><p>os sem pend </p>
<p>Pend (wait) for a semaphore.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>os_error_t OS_INVALID_PARM Semaphore passed in was NULL. OS_TIMEOUT Semaphore was owned by another task and timeout=0 OS_OK no error. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">mu</span></code>: Pointer to semaphore. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">timeout</span></code>: Timeout, in os ticks. A timeout of 0 means do not wait if not available. A timeout of OS_TIMEOUT_NEVER means wait forever.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_sem_get_count">
<span class="target" id="group___o_s_sem_1gac83a58d5a5a64e0c1bfbadc2a0611539"></span><em class="property"><span class="pre">static</span></em> <em class="property"><span class="pre">inline</span></em> <span class="pre">uint16_t</span> <code class="sig-name descname"><span class="pre">os_sem_get_count</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_sem" title="os_sem"><span class="pre">os_sem</span></a> <span class="pre">*</span><em><span class="pre">sem</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_sem_get_count" title="Permalink to this definition"></a><br /></dt>
<dd><p>Get current semaphore’s count. </p>
</dd></dl>
<dl class="c struct">
<dt id="c.os_sem">
<span class="target" id="structos__sem"></span><em class="property"><span class="pre">struct</span> </em><code class="sig-name descname"><span class="pre">os_sem</span></code><a class="headerlink" href="#c.os_sem" title="Permalink to this definition"></a><br /></dt>
<dd><em>#include &lt;os_sem.h&gt;</em><p>Structure representing an OS semaphore. </p>
<div class="breathe-sectiondef docutils container">
<p class="breathe-sectiondef-title rubric" id="breathe-section-title-public-members">Public Members</p>
<dl class="c var">
<dt id="c.os_sem.sem_tokens">
<span class="target" id="structos__sem_1a2bd4c88720d5a9581fe7959c2a5db686"></span><span class="pre">uint16_t</span> <code class="sig-name descname"><span class="pre">sem_tokens</span></code><a class="headerlink" href="#c.os_sem.sem_tokens" title="Permalink to this definition"></a><br /></dt>
<dd><p>Number of tokens. </p>
</dd></dl>
</div>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="rst-footer-buttons row" role="navigation" aria-label="footer navigation">
<a href="../event_queue/event_queue.html" class="btn btn-neutral float-right" title="Event Queues" accesskey="n">Next: Event Queues <span class="fa fa-arrow-circle-right"></span></a>
<a href="../mutex/mutex.html" class="btn btn-neutral" title="Mutex" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous: Mutex</a>
</div>
</div>
</div>
</div>
<!-- ENDS CONTENT SECTION -->
</div>
<!-- ENDS .content -->
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<img src="../../../_static/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt project logo are either
registered trademarks or trademarks of the Apache Software Foundation in the United States and other countries.
</small>
<a href="">
<img src="../../../_static/img/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
</div>
</div>
</footer>
</div>
<!-- ENDS #wrapper -->
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'latest',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
LINK_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/bootstrap-3.0.3.min.js"></script>
<script type="text/javascript" src="../../../_static/js/affix.js"></script>
<script type="text/javascript" src="../../../_static/js/main.js"></script>
</body>
</html>