summaryrefslogtreecommitdiffstats
path: root/c-user/task/background.rst
blob: a55f7433faa0e3fc2f2798a35eb7655a709f817e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
.. SPDX-License-Identifier: CC-BY-SA-4.0

.. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)

Background
==========

.. index:: task, definition

Task Definition
---------------

Many definitions of a task have been proposed in computer literature.
Unfortunately, none of these definitions encompasses all facets of the concept
in a manner which is operating system independent.  Several of the more common
definitions are provided to enable each user to select a definition which best
matches their own experience and understanding of the task concept:

- a "dispatchable" unit.

- an entity to which the processor is allocated.

- an atomic unit of a real-time, multiprocessor system.

- single threads of execution which concurrently compete for resources.

- a sequence of closely related computations which can execute concurrently
  with other computational sequences.

From RTEMS' perspective, a task is the smallest thread of execution which can
compete on its own for system resources.  A task is manifested by the existence
of a task control block (TCB).

.. _TaskControlBlock:

Task Control Block
------------------

The Task Control Block (TCB) is an RTEMS defined data structure which contains
all the information that is pertinent to the execution of a task.  During
system initialization, RTEMS reserves a TCB for each task configured.  A TCB is
allocated upon creation of the task and is returned to the TCB free list upon
deletion of the task.

The TCB's elements are modified as a result of system calls made by the
application in response to external and internal stimuli.  TCBs are the only
RTEMS internal data structure that can be accessed by an application via user
extension routines.  The TCB contains a task's name, ID, current priority,
current and starting states, execution mode, TCB user extension pointer,
scheduling control structures, as well as data required by a blocked task.

A task's context is stored in the TCB when a task switch occurs.  When the task
regains control of the processor, its context is restored from the TCB.  When a
task is restarted, the initial state of the task is restored from the starting
context area in the task's TCB.

.. index:: task memory

Task Memory
-----------

The system uses two separate memory areas to manage a task.  One memory area is
the :ref:`TaskControlBlock`.  The other memory area is allocated from the stack
space or provided by the user and contains

* the task stack,

* the thread-local storage (:term:`TLS`), and

* an optional architecture-specific floating-point context.

The size of the thread-local storage is determined at link time.  A
user-provided task stack must take the size of the thread-local storage into
account.

On architectures with a dedicated floating-point context, the application
configuration assumes that every task is a floating-point task, but whether or
not a task is actually floating-point is determined at runtime during task
creation (see :ref:`TaskFloatingPointConsiderations`).  In highly memory
constrained systems this potential overestimate of the task stack space can be
mitigated through the :ref:`CONFIGURE_MINIMUM_TASK_STACK_SIZE` configuration
option and aligned task stack sizes for the tasks.  A user-provided task stack
must take the potential floating-point context into account.

.. index:: task name

Task Name
---------

By default, the task name is defined by the task object name given to
:ref:`rtems_task_create() <rtems_task_create>`.  The task name can be obtained
with the `pthread_getname_np()
<http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html>`_ function.
Optionally, a new task name may be set with the `pthread_setname_np()
<http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html>`_ function.
The maximum size of a task name is defined by the application configuration
option :ref:`CONFIGURE_MAXIMUM_THREAD_NAME_SIZE
<CONFIGURE_MAXIMUM_THREAD_NAME_SIZE>`.

.. index:: task states

Task States
-----------

A task may exist in one of the following five states:

- *executing* - Currently scheduled to the CPU

- *ready* - May be scheduled to the CPU

- *blocked* - Unable to be scheduled to the CPU

- *dormant* - Created task that is not started

- *non-existent* - Uncreated or deleted task

An active task may occupy the executing, ready, blocked or dormant state,
otherwise the task is considered non-existent.  One or more tasks may be active
in the system simultaneously.  Multiple tasks communicate, synchronize, and
compete for system resources with each other via system calls.  The multiple
tasks appear to execute in parallel, but actually each is dispatched to the CPU
for periods of time determined by the RTEMS scheduling algorithm.  The
scheduling of a task is based on its current state and priority.

.. index:: task priority
.. index:: priority, task
.. index:: rtems_task_priority

Task Priority
-------------

A task's priority determines its importance in relation to the other tasks
executing on the same processor.  RTEMS supports 255 levels of priority ranging
from 1 to 255.  The data type ``rtems_task_priority`` is used to store task
priorities.

Tasks of numerically smaller priority values are more important tasks than
tasks of numerically larger priority values.  For example, a task at priority
level 5 is of higher privilege than a task at priority level 10.  There is no
limit to the number of tasks assigned to the same priority.

Each task has a priority associated with it at all times.  The initial value of
this priority is assigned at task creation time.  The priority of a task may be
changed at any subsequent time.

Priorities are used by the scheduler to determine which ready task will be
allowed to execute.  In general, the higher the logical priority of a task, the
more likely it is to receive processor execution time.

.. index:: task mode
.. index:: rtems_task_mode

Task Mode
---------

A task's execution mode is a combination of the following four components:

- preemption

- ASR processing

