[PATCH] user: Add a Languages section

Gedare Bloom gedare at rtems.org
Fri Oct 9 15:26:40 UTC 2020


On Thu, Oct 8, 2020 at 11:42 PM <chrisj at rtems.org> wrote:
>
> From: Chris Johns <chrisj at rtems.org>
>
> ---
>  user/index.rst           |   2 +
>  user/languages/c.rst     |  14 ++
>  user/languages/cpp.rst   | 312 +++++++++++++++++++++++++++++++++++++++
>  user/languages/index.rst |  21 +++
>  4 files changed, 349 insertions(+)
>  create mode 100644 user/languages/c.rst
>  create mode 100644 user/languages/cpp.rst
>  create mode 100644 user/languages/index.rst
>
> diff --git a/user/index.rst b/user/index.rst
> index a91aa55..32667f4 100644
> --- a/user/index.rst
> +++ b/user/index.rst
> @@ -42,6 +42,8 @@ RTEMS User Manual (|version|).
>      bld/index
>      bsps/index
>
> +    languages/index
> +
>      exe/index
>      testing/index
>      tracing/index
> diff --git a/user/languages/c.rst b/user/languages/c.rst
> new file mode 100644
> index 0000000..c3965eb
> --- /dev/null
> +++ b/user/languages/c.rst
> @@ -0,0 +1,14 @@
> +.. SPDX-License-Identifier: CC-BY-SA-4.0
> +
> +.. Copyright (C) 2020 Chris Johns <chrisj at rtems.org>
> +
> +.. index:: C
> +.. index:: C Programming Language
> +
> +C
> +=
> +.. index:: C
> +
> +RTEMS supports the C programming language.
> +
> +TBD.
> diff --git a/user/languages/cpp.rst b/user/languages/cpp.rst
> new file mode 100644
> index 0000000..8a8cb86
> --- /dev/null
> +++ b/user/languages/cpp.rst
> @@ -0,0 +1,312 @@
> +.. SPDX-License-Identifier: CC-BY-SA-4.0
> +
> +.. Copyright (C) 2020 Chris Johns <chrisj at rtems.org>
> +
> +.. index:: C++
> +.. index:: C++ Programming Language
> +
> +C++
> +===
> +.. index:: C++
> +
> +RTEMS supports the C++ programming language and its standard library. The
> +supported language versions are C++11, C++14, and C++17.

I'm curious, will C++98/C++03 compliant code work? I admit to being
completely out of touch with the C++ standard evolution.

> +
> +The C++ standard library provides a rich set of interfaces to support
> +multi-threaded programming. The Thread support library provides
> +``std::lock_guard`` as a means to manage ``std::mutex`` or similar objects
> +within a code block while execution remains within that block. The
> +``std::promise`` and ``std::future`` supports provides a controlled means for
> +threads to end, clean-up and return a status value of some type. The Atomic
> +operations library provdes a range of methods to atomically acess data as well
provides
access

> +as establish inter-thread synchronization and order non-atomic memory
> +accesses.
> +
> +The Thread support library maps to the RTEMS POSIX ``pthread`` interface and
> +the various sychronisation primatives such as mutual exclusion, condition
primitives

> +variables, and futures map to the high performance self-contained RTEMS
> +interface. These objects have a fast execution profile and their storage is
> +self-contained which means it does not have to be accounted for in the
> +configuration and work-space settings. C++ applications do not need to be
> +concerned about the number of locks being used and can implement fine grain
> +locking protocols.
> +
> +RTEMS Threads
> +-------------
> +
> +RTEMS provides an alternative Thread interface that lets you specify the
> +attributes of a thread when it is constructed. This is an extension to the
> +standard and is not based on any current or pending standards efforts. The
> +goal is to make the interface as close as possible to the existing standard to
> +minimise the impact on code being ported to RTEMS.
> +
> +The following compiler option must be used as the implementation uses the
> +``std::invoke`` call which is only available with C++17:
> +
> +.. code-block:: c++
> +
> +   --std=c++17
> +
> +The standard Thread support library specifies the thread constructor as:
> +
> +.. code-block:: c++
> +
> +   template< class Function, class... Args >
> +   explicit thread( Function&& f, Args&&... args );
> +
> +A thread constructed using this interface will have a default set of initial
> +values. An important atribute of a thread is the stack size and this cannot be
attribute

