[PATCH] user: Add a Languages section

Gedare Bloom gedare at rtems.org
Fri Oct 9 15:41:11 UTC 2020


On Fri, Oct 9, 2020 at 9:38 AM Joel Sherrill <joel at rtems.org> wrote:
>
>
>
> 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
>
or synchronisation to be self-consistent. thanks for spotting that..
the UK/AU s throws off my typo parsing :)

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


More information about the devel mailing list