- timeslicing

- interrupt level

It is used to modify RTEMS' scheduling process and to alter the execution
environment of the task.  The data type ``rtems_task_mode`` is used to manage
the task execution mode.

.. index:: preemption

The preemption component allows a task to determine when control of the
processor is relinquished.  If preemption is disabled (``RTEMS_NO_PREEMPT``),
the task will retain control of the processor as long as it is in the executing
state - even if a higher priority task is made ready.  If preemption is enabled
(``RTEMS_PREEMPT``) and a higher priority task is made ready, then the
processor will be taken away from the current task immediately and given to the
higher priority task.

.. index:: timeslicing

The timeslicing component is used by the RTEMS scheduler to determine how the
processor is allocated to tasks of equal priority.  If timeslicing is enabled
(``RTEMS_TIMESLICE``), then RTEMS will limit the amount of time the task can
execute before the processor is allocated to another ready task of equal
priority. The length of the timeslice is application dependent and specified in
the Configuration Table.  If timeslicing is disabled (``RTEMS_NO_TIMESLICE``),
then the task will be allowed to execute until a task of higher priority is
made ready.  If ``RTEMS_NO_PREEMPT`` is selected, then the timeslicing component
is ignored by the scheduler.

The asynchronous signal processing component is used to determine when received
signals are to be processed by the task.  If signal processing is enabled
(``RTEMS_ASR``), then signals sent to the task will be processed the next time
the task executes.  If signal processing is disabled (``RTEMS_NO_ASR``), then
all signals received by the task will remain posted until signal processing is
enabled.  This component affects only tasks which have established a routine to
process asynchronous signals.

.. index:: interrupt level, task

The interrupt level component is used to determine which interrupts will be
enabled when the task is executing. ``RTEMS_INTERRUPT_LEVEL(n)`` specifies that
the task will execute at interrupt level n.

.. list-table::
 :class: rtems-table

 * - ``RTEMS_PREEMPT``
   - enable preemption (default)
 * - ``RTEMS_NO_PREEMPT``
   - disable preemption
 * - ``RTEMS_NO_TIMESLICE``
   - disable timeslicing (default)
 * - ``RTEMS_TIMESLICE``
   - enable timeslicing
 * - ``RTEMS_ASR``
   - enable ASR processing (default)
 * - ``RTEMS_NO_ASR``
   - disable ASR processing
 * - ``RTEMS_INTERRUPT_LEVEL(0)``
   - enable all interrupts (default)
 * - ``RTEMS_INTERRUPT_LEVEL(n)``
   - execute at interrupt level n

The set of default modes may be selected by specifying the
``RTEMS_DEFAULT_MODES`` constant.

.. index:: task arguments
.. index:: task prototype

Accessing Task Arguments
------------------------

All RTEMS tasks are invoked with a single argument which is specified when they
are started or restarted.  The argument is commonly used to communicate startup
information to the task.  The simplest manner in which to define a task which
accesses it argument is:

.. index:: rtems_task

.. code-block:: c

    rtems_task user_task(
        rtems_task_argument argument
    );

Application tasks requiring more information may view this single argument as
an index into an array of parameter blocks.

.. index:: floating point

.. _TaskFloatingPointConsiderations:

Floating Point Considerations
-----------------------------

Please consult the *RTEMS CPU Architecture Supplement* if this section is
relevant on your architecture.  On some architectures the floating-point context
is contained in the normal task context and this section does not apply.

Creating a task with the ``RTEMS_FLOATING_POINT`` attribute flag results in
additional memory being allocated for the task to store the state of the numeric
coprocessor during task switches.  This additional memory is **not** allocated
for ``RTEMS_NO_FLOATING_POINT`` tasks. Saving and restoring the context of a
``RTEMS_FLOATING_POINT`` task takes longer than that of a
``RTEMS_NO_FLOATING_POINT`` task because of the relatively large amount of time
required for the numeric coprocessor to save or restore its computational state.

Since RTEMS was designed specifically for embedded military applications which
are floating point intensive, the executive is optimized to avoid unnecessarily
saving and restoring the state of the numeric coprocessor.  In uniprocessor
configurations, the state of the numeric coprocessor is only saved when a
``RTEMS_FLOATING_POINT`` task is dispatched and that task was not the last task
to utilize the coprocessor.  In a uniprocessor system with only one
``RTEMS_FLOATING_POINT`` task, the state of the numeric coprocessor will never
be saved or restored.

Although the overhead imposed by ``RTEMS_FLOATING_POINT`` tasks is minimal,
some applications may wish to completely avoid the overhead associated with
``RTEMS_FLOATING_POINT`` tasks and still utilize a numeric coprocessor.  By
preventing a task from being preempted while performing a sequence of floating
point operations, a ``RTEMS_NO_FLOATING_POINT`` task can utilize the numeric
coprocessor without incurring the overhead of a ``RTEMS_FLOATING_POINT``
context switch.  This approach also avoids the allocation of a floating point
context area.  However, if this approach is taken by the application designer,
**no** tasks should be created as ``RTEMS_FLOATING_POINT`` tasks.  Otherwise, the
floating point context will not be correctly maintained because RTEMS assumes
that the state of the numeric coprocessor will not be altered by
``RTEMS_NO_FLOATING_POINT`` tasks.  Some architectures with a dedicated
floating-point context raise a processor exception if a task with
``RTEMS_NO_FLOATING_POINT`` issues a floating-point instruction, so this
approach may not work at all.