> +specified or altered with this interface. On Unix systems virtual memory can
> +be used to manage a thread's stack size and stack handling is more complex
> +when security is considered so manually controlling the stack size of a thread
> +is not needed or wanted.
> +
> +Attributes
> +^^^^^^^^^^
> +
> +The ``rtems::thread::attributes`` class provides an interface to control the
> +various attributes a thread has. The header file is:
> +
> +.. code-block:: c++
> +
> +   #include <rtems/thread.hpp>
> +
> +The default constructor initialises the attributes to the executing thread's
> +settings and the stack size is set to the configured minimum. You can then
> +alter the attributes to match the requirements of the new thread. It is easy
> +to set a name, stack size and priority:
> +
> +.. code-block:: c++
> +
> +   rtems::thread::attribute attr;
> +   attr.set_name("blue");
> +   attr.set_stack_size(16 * 1024);
> +   attr.set_priority(attr.get_priority() + 1);
> +
> +The ``update()`` method will read the attributes of the currently executing
> +thread and update the attribute instance making the call. The stack size is
> +not read and updated, there is no public interface in RTEMS to obtain the
comma splice, add a conjunction. I don't know if this should be
"because there is no"?

> +executing thread's stack size.
> +
> +An attribute object can be used to start a number of threads. The thread does
> +not referenced the attribute object once running.
reference

> +
> +An attribute object can be used to alter an attribute of a thread after it has
> +started by calling the ``commit()`` method. The ``commit()`` method does not
> +change the name or stack size of the executing thread.
> +
> +The attribute controls the scheduler policy, this is based on the POSIX
"policy based" (delete ", this is")

> +standard. The policies are:
> +
> +``sched_other``
> +  A CPU budget algorthim with timeslicing where the timeslice is reset.
s/algorthim/algorithm

> +
> +``sched_fifo``
> + A CPU budget algorthim with no timeslicing.
s/algorthim/algorithm

> +
> +``sched_roundrobin``
> +  A CPU budget algorthim with timeslicing where the timeslice is exhausted.
s/algorthim/algorithm

> +
> +``sched_sporadic``
> +  A CPU budget algorthim with a priorty, low priority and a replenish period.
s/algorthim/algorithm
s/priorty/priority

> +
> +Thread
> +^^^^^^
> +
> +The ``rtems::thread::thread`` class provides a thread interface to start a new
> +thread executing using the provided attributes. The header file is:
> +
> +.. code-block:: c++
> +
> +   #include <rtems/thread.hpp>
> +
> +The ``thread`` provides the same constructor as the C++ standard's Thread
> +support library:
> +
> +.. code-block:: c++
> +
> +   template<typename F, typename... Args>
> +   explicit thread (F&& func, Args&&... args);
> +
> +A thread can be run using the default parameters:
> +
> +.. code-block:: c++
> +
> +   #include <chrono>
> +   #include <iostream>
> +
> +   #include <rtems/thread.hpp>
> +
> +   static void wait_for(size_t seconds)
> +   {
> +     while (seconds--) {
> +       std::this_thread::sleep_for(std::chrono::seconds(1));
> +       std::cout << "Seconds: " << seconds << std::endl;
> +     }
> +   }
> +
> +   void example_1()
> +   {
> +     std::cout << "Start example 1" << std::endl;
> +
> +     rtems::thread::thread t(wait_for, 5);
> +     t.join();
> +
> +     std::cout << "End example 1" << std::endl;
> +   }
> +
> +The ``thread`` provides a way to construct a thread with attributes:
> +
> +.. code-block:: c++
> +
> +   template <typename A, typename F, typename ...Args,
> +             class = enable_if_attributes<A>>
> +   explicit thread (A&& attr, F&& func, Args&&... args);
> +
> +To create threads with different names and priorities use the ``attribute``
> +class and pass it to the ``thread`` class when constructing:
> +
> +.. code-block:: c++
> +
> +   #include <chrono>
> +   #include <iostream>
> +
> +   #include <rtems/thread.hpp>
> +
> +   static void wait_for(std::string me, size_t seconds, size_t announce)
> +   {
> +     size_t count = 0;
> +     while (count < seconds) {
> +       std::this_thread::sleep_for(std::chrono::seconds(1));
> +       if ((count % announce) == 0)
> +         std::cout << me << ": " << count << std::endl;
> +       count++;
> +     }
> +   }
> +
> +   void example_2()
> +   {
> +     std::cout << "Start example 2" << std::endl;
> +
> +     rtems::thread::attributes attr;
> +     attr.set_stack_size(16 * 1024);
> +
> +     attr.set_priority(100);
> +     attr.set_name("T1");
> +     rtems::thread::thread t1(attr, wait_for, "T1", 10, 1);
> +
> +     attr.set_priority(101);
> +     attr.set_name("T2");
> +     rtems::thread::thread t2(attr, wait_for, "T2", 10, 2);
> +
> +     attr.set_priority(attr.get_priority());
> +     attr.set_name("T3");
> +     rtems::thread::thread t3(attr, wait_for, "T3", 15, 3);
> +
> +     t1.join();
> +     t2.join();
> +     t3.join();
> +
> +     std::cout << "End example 2" << std::endl;
> +   }
> +
> +A more powerful example shows the encapsulation of threads in a class or
> +structure to provide a concurrent interface. The example uses a thread in a
> +class to count seconds. The example shows the use of atomics and a mutex to
> +access to some elements in the class sequentially:
delete 'to' -> read as "mutex to access some"

