[PATCH v2] user: Add a Languages section
chrisj at rtems.org
chrisj at rtems.org
Sun Oct 18 22:00:45 UTC 2020
From: Chris Johns <chrisj at rtems.org>
---
user/index.rst | 2 +
user/languages/c.rst | 18 +++
user/languages/cpp.rst | 312 +++++++++++++++++++++++++++++++++++++++
user/languages/index.rst | 24 +++
4 files changed, 356 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..cca0a4b
--- /dev/null
+++ b/user/languages/c.rst
@@ -0,0 +1,18 @@
+.. 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 via the inherent C compiler
+support with the C Standard Library provided by newlib. The support
+language version is C99 and C11 including C11 threads. The RTEMS POSIX
+1003.1 Compliance Guide details the supported interfaces and standards
+the C Standard Library supports.
+
+TBD.
diff --git a/user/languages/cpp.rst b/user/languages/cpp.rst
new file mode 100644
index 0000000..f9e4cb9
--- /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.
+
+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 provides a range of methods to atomically access data as
+well 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 synchronization primitives such as mutual exclusion, condition
+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
+minimize 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 attribute of a thread is the stack size and this cannot
+be 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 initialise 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
+executing thread's stack size.
+
+An attribute object can be used to start a number of threads. The thread does
+not reference the attribute object once running.
+
+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 based on the POSIX standard. The
+policies are:
+
+``sched_other``
+ A CPU budget algorithm with time-slicing where the time-slice is reset.
+
+``sched_fifo``
+ A CPU budget algorithm with no time-slicing.
+
+``sched_roundrobin``
+ A CPU budget algorithm with time-slicing where the time-slice is exhausted.
+
+``sched_sporadic``
+ A CPU budget algorithm with a priority, low priority and a replenish period.
+
+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 some elements in the class sequentially:
+
+.. 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 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..3b262b5
--- /dev/null
+++ b/user/languages/index.rst
@@ -0,0 +1,24 @@
+.. 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 some of the languages you can use to develop
+RTEMS applications. The RTEMS Application Programming Interfaces (API)
+are specified as C language bindings but this does not limit the
+languages RTEMS supports.
+
+The languages listed in the section are supported and tested. Many
+others languages have been ported to RTEMS over the years and maybe
+available as 3rd party additions.
+
+.. toctree::
+
+ c
+ cpp
--
2.24.1
More information about the devel
mailing list