source: rtems/doc/user/smp.t @ 4a93980

4.115
Last change on this file since 4a93980 was 4a93980, checked in by Sebastian Huber <sebastian.huber@…>, on 04/16/14 at 13:17:32

doc: rtems_get_current_processor()

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