> +
> +.. code-block:: c++
> +
> +   #include <atomic>
> +   #include <chrono>
> +   #include <iostream>
> +   #include <mutex>
> +
> +   #include <rtems/thread.hpp>
> +
> +   class ticker
> +   {
> +     public:
> +       ticker();
> +
> +       void start(const size_t life_time);
> +       bool finished();
> +
> +       size_t seconds();
> +
> +     private:
> +       void timer(const size_t life_time);
> +
> +       rtems::thread::thread tocker;
> +       std::mutex            lock;
> +       std::atomic<bool>     done;
> +       bool                  running;
> +       std::atomic<size_t>   the_seconds;
> +   };
> +
> +   ticker::ticker()
> +     : done(false),
> +       running(false),
> +       the_seconds(0)
> +   {
> +   }
> +
> +   void ticker::start(const size_t life_time)
> +   {
> +     std::lock_guard<std::mutex> guard(lock);
> +     if (!running) {
> +       rtems::thread::attributes attr;
> +       attr.set_name("CLCK");
> +       attr.set_stack_size(8 * 1024);
> +       attr.set_priority(10);
> +       running = true;
> +       tocker = rtems::thread::thread(attr, &ticker::timer, this, life_time);
> +     }
> +   }
> +
> +   bool ticker::finished()
> +   {
> +     return done.load();
> +   }
> +
> +   size_t ticker::seconds()
> +   {
> +     return the_seconds.load();
> +   }
> +
> +   void ticker::timer(const size_t life_time)
> +   {
> +     while (the_seconds.load() < life_time) {
> +       std::this_thread::sleep_for(std::chrono::seconds(1));
> +       the_seconds++;
> +     }
> +     done = true;
> +     std::lock_guard<std::mutex> guard(lock);
> +     running = false;
> +   }
> +
> +   void example_3()
> +   {
> +     std::cout << "Start example 3" << std::endl;
> +
> +     ticker my_ticker;
> +
> +     my_ticker.start(5);
> +
> +     while (!my_ticker.finished()) {
> +       std::this_thread::sleep_for(std::chrono::seconds(2));
> +       std::cout << "Ticker is " << my_ticker.seconds() << std::endl;
> +     }
> +
> +     std::cout << "End example 3" << std::endl;
> +   }
> +
> +The thread object's constructor provides the arguments to the new thread. The
> +first argument is the ``this`` pointer and that is required because the class
> +method is not static. The remaining arguments are optional and they only need
> +to match the signature of the method being used as the thread. In the example
> +the value passed to the ``start`` method is passed to the thread's body by it
s/it/its

> +arguments. Note, the arguments are copied so do not reference or use
> +references to local variables held in the context of the constructing
> +thread. If passing pointers wrap them in a ``std::unique_ptr`` or
> +``std::shared_ptr`` object.
> diff --git a/user/languages/index.rst b/user/languages/index.rst
> new file mode 100644
> index 0000000..f27e324
> --- /dev/null
> +++ b/user/languages/index.rst
> @@ -0,0 +1,21 @@
> +.. SPDX-License-Identifier: CC-BY-SA-4.0
> +
> +.. Copyright (C) 2020 Chris Johns <chrisj at rtems.org>
> +
> +.. _Languages:
> +
> +Languages
> +*********
> +.. index:: Languages
> +.. index:: Programming Languages
> +
> +This section discusses the languages you can use to develop RTEMS
> +applications with. The RTEMS Application Programming Interfaces (API)
delete " with"

> +are specified a C language bindings but this does not limit the
s/a/as

> +languages RTEMS supports.
> +
> +.. toctree::
> +
> +   c
> +   cpp
> +   ada

There are many other languages that are (suspected to be) working.
java, go, lua, ... Maybe this section needs to be either expanded with
all the languages we have seen used, or the language needs to be made
more vague to imply that we support the bindings for c/c++/ada and
that other languages can be supported?

> --
> 2.24.1
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list