If the supported processor type does not have hardware floating capabilities or
a standard numeric coprocessor, RTEMS will not provide built-in support for
hardware floating point on that processor.  In this case, all tasks are
considered ``RTEMS_NO_FLOATING_POINT`` whether created as
``RTEMS_FLOATING_POINT`` or ``RTEMS_NO_FLOATING_POINT`` tasks.  A floating
point emulation software library must be utilized for floating point
operations.

On some processors, it is possible to disable the floating point unit
dynamically.  If this capability is supported by the target processor, then
RTEMS will utilize this capability to enable the floating point unit only for
tasks which are created with the ``RTEMS_FLOATING_POINT`` attribute.  The
consequence of a ``RTEMS_NO_FLOATING_POINT`` task attempting to access the
floating point unit is CPU dependent but will generally result in an exception
condition.

.. index:: task attributes, building

Building a Task Attribute Set
-----------------------------

In general, an attribute set is built by a bitwise OR of the desired
components.  The set of valid task attribute components is listed below:

.. list-table::
 :class: rtems-table

 * - ``RTEMS_NO_FLOATING_POINT``
   - does not use coprocessor (default)
 * - ``RTEMS_FLOATING_POINT``
   - uses numeric coprocessor
 * - ``RTEMS_LOCAL``
   - local task (default)
 * - ``RTEMS_GLOBAL``
   - global task

Attribute values are specifically designed to be mutually exclusive, therefore
bitwise OR and addition operations are equivalent as long as each attribute
appears exactly once in the component list.  A component listed as a default is
not required to appear in the component list, although it is a good programming
practice to specify default components.  If all defaults are desired, then
``RTEMS_DEFAULT_ATTRIBUTES`` should be used.

This example demonstrates the attribute_set parameter needed to create a local
task which utilizes the numeric coprocessor.  The attribute_set parameter could
be ``RTEMS_FLOATING_POINT`` or ``RTEMS_LOCAL | RTEMS_FLOATING_POINT``.  The
attribute_set parameter can be set to ``RTEMS_FLOATING_POINT`` because
``RTEMS_LOCAL`` is the default for all created tasks.  If the task were global
and used the numeric coprocessor, then the attribute_set parameter would be
``RTEMS_GLOBAL | RTEMS_FLOATING_POINT``.

.. index:: task mode, building

Building a Mode and Mask
------------------------

In general, a mode and its corresponding mask is built by a bitwise OR of the
desired components.  The set of valid mode constants and each mode's
corresponding mask constant is listed below:

.. list-table::
 :class: rtems-table

 * - ``RTEMS_PREEMPT``
   - is masked by ``RTEMS_PREEMPT_MASK`` and enables preemption
 * - ``RTEMS_NO_PREEMPT``
   - is masked by ``RTEMS_PREEMPT_MASK`` and disables preemption
 * - ``RTEMS_NO_TIMESLICE``
   - is masked by ``RTEMS_TIMESLICE_MASK`` and disables timeslicing
 * - ``RTEMS_TIMESLICE``
   - is masked by ``RTEMS_TIMESLICE_MASK`` and enables timeslicing
 * - ``RTEMS_ASR``
   - is masked by ``RTEMS_ASR_MASK`` and enables ASR processing
 * - ``RTEMS_NO_ASR``
   - is masked by ``RTEMS_ASR_MASK`` and disables ASR processing
 * - ``RTEMS_INTERRUPT_LEVEL(0)``
   - is masked by ``RTEMS_INTERRUPT_MASK`` and enables all interrupts
 * - ``RTEMS_INTERRUPT_LEVEL(n)``
   - is masked by ``RTEMS_INTERRUPT_MASK`` and sets interrupts level n

Mode values are specifically designed to be mutually exclusive, therefore
bitwise OR and addition operations are equivalent as long as each mode appears
exactly once in the component list.  A mode component listed as a default is
not required to appear in the mode component list, although it is a good
programming practice to specify default components.  If all defaults are
desired, the mode ``RTEMS_DEFAULT_MODES`` and the mask ``RTEMS_ALL_MODE_MASKS``
should be used.

The following example demonstrates the mode and mask parameters used with the
``rtems_task_mode`` directive to place a task at interrupt level 3 and make it
non-preemptible.  The mode should be set to ``RTEMS_INTERRUPT_LEVEL(3) |
RTEMS_NO_PREEMPT`` to indicate the desired preemption mode and interrupt level,
while the mask parameter should be set to ``RTEMS_INTERRUPT_MASK |
RTEMS_NO_PREEMPT_MASK`` to indicate that the calling task's interrupt level and
preemption mode are being altered.