source: rtems/doc/user/smp.t @ 89e72a80

4.115
Last change on this file since 89e72a80 was 89e72a80, checked in by Joel Sherrill <joel.sherrill@…>, on 03/10/14 at 16:35:16

smp.t: Add Background and Operation Sections

  • Property mode set to 100644
File size: 11.7 KB
Line 
1@c
2@c  COPYRIGHT (c) 2014.
3@c  On-Line Applications Research Corporation (OAR).
4@c  All rights reserved.
5@c
6
7@chapter Symmetric Multiprocessing Services
8
9@section Introduction
10
11This chapter describes the services related to Symmetric Multiprocessing
12provided by RTEMS.
13
14The application level services currently provided are:
15
16@itemize @bullet
17@item @code{rtems_smp_get_processor_count} - Obtain Number of CPUs
18@item @code{rtems_task_get_affinity} - Obtain Task Affinity
19@item @code{rtems_task_set_affinity} - Set Task Affinity
20@end itemize
21
22@c
23@c
24@c
25@section Background
26
27@subsection Uniprocessor versus SMP Parallelism
28
29Uniprocessor systems have long been used in embedded systems. In this hardware
30model, there are some system execution characteristics which have long been
31taken for granted:
32
33@itemize @bullet
34@item one task executes at a time
35@item hardware events result in interrupts
36@end itemize
37
38There is no true parallelism. Even when interrupts appear to occur
39at the same time, they are processed in largely a serial fashion.
40This is true even when the interupt service routines are allowed to
41nest.  From a tasking viewpoint,  it is the responsibility of the real-time
42operatimg system to simulate parallelism by switching between tasks.
43These task switches occur in response to hardware interrupt events and explicit
44application events such as blocking for a resource or delaying.
45
46With symmetric multiprocessing, the presence of multiple processors
47allows for true concurrency and provides for cost-effective performance
48improvements. Uniprocessors tend to increase performance by increasing
49clock speed and complexity. This tends to lead to hot, power hungry
50microprocessors which are poorly suited for many embedded applications.
51
52The true concurrency is in sharp contrast to the single task and
53interrupt model of uniprocessor systems. This results in a fundamental
54change to uniprocessor system characteristics listed above. Developers
55are faced with a different set of characteristics which, in turn, break
56some existing assumptions and result in new challenges. In an SMP system
57with N processors, these are the new execution characteristics.
58
59@itemize @bullet
60@item N tasks execute in parallel
61@item hardware events result in interrupts
62@end itemize
63
64There is true parallelism with a task executing on each processor and
65the possibility of interrupts occurring on each processor. Thus in contrast
66to their being one task and one interrupt to consider on a uniprocessor,
67there are N tasks and potentially N simultaneous interrupts to consider
68on an SMP system.
69
70This increase in hardware complexity and presence of true parallelism
71results in the application developer needing to be even more cautious
72about mutual exclusion and shared data access than in a uniprocessor
73embedded system. Race conditions that never or rarely happened when an
74application executed on a uniprocessor system, become much more likely
75due to multiple threads executing in parallel. On a uniprocessor system,
76these race conditions would only happen when a task switch occurred at
77just the wrong moment. Now there are N-1 tasks executing in parallel
78all the time and this results in many more opportunities for small
79windows in critical sections to be hit.
80
81@subsection Task Affinity
82
83@cindex task affinity
84@cindex thread affinity
85
86RTEMS provides services to manipulate the affinity of a task. Affinity
87is used to specify the subset of processors in an SMP system on which
88a particular task can execute.
89
90By default, tasks have an affinity which allows them to execute on any
91available processor.
92
93Task affinity is a possible feature to be supported by SMP-aware
94schedulers. However, only a subset of the available schedulers support
95affinity. Although the behavior is scheduler specific, if the scheduler
96does not support affinity, it is likely to ignore all attempts to set
97affinity.
98
99@subsection Critical Section Techniques and SMP
100
101As discussed earlier, SMP systems have opportunities for true parallelism
102which was not possible on uniprocessor systems. Consequently, multiple
103techniques that provided adequate critical sections on uniprocessor
104systems are unsafe on SMP systems. In this section, some of these
105unsafe techniques will be discussed.
106
107In general, applications must use proper operating system provided mutual
108exclusion mechanisms to ensure correct behavior. This primarily means
109the use of binary semaphores or mutexes to implement critical sections.
110
111@subsubsection Disable Interrupts
112
113Again on a uniprocessor system, there is only a single processor which
114logically executes a single task and takes interrupts. On an SMP system,
115each processor may take an interrupt. When the application disables
116interrupts, it generally does so by altering a processor register to
117mask interrupts and later to re-enable them. On a uniprocessor system,
118changing this in the single processor is sufficient. However, on an SMP
119system, this register in @strong{ALL} processors must be changed. There
120are no comparable capabilities in an SMP system to disable all interrupts
121across all processors.
122
123@subsubsection Highest Priority Task Assumption
124
125On a uniprocessor system, it is safe to assume that when the highest
126priority task in an application executes, it will execute without being
127preempted until it voluntarily blocks. Interrupts may occur while it is
128executing, but there will be no context switch to another task unless
129the highest priority task voluntarily initiates it.
130
131Given the assumption that no other tasks will have their execution
132interleaved with the highest priority task, it is possible for this
133task to be constructed such that it does not need to acquire a binary
134semaphore or mutex for protected access to shared data.
135
136In an SMP system, it cannot be assumed there will never be a single task
137executing. It should be assumed that every processor is executing another
138application task. Further, those tasks will be ones which would not have
139been executed in a uniprocessor configuration and should be assumed to
140have data synchronization conflicts with what was formerly the highest
141priority task which executed without conflict.
142
143@subsubsection Disable Preemption
144
145On a uniprocessor system, disabling preemption in a task is very similar
146to making the highest priority task assumption. While preemption is
147disabled, no task context switches will occur unless the task initiates
148them voluntarily. And, just as with the highest priority task assumption,
149there are N-1 processors also running tasks. Thus the assumption that no
150other tasks will run while the task has preemption disabled is violated.
151
152@subsection Task Unique Data and SMP
153
154Per task variables are a service commonly provided by real-time operating
155systems for application use. They work by allowing the application
156to specify a location in memory (typically a @code{void *}) which is
157logically added to the context of a task. On each task switch, the
158location in memory is stored and each task can have a unique value in
159the same memory location. This memory location is directly accessed as a
160variable in a program.
161
162This works well in a uniprocessor environment because there is one task
163executing and one memory location containing a task-specific value. But
164it is fundamentally broken on an SMP system because there are always N
165tasks executing. With only one location in memory, N-1 tasks will not
166have the correct value.
167
168This paradigm for providing task unique data values is fundamentally
169broken on SMP systems.
170
171@subsubsection Classic API Per Task Variables
172
173The Classic API provides three directives to support per task variables. These are:
174
175@itemize @bullet
176@item @code{@value{DIRPREFIX}task_variable_add} - Associate per task variable
177@item @code{@value{DIRPREFIX}task_variable_get} - Obtain value of a a per task variable
178@item @code{@value{DIRPREFIX}task_variable_delete} - Remove per task variable
179@end itemize
180
181As task variables are unsafe for use on SMP systems, the use of these
182services should be eliminated in all software that is to be used in
183an SMP environment. It is recommended that the application developer
184consider the use of POSIX Keys or Thread Local Storage (TLS). POSIX Keys
185are not enabled in all RTEMS configurations.
186
187@b{STATUS}: As of March 2014, some support services in the
188@code{rtems/cpukit} use per task variables. When these uses are
189eliminated, the per task variable directives will be disabled when
190building RTEMS in SMP configuration.
191
192@c
193@c
194@c
195@section Operations
196
197@subsection Setting Affinity to a Single Processor
198
199In many embedded applications targeting SMP systems, it is common to lock individual tasks to specific cores. In this way, one can designate a core for I/O tasks, another for computation, etc.. The following illustrates the code sequence necessary to assign a task an affinity for processor zero (0).
200
201@example
202rtems_status_code sc;
203cpu_set_t         set;
204
205CPU_EMPTY( &set );
206CPU_SET( 0, &set );
207
208sc = rtems_task_set_affinity(rtems_task_self(), sizeof(set), &set);
209assert(sc == RTEMS_SUCCESSFUL);
210@end example
211
212It is important to note that the @code{cpu_set_t} is not validated until the
213@code{@value{DIRPREFIX}task_set_affinity} call is made. At that point,
214it is validated against the current system configuration.
215
216@c
217@c
218@c
219@section Directives
220
221This section details the symmetric multiprocessing services.  A subsection
222is dedicated to each of these services and describes the calling sequence,
223related constants, usage, and status codes.
224
225@c
226@c rtems_smp_get_processor_count
227@c
228@page
229@subsection rtems_smp_get_processor_count - Obtain Number of CPUs
230
231@subheading CALLING SEQUENCE:
232
233@ifset is-C
234@example
235#include <rtems.h>
236
237int rtems_smp_get_processor_count(void);
238@end example
239@end ifset
240
241@ifset is-Ada
242@end ifset
243
244@subheading STATUS CODES:
245
246Returns the number of processors being utilized.
247
248@subheading DESCRIPTION:
249
250The @code{rtems_smp_get_processor_count} routine is used to obtain the
251number of processor cores being utilized.
252
253@subheading NOTES:
254
255NONE
256
257@c
258@c rtems_task_get_affinity
259@c
260@page
261@subsection rtems_task_get_affinity - Obtain Task Affinity
262
263@subheading CALLING SEQUENCE:
264
265@ifset is-C
266@example
267#include <rtems.h>
268
269rtems_status_code rtems_task_get_affinity(
270  rtems_id             id,
271  size_t               cpusetsize,
272  cpu_set_t           *cpuset
273);
274@end example
275@end ifset
276
277@ifset is-Ada
278@end ifset
279
280@subheading STATUS CODES:
281
282@table @b
283@item RTEMS_UNSATISFIED
284The @code{cpuset} pointer argument is invalid.
285
286@item RTEMS_UNSATISFIED
287The @code{cpusetsize} does not match the value of @code{affinitysetsize}
288field in the thread attribute object.
289
290@item RTEMS_INVALID_ID
291The @code{id} is invalid.
292
293@end table
294
295@subheading DESCRIPTION:
296
297The @code{rtems_task_get_affinity} routine is used to obtain the
298@code{affinityset} field from the thread object @code{id}.
299The value of this field is returned in @code{cpuset}
300
301@subheading NOTES:
302
303NONE
304
305@c
306@c rtems_task_set_affinity
307@c
308@page
309@subsection rtems_task_set_affinity - Set Task Affinity
310
311@subheading CALLING SEQUENCE:
312
313@ifset is-C
314@example
315#include <rtems.h>
316
317rtems_status_code rtems_task_set_affinity(
318  rtems_id             id,
319  size_t               cpusetsize,
320  cpu_set_t           *cpuset
321);
322@end example
323@end ifset
324
325@ifset is-Ada
326@end ifset
327
328@subheading STATUS CODES:
329
330@table @b
331@item RTEMS_UNSATISFIED
332The @code{cpuset} pointer argument is invalid.
333
334@item RTEMS_UNSATISFIED
335The @code{cpusetsize} does not match the value of @code{affinitysetsize}
336field in the thread attribute object.
337
338@item RTEMS_UNSATISFIED
339The @code{cpuset} did not select a valid cpu.
340
341@item RTEMS_UNSATISFIED
342The @code{cpuset} selected a cpu that was invalid.
343
344@item RTEMS_INVALID_ID
345The @code{id} is invalid.
346
347@end table
348
349@subheading DESCRIPTION:
350
351The @code{rtems_task_set_affinity} routine is used to set the
352@code{affinity.set} field of the thread control object associated
353with @code{id}.  This value controls the @code{cpuset} that the task can
354execute on.
355
356@subheading NOTES:
357
358NONE
Note: See TracBrowser for help on using the repository browser.