| <!-- |
| 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.19: https://docutils.sourceforge.io/" /> |
| |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>Signaling Events from Interrupt Handlers — 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/sphinx_collapse.css" /> |
| <link rel="stylesheet" type="text/css" href="../_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.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/design-tabs.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="Signaling Semaphores and Priority Inheritance" href="signaling_sem_priority_inheritance.html" /> |
| <link rel="prev" title="Run NuttX on Renode" href="renode.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"><a class="reference internal" href="../components/index.html">OS Components</a></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="../debugging/index.html">Debugging</a></li> |
| <li class="toctree-l1 current"><a class="reference internal" href="index.html">Guides</a><ul class="current"> |
| <li class="toctree-l2"><a class="reference internal" href="nfs.html">NFS Client How-To</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="nix_flake.html">Nix Flake for Reproducible Development</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="usbtrace.html">USB Device Trace</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="simulator.html">Simulator</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="rndis.html">How to use RNDIS</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="drivers.html">Drivers</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="cpp_cmake.html">C++ Example using CMake</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="pysimcoder.html">pysimCoder integration with NuttX</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="customboards.html">Custom Boards How-To</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="customapps.html">Custom Apps How-to</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="citests.html">Running CI Test Locally</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="zerolatencyinterrupts.html">High Performance: Zero Latency Interrupts, Maskable Nested Interrupts</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="fortify.html">Fortify</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="nestedinterrupts.html">Nested Interrupts</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="ofloader.html">Open Flash Loader</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="testingtcpip.html">Testing TCP/IP Network Stacks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="automounter.html">Auto-Mounter</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="stm32nullpointer.html">STM32 Null Pointer Detection</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="stm32ccm.html">STM32 CCM Allocator</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="etcromfs.html">etc romfs</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="thread_local_storage.html">Thread Local Storage</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="devicetree.html">Device Tree</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="changing_systemclockconfig.html">Changing the System Clock Configuration</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="usingkernelthreads.html">Using Kernel Threads</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="armv7m_runtimestackcheck.html">ARMv7-M Run Time Stack Checking</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="include_files_board_h.html">Including Files in board.h</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="specialstuff_in_nuttxheaderfiles.html">Why can’t I put my special stuff in NuttX header files?</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="kernel_threads_with_custom_stacks.html">Kernel Threads with Custom Stacks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="versioning_and_task_names.html">Versioning and Task Names</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="logging_rambuffer.html">Logging to a RAM Buffer</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="ipv6.html">IPv6</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="integrate_newlib.html">Integrating with Newlib</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="protected_build.html">NuttX Protected Build</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="platform_directories.html">Platform Directories</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="port_drivers_to_stm32f7.html">Porting Drivers to the STM32 F7</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="semihosting.html">Semihosting</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="renode.html">Run NuttX on Renode</a></li> |
| <li class="toctree-l2 current"><a class="current reference internal" href="#">Signaling Events from Interrupt Handlers</a><ul> |
| <li class="toctree-l3"><a class="reference internal" href="#best-way-to-wake-multiple-threads-from-interrupt">Best way to wake multiple threads from interrupt?</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#message-queues">Message Queues</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#semaphores">Semaphores</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#signals">Signals</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#poll"><code class="docutils literal notranslate"><span class="pre">poll()</span></code></a></li> |
| </ul> |
| </li> |
| <li class="toctree-l2"><a class="reference internal" href="signaling_sem_priority_inheritance.html">Signaling Semaphores and Priority Inheritance</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="smaller_vector_tables.html">Smaller Vector Tables</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="port.html">How to port</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="updating_release_system_elf.html">Updating a Release System with ELF Programs</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="partially_linked_elf.html">ELF Programs – With Symbol Tables</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="fully_linked_elf.html">ELF Programs – No Symbol Tables</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="building_nuttx_with_app_out_of_src_tree.html">Building NuttX with Applications Outside the Source Tree</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="building_uclibcpp.html">Building uClibc++</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="custom_app_directories.html">Custom Application Directories</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="multiple_nsh_sessions.html">Multiple NSH Sessions</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="nsh_network_link_management.html">NSH Network Link Management</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="ram_rom_disks.html">RAM Disks and ROM Disks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="reading_can_msgs.html">Reading CAN Messages</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="remove_device_drivers_nsh.html">Removing Device Drivers with NSH</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="rust.html">Rust in NuttX</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="optee.html">Interfacing with OP-TEE</a></li> |
| </ul> |
| </li> |
| <li class="toctree-l1"><a class="reference internal" href="../standards/index.html">Standards</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> |
| <li class="toctree-l1"><a class="reference internal" href="../_tags/tagsindex.html">Tags</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">Guides</a></li> |
| <li class="breadcrumb-item active">Signaling Events from Interrupt Handlers</li> |
| <li class="wy-breadcrumbs-aside"> |
| <a href="https://github.com/apache/nuttx/blob/master/Documentation/guides/signal_events_interrupt_handlers.rst" class="fa fa-github"> Edit on GitHub</a> |
| </li> |
| </ul> |
| <hr/> |
| </div> |
| <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> |
| <div itemprop="articleBody"> |
| |
| <section id="signaling-events-from-interrupt-handlers"> |
| <h1>Signaling Events from Interrupt Handlers<a class="headerlink" href="#signaling-events-from-interrupt-handlers" title="Permalink to this heading"></a></h1> |
| <div class="admonition warning"> |
| <p class="admonition-title">Warning</p> |
| <p>Migrated from |
| <a class="reference external" href="https://cwiki.apache.org/confluence/display/NUTTX/Signaling+Events+from+Interrupt+Handlers">https://cwiki.apache.org/confluence/display/NUTTX/Signaling+Events+from+Interrupt+Handlers</a></p> |
| </div> |
| <section id="best-way-to-wake-multiple-threads-from-interrupt"> |
| <h2>Best way to wake multiple threads from interrupt?<a class="headerlink" href="#best-way-to-wake-multiple-threads-from-interrupt" title="Permalink to this heading"></a></h2> |
| <blockquote> |
| <div><p>I want to make a character device driver that passes the same data to |
| all tasks that are reading it. It is not so important whether the data |
| is queued or if just latest sample is retrieved. Problem is just how to |
| wake up the waiting threads.</p> |
| </div></blockquote> |
| <p>At the most primitive level, a thread can be waiting for a semaphore, a signal, |
| or a message queue (not empty or not full). Then there are higher |
| level wrappers around these like mutexes, semaphores, poll waits, |
| etc. But under the hood those are the three fundamental wait |
| mechanisms. Any could be used to accomplish what you want.</p> |
| <p>In NuttX, some additional effort was put into the design of the signalling |
| side of each of the IPCs so that they could be easily used by interrupts |
| handlers. This behavior is unique to NuttX; POSIX says nothing about |
| interrupt handlers. As a result, we will be talking about primarily |
| non-portable OS interfaces.</p> |
| <blockquote> |
| <div><p>So far I’ve considered the following options:</p> |
| </div></blockquote> |
| <p>And you basically have gone through the list of wait mechanisms:</p> |
| </section> |
| <section id="message-queues"> |
| <h2>Message Queues<a class="headerlink" href="#message-queues" title="Permalink to this heading"></a></h2> |
| <blockquote> |
| <div><p>1) Open a message queue when the device is opened (a new queue for each |
| task) and keep them in a list. Post to a non-blocking endpoint of these |
| queues in the ISR. Read from a blocking endpoint in the device <code class="docutils literal notranslate"><span class="pre">read()</span></code>. |
| I would need to generate names for the message queues, as there doesn’t |
| seem to be anonymous message queues?</p> |
| </div></blockquote> |
| <p>When you start a project. It is a good idea to decide upon a common IPC |
| mechanism to base your design on. POSIX message queues are one good |
| choice to do that: Assign each thread a message queue and the <code class="docutils literal notranslate"><span class="pre">main()</span></code> |
| of each thread simply waits on the message queue. It is a good |
| architecture and used frequently.</p> |
| <p>However, I would probably avoid creating a lot of message queues just |
| to support the interrupt level signaling. There are other ways to do |
| that that do not use so much memory. So, if you have message queues, |
| use them. If not, keep it simple.</p> |
| <p>In this case, your waiting task will block on a call to <code class="docutils literal notranslate"><span class="pre">mq_receive()</span></code> |
| until a message is received. It will then wake up and can process |
| the message. In the interrupt handler, it will call <code class="docutils literal notranslate"><span class="pre">mq_send()</span></code> when |
| an event of interest occurs which will, in turn, wake up the waiting |
| task.</p> |
| <p>Advantages of the use of message queues in this case are that 1) you |
| can pass quite a lot of data in the message, and 2) it integrates |
| well in a message-based application architecture. A disadvantage |
| is that there is a limitation on the number of messages that can be |
| sent from an interrupt handler so it is possible to get data overrun |
| conditions, that is, more interrupt events may be received than can |
| be reported with the available messages.</p> |
| <p>This limitation is due to the fact that you cannot allocate memory |
| dynamically from an interrupt handler. Instead, interrupt handlers |
| are limited to the use of pre-allocated messages. The number of |
| pre-allocated messages is given by <code class="docutils literal notranslate"><span class="pre">CONFIG_PREALLOC_MQ_MSGS</span></code> + 8. |
| The <code class="docutils literal notranslate"><span class="pre">CONFIG_PREALLOC_MQ_MSGS</span></code> can be used either by normal tasking |
| logic or by interrupt level logic. The extra eight are an emergency |
| pool for interrupt handling logic only (that value is not currently |
| configurable).</p> |
| <p>If the task logic consumes all of the <code class="docutils literal notranslate"><span class="pre">CONFIG_PREALLOC_MQ_MSGS</span></code> messages, it |
| will fall back to dynamically allocating messages at some cost to |
| performance and deterministic behavior.</p> |
| <p>If the interrupt level consumes all of the <code class="docutils literal notranslate"><span class="pre">CONFIG_PREALLOC_MQ_MSGS</span></code> |
| messages, it will fall back and use the emergency pool of 8 |
| pre-allocated messages. If those are also exhausted, then the message |
| will not be sent and an interrupt is effectively lost.</p> |
| </section> |
| <section id="semaphores"> |
| <h2>Semaphores<a class="headerlink" href="#semaphores" title="Permalink to this heading"></a></h2> |
| <blockquote> |
| <div><p>2) Allocate a semaphore per each device open and keep them in a list. |
| Post the semaphores when new data is available in a shared buffer. |
| Read the data inside <code class="docutils literal notranslate"><span class="pre">sched_lock()</span></code>.</p> |
| </div></blockquote> |
| <p>If you don’t have an architecture that uses message queues, and all of |
| these threads are waiting only for the interrupt event and nothing else, |
| then signaling semaphores would work fine too. You are basically using |
| semaphores as condition variables in this case so you do have to be careful.</p> |
| <p>NOTE: You do not need multiple semaphores. You can do this with a single |
| semaphore. If the semaphore is used for this purpose then you initialize |
| it to zero:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">sem_init</span><span class="p">(</span><span class="o">&</span><span class="n">sem</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span> |
| <span class="n">sem_setprotocol</span><span class="p">(</span><span class="o">&</span><span class="n">sem</span><span class="p">,</span><span class="w"> </span><span class="n">SEM_PRIO_NONE</span><span class="p">);</span> |
| </pre></div> |
| </div> |
| <p><code class="docutils literal notranslate"><span class="pre">sem_setprotocol()</span></code> is a non-standard NuttX function that should be called |
| immediately after the <code class="docutils literal notranslate"><span class="pre">sem_init()</span></code>. The effect of this function call is to |
| disable priority inheritance for that specific semaphore. There should |
| then be no priority inheritance operations on this semaphore that is |
| used for signaling. See <a class="reference internal" href="signaling_sem_priority_inheritance.html"><span class="doc">Signaling Semaphores and Priority Inheritance</span></a> |
| for further information.</p> |
| <p>Since the semaphore is initialized to zero, each time that a thread joins |
| the group of waiting threads, the count is decremented. So a simple loop |
| like this would wake up all waiting threads:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="n">svalue</span><span class="p">;</span> |
| <span class="kt">int</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span> |
| |
| <span class="k">for</span><span class="w"> </span><span class="p">(;</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="p">)</span> |
| <span class="p">{</span> |
| <span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sem_getvalue</span><span class="p">(</span><span class="o">&</span><span class="n">sem</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">svalue</span><span class="p">);</span> |
| <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">svalue</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span> |
| <span class="w"> </span><span class="p">{</span> |
| <span class="w"> </span><span class="n">sem_post</span><span class="p">(</span><span class="o">&</span><span class="n">sem</span><span class="p">);</span> |
| <span class="w"> </span><span class="p">}</span> |
| <span class="w"> </span><span class="k">else</span> |
| <span class="w"> </span><span class="p">{</span> |
| <span class="w"> </span><span class="k">break</span><span class="p">;</span> |
| <span class="w"> </span><span class="p">}</span> |
| <span class="p">}</span> |
| </pre></div> |
| </div> |
| <p>NOTE: This use of <code class="docutils literal notranslate"><span class="pre">sem_getvalue()</span></code> is not portable. In many environments, |
| <code class="docutils literal notranslate"><span class="pre">sem_getvalue()</span></code> will not return negative values if there are waiters on |
| the semaphore.</p> |
| <p>The above code snippet is essentially what the NuttX |
| <code class="docutils literal notranslate"><span class="pre">pthread_cond_broadcast()</span></code> does (see <a class="reference external" href="https://github.com/apache/nuttx/blob/master/sched/pthread/pthread_condbroadcast.c">nuttx/sched/pthread_condbroadcast.c</a>). |
| In NuttX condition variables are really just wrappers around semaphores |
| that give them a few new properties. You could even call |
| <code class="docutils literal notranslate"><span class="pre">pthread_cond_broadcast()</span></code> from an interrupt handler: See |
| <a class="reference external" href="http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html">http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html</a> |
| for usage information.</p> |
| <p>Neither of the above mechanisms are portable uses of these interfaces. |
| However, there is no portable interface for communicating directly with |
| interrupt handlers.</p> |
| <p>If you want to signal a single waiting thread, there are simpler things |
| you an do. In the waiting task:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">semt_t</span><span class="w"> </span><span class="n">g_mysemaphore</span><span class="p">;</span> |
| <span class="k">volatile</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="n">g_waiting</span><span class="p">;</span> |
| <span class="p">...</span> |
| |
| <span class="n">sem_init</span><span class="p">(</span><span class="o">&</span><span class="n">g_mysemaphore</span><span class="p">);</span> |
| <span class="n">sem_setprotocol</span><span class="p">(</span><span class="o">&</span><span class="n">g_mysemaphore</span><span class="p">,</span><span class="w"> </span><span class="n">SEM_PRIO_NONE</span><span class="p">);</span> |
| <span class="p">...</span> |
| |
| <span class="n">flags</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">enter_critical_section</span><span class="p">();</span> |
| <span class="n">g_waiting</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">true</span><span class="p">;</span> |
| <span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">g_waiting</span><span class="p">)</span> |
| <span class="p">{</span> |
| <span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sem_wait</span><span class="p">(</span><span class="o">&</span><span class="n">g_mysemaphore</span><span class="p">);</span> |
| <span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="n">handler</span><span class="w"> </span><span class="n">errors</span><span class="w"> </span><span class="p">...</span> |
| <span class="p">}</span> |
| |
| <span class="n">leave_critical_section</span><span class="p">(</span><span class="n">flags</span><span class="p">);</span> |
| </pre></div> |
| </div> |
| <p>In the above code snippet, interrupts are disabled to set and test |
| <code class="docutils literal notranslate"><span class="pre">g_waiting</span></code>. Interrupts will, of course, be re-enabled automatically |
| and atomically while the task is waiting for the interrupt event.</p> |
| <p>Then in the interrupt handler</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">extern</span><span class="w"> </span><span class="n">semt_t</span><span class="w"> </span><span class="n">g_mysemaphore</span><span class="p">;</span> |
| <span class="k">extern</span><span class="w"> </span><span class="k">volatile</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="n">g_waiting</span><span class="p">;</span> |
| <span class="p">...</span> |
| |
| <span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">g_waiting</span><span class="p">)</span> |
| <span class="p">{</span> |
| <span class="w"> </span><span class="n">g_waiting</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">false</span><span class="p">;</span> |
| <span class="w"> </span><span class="n">sem_post</span><span class="p">(</span><span class="o">&</span><span class="n">g_mysemaphore</span><span class="p">);</span> |
| <span class="p">}</span> |
| </pre></div> |
| </div> |
| <p>An integer type counter could also be used instead of a type bool to |
| support multiple waitings. In that case, this is equivalent to the |
| case above using <code class="docutils literal notranslate"><span class="pre">sem_getvalue()</span></code> but does not depend on non-portable |
| properties of <code class="docutils literal notranslate"><span class="pre">sem_getvalue()</span></code>.</p> |
| <p>NOTE: There is possibility of improper interactions between the |
| semaphore when it is used for signaling and priority inheritance. |
| In this case, you should disable priority inheritance on the |
| signaling semaphore using <code class="docutils literal notranslate"><span class="pre">sem_setprotocol(SEM_PRIO_NONE)</span></code>. See |
| <a class="reference internal" href="signaling_sem_priority_inheritance.html"><span class="doc">Signaling Semaphores and Priority Inheritance</span></a> |
| for further information.</p> |
| </section> |
| <section id="signals"> |
| <h2>Signals<a class="headerlink" href="#signals" title="Permalink to this heading"></a></h2> |
| <blockquote> |
| <div><p>3) Store the thread id’s in a list when <code class="docutils literal notranslate"><span class="pre">read()</span></code> is called. Wake up the |
| threads using <code class="docutils literal notranslate"><span class="pre">sigqueue()</span></code>. Read the data from a shared buffer |
| inside <code class="docutils literal notranslate"><span class="pre">sched_lock()</span></code>.</p> |
| </div></blockquote> |
| <p>Signals would work fine too. Signals have a side-effect that is sometimes |
| helpful and sometimes a pain in the butt: They cause almost all kinds of |
| waits (<code class="docutils literal notranslate"><span class="pre">read()</span></code>, <code class="docutils literal notranslate"><span class="pre">sem_wait()</span></code>, etc.) to wake up and return an error with |
| <code class="docutils literal notranslate"><span class="pre">errno=EINTR</span></code>.</p> |
| <p>That is sometimes helpful because you can wake up a <code class="docutils literal notranslate"><span class="pre">recv()</span></code> or a <code class="docutils literal notranslate"><span class="pre">read()</span></code> |
| etc., detect the event that generated the signal, and do something |
| about it. It is sometimes a pain because you have to remember to |
| handle the <code class="docutils literal notranslate"><span class="pre">EINTR</span></code> return value even when you don’t care about it.</p> |
| <p>The POSIX signal definition includes some support that would make this |
| easier for you. This support is not currently implemented in NuttX. |
| The <code class="docutils literal notranslate"><span class="pre">kill()</span></code> interface for example |
| (<a class="reference external" href="http://pubs.opengroup.org/onlinepubs/009695399/functions/kill.html">http://pubs.opengroup.org/onlinepubs/009695399/functions/kill.html</a>) |
| supports this behavior:</p> |
| <p>“If pid is 0, sig will be sent to all processes (excluding an unspecified |
| set of system processes) whose process group ID is equal to the process |
| group ID of the sender, and for which the process has permission to send |
| a signal.</p> |
| <p>“If pid is -1, sig will be sent to all processes (excluding an unspecified |
| set of system processes) for which the process has permission to send that |
| signal.”</p> |
| <p>“If pid is negative, but not -1, sig will be sent to all processes (excluding |
| an unspecified set of system processes) whose process group ID is equal to |
| the absolute value of pid, and for which the process has permission to send |
| a signal.”</p> |
| <p>NuttX does not currently support process groups. But that might be a good |
| RTOS extension. If you and others think that would be useful I could |
| probably add the basics of such a feature in a day or so.</p> |
| </section> |
| <section id="poll"> |
| <h2><code class="docutils literal notranslate"><span class="pre">poll()</span></code><a class="headerlink" href="#poll" title="Permalink to this heading"></a></h2> |
| <blockquote> |
| <div><p>Is there some better way that I haven’t discovered?</p> |
| </div></blockquote> |
| <p>The obvious thing that you did not mention is <code class="docutils literal notranslate"><span class="pre">poll()</span></code>. See |
| <a class="reference external" href="http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html">http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html</a> . |
| Since you are writing a device driver, support for the <code class="docutils literal notranslate"><span class="pre">poll()</span></code> method |
| in your driver seems to be the natural solution. See the <code class="docutils literal notranslate"><span class="pre">drivers/</span></code> |
| directory for many examples, <code class="docutils literal notranslate"><span class="pre">drivers/pipes/pipe_common.c</span></code> for one. |
| Each thread could simply wait on <code class="docutils literal notranslate"><span class="pre">poll()</span></code>; when the event occurs the |
| driver could then wake up the set of waiters. Under the hood, this |
| is again just a set of <code class="docutils literal notranslate"><span class="pre">sem_post</span></code>’s. But it is also a very standard |
| mechanism.</p> |
| <p>In your case, the semantics of <code class="docutils literal notranslate"><span class="pre">poll()</span></code> might have to be bent just a |
| little. You might have to bend the meaning of some of the event |
| flags since they are all focused on data I/O events.</p> |
| <p>Another creative use of <code class="docutils literal notranslate"><span class="pre">poll()</span></code> for use in cases like this:</p> |
| <blockquote> |
| <div><p>That would be something great! PX4 project has that implemented somehow |
| (in C++), so maybe - if license permits - it could be ported to NuttX in |
| no time?</p> |
| <p><a class="reference external" href="https://pixhawk.ethz.ch/px4/dev/shared_object_communication">https://pixhawk.ethz.ch/px4/dev/shared_object_communication</a></p> |
| </div></blockquote> |
| <p>I don’t know a lot about this, but it might be worth looking into |
| if it matches your need.</p> |
| </section> |
| </section> |
| |
| |
| </div> |
| </div> |
| <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> |
| <a href="renode.html" class="btn btn-neutral float-left" title="Run NuttX on Renode" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> |
| <a href="signaling_sem_priority_inheritance.html" class="btn btn-neutral float-right" title="Signaling Semaphores and Priority Inheritance" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> |
| </div> |
| |
| <hr/> |
| |
| <div role="contentinfo"> |
| <p>© Copyright 2023, The Apache Software Foundation.</p> |
| </div> |
| |
| |
| |
| </footer> |
| </div> |
| </div> |
| </section> |
| </div> |
| <script> |
| jQuery(function () { |
| SphinxRtdTheme.Navigation.enable(true); |
| }); |
| </script> |
| |
| </body> |
| </html> |