[PATCH] user: Add a Languages section

Joel Sherrill joel at rtems.org
Fri Oct 9 15:38:21 UTC 2020


On Fri, Oct 9, 2020 at 10:26 AM Gedare Bloom <gedare at rtems.org> wrote:

> 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>
> > +
>

Should there be a general introduction on the compilers we support
and that we inherently rely on them. This puts the context into what
do GCC and CLANG support and which compiler(s) are available
on your target architecture.

Also Ada should have a TBD section.

If you can build Fortran with the RSB, it also needs a TBD section.
Surprising though it may be, it does work. :)


> > +.. index:: C
> > +.. index:: C Programming Language
> > +
> > +C
> > +=
> > +.. index:: C
> > +
> > +RTEMS supports the C programming language.
> > +
> > +TBD.
>

Obviously TBD but supported via the inherent compiler support
with the C Standard Library provided by newlib. Could reference
the POSIX Compliance Guide section on the C Standard Library.

Support should be primarily for C99 and C11 including C11 threads.
Don't C11 thread also map to pthreads?

There is a C11 threads example in rtems-examples.

Disclaimer: C11 threads are a terrible API.


> 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.
>

Yes.  The FACE Conformance Test Suite has been run against our C++03
support with no issues. GCC and its C++ Library are the magic here.


>
> > +
> > +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
>

synchronization


>
> > +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
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20201009/2153d0c5/attachment-0001.html>


More information about the devel mailing list