source: rtems/doc/user/smp.t @ 8839cf6

4.11
Last change on this file since 8839cf6 was 8839cf6, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 16, 2015 at 5:28:48 AM

doc: SMP introduction

  • Property mode set to 100644
File size: 30.5 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
11The Symmetric Multiprocessing (SMP) support of the RTEMS @value{VERSION} is
12available on
13
14@itemize @bullet
15@item ARM,
16@item PowerPC, and
17@item SPARC.
18@end itemize
19
20It must be explicitly enabled via the @code{--enable-smp} configure command
21line option.  To enable SMP in the application configuration see
22@ref{Configuring a System Enable SMP Support for Applications}.  The default
23scheduler for SMP applications supports up to 32 processors and is a global
24fixed priority scheduler, see also @ref{Configuring a System Configuring
25Clustered/Partitioned Schedulers}.  For example applications see
26@file{testsuites/smptests}.
27
28This chapter describes the services related to Symmetric Multiprocessing
29provided by RTEMS.
30
31The application level services currently provided are:
32
33@itemize @bullet
34@item @code{rtems_get_processor_count} - Get processor count
35@item @code{rtems_get_current_processor} - Get current processor index
36@item @code{rtems_scheduler_ident} - Get ID of a scheduler
37@item @code{rtems_scheduler_get_processor_set} - Get processor set of a scheduler
38@item @code{rtems_task_get_scheduler} - Get scheduler of a task
39@item @code{rtems_task_set_scheduler} - Set scheduler of a task
40@item @code{rtems_task_get_affinity} - Get task processor affinity
41@item @code{rtems_task_set_affinity} - Set task processor affinity
42@end itemize
43
44@c
45@c
46@c
47@section Background
48
49@subsection Uniprocessor versus SMP Parallelism
50
51Uniprocessor systems have long been used in embedded systems. In this hardware
52model, there are some system execution characteristics which have long been
53taken for granted:
54
55@itemize @bullet
56@item one task executes at a time
57@item hardware events result in interrupts
58@end itemize
59
60There is no true parallelism. Even when interrupts appear to occur
61at the same time, they are processed in largely a serial fashion.
62This is true even when the interupt service routines are allowed to
63nest.  From a tasking viewpoint,  it is the responsibility of the real-time
64operatimg system to simulate parallelism by switching between tasks.
65These task switches occur in response to hardware interrupt events and explicit
66application events such as blocking for a resource or delaying.
67
68With symmetric multiprocessing, the presence of multiple processors
69allows for true concurrency and provides for cost-effective performance
70improvements. Uniprocessors tend to increase performance by increasing
71clock speed and complexity. This tends to lead to hot, power hungry
72microprocessors which are poorly suited for many embedded applications.
73
74The true concurrency is in sharp contrast to the single task and
75interrupt model of uniprocessor systems. This results in a fundamental
76change to uniprocessor system characteristics listed above. Developers
77are faced with a different set of characteristics which, in turn, break
78some existing assumptions and result in new challenges. In an SMP system
79with N processors, these are the new execution characteristics.
80
81@itemize @bullet
82@item N tasks execute in parallel
83@item hardware events result in interrupts
84@end itemize
85
86There is true parallelism with a task executing on each processor and
87the possibility of interrupts occurring on each processor. Thus in contrast
88to their being one task and one interrupt to consider on a uniprocessor,
89there are N tasks and potentially N simultaneous interrupts to consider
90on an SMP system.
91
92This increase in hardware complexity and presence of true parallelism
93results in the application developer needing to be even more cautious
94about mutual exclusion and shared data access than in a uniprocessor
95embedded system. Race conditions that never or rarely happened when an
96application executed on a uniprocessor system, become much more likely
97due to multiple threads executing in parallel. On a uniprocessor system,
98these race conditions would only happen when a task switch occurred at
99just the wrong moment. Now there are N-1 tasks executing in parallel
100all the time and this results in many more opportunities for small
101windows in critical sections to be hit.
102
103@subsection Task Affinity
104
105@cindex task affinity
106@cindex thread affinity
107
108RTEMS provides services to manipulate the affinity of a task. Affinity
109is used to specify the subset of processors in an SMP system on which
110a particular task can execute.
111
112By default, tasks have an affinity which allows them to execute on any
113available processor.
114
115Task affinity is a possible feature to be supported by SMP-aware
116schedulers. However, only a subset of the available schedulers support
117affinity. Although the behavior is scheduler specific, if the scheduler
118does not support affinity, it is likely to ignore all attempts to set
119affinity.
120
121@subsection Task Migration
122
123@cindex task migration
124@cindex thread migration
125
126With more than one processor in the system tasks can migrate from one processor
127to another.  There are three reasons why tasks migrate in RTEMS.
128
129@itemize @bullet
130@item The scheduler changes explicitly via @code{rtems_task_set_scheduler()} or
131similar directives.
132@item The task resumes execution after a blocking operation.  On a priority
133based scheduler it will evict the lowest priority task currently assigned to a
134processor in the processor set managed by the scheduler instance.
135@item The task moves temporarily to another scheduler instance due to locking
136protocols like @cite{Migratory Priority Inheritance} or the
137@cite{Multiprocessor Resource Sharing Protocol}.
138@end itemize
139
140Task migration should be avoided so that the working set of a task can stay on
141the most local cache level.
142
143The current implementation of task migration in RTEMS has some implications
144with respect to the interrupt latency.  It is crucial to preserve the system
145invariant that a task can execute on at most one processor in the system at a
146time.  This is accomplished with a boolean indicator in the task context.  The
147processor architecture specific low-level task context switch code will mark
148that a task context is no longer executing and waits that the heir context
149stopped execution before it restores the heir context and resumes execution of
150the heir task.  So there is one point in time in which a processor is without a
151task.  This is essential to avoid cyclic dependencies in case multiple tasks
152migrate at once.  Otherwise some supervising entity is necessary to prevent
153life-locks.  Such a global supervisor would lead to scalability problems so
154this approach is not used.  Currently the thread dispatch is performed with
155interrupts disabled.  So in case the heir task is currently executing on
156another processor then this prolongs the time of disabled interrupts since one
157processor has to wait for another processor to make progress.
158
159It is difficult to avoid this issue with the interrupt latency since interrupts
160normally store the context of the interrupted task on its stack.  In case a
161task is marked as not executing we must not use its task stack to store such an
162interrupt context.  We cannot use the heir stack before it stopped execution on
163another processor.  So if we enable interrupts during this transition we have
164to provide an alternative task independent stack for this time frame.  This
165issue needs further investigation.
166
167@subsection Scheduler Helping Protocol
168
169The scheduler provides a helping protocol to support locking protocols like
170@cite{Migratory Priority Inheritance} or the @cite{Multiprocessor Resource
171Sharing Protocol}.  Each ready task can use at least one scheduler node at a
172time to gain access to a processor.  Each scheduler node has an owner, a user
173and an optional idle task.  The owner of a scheduler node is determined a task
174creation and never changes during the life time of a scheduler node.  The user
175of a scheduler node may change due to the scheduler helping protocol.  A
176scheduler node is in one of the four scheduler help states:
177
178@table @dfn
179
180@item help yourself
181
182This scheduler node is solely used by the owner task.  This task owns no
183resources using a helping protocol and thus does not take part in the scheduler
184helping protocol.  No help will be provided for other tasks.
185
186@item help active owner
187
188This scheduler node is owned by a task actively owning a resource and can be
189used to help out tasks.
190
191In case this scheduler node changes its state from ready to scheduled and the
192task executes using another node, then an idle task will be provided as a user
193of this node to temporarily execute on behalf of the owner task.  Thus lower
194priority tasks are denied access to the processors of this scheduler instance.
195
196In case a task actively owning a resource performs a blocking operation, then
197an idle task will be used also in case this node is in the scheduled state.
198
199@item help active rival
200
201This scheduler node is owned by a task actively obtaining a resource currently
202owned by another task and can be used to help out tasks.
203
204The task owning this node is ready and will give away its processor in case the
205task owning the resource asks for help.
206
207@item help passive
208
209This scheduler node is owned by a task obtaining a resource currently owned by
210another task and can be used to help out tasks.
211
212The task owning this node is blocked.
213
214@end table
215
216The following scheduler operations return a task in need for help
217
218@itemize @bullet
219@item unblock,
220@item change priority,
221@item yield, and
222@item ask for help.
223@end itemize
224
225A task in need for help is a task that encounters a scheduler state change from
226scheduled to ready (this is a pre-emption by a higher priority task) or a task
227that cannot be scheduled in an unblock operation.  Such a task can ask tasks
228which depend on resources owned by this task for help.
229
230In case it is not possible to schedule a task in need for help, then the
231scheduler nodes available for the task will be placed into the set of ready
232scheduler nodes of the corresponding scheduler instances.  Once a state change
233from ready to scheduled happens for one of scheduler nodes it will be used to
234schedule the task in need for help.
235
236The ask for help scheduler operation is used to help tasks in need for help
237returned by the operations mentioned above.  This operation is also used in
238case the root of a resource sub-tree owned by a task changes.
239
240The run-time of the ask for help procedures depend on the size of the resource
241tree of the task needing help and other resource trees in case tasks in need
242for help are produced during this operation.  Thus the worst-case latency in
243the system depends on the maximum resource tree size of the application.
244
245@subsection Critical Section Techniques and SMP
246
247As discussed earlier, SMP systems have opportunities for true parallelism
248which was not possible on uniprocessor systems. Consequently, multiple
249techniques that provided adequate critical sections on uniprocessor
250systems are unsafe on SMP systems. In this section, some of these
251unsafe techniques will be discussed.
252
253In general, applications must use proper operating system provided mutual
254exclusion mechanisms to ensure correct behavior. This primarily means
255the use of binary semaphores or mutexes to implement critical sections.
256
257@subsubsection Disable Interrupts and Interrupt Locks
258
259A low overhead means to ensure mutual exclusion in uni-processor configurations
260is to disable interrupts around a critical section.  This is commonly used in
261device driver code and throughout the operating system core.  On SMP
262configurations, however, disabling the interrupts on one processor has no
263effect on other processors.  So, this is insufficient to ensure system wide
264mutual exclusion.  The macros
265@itemize @bullet
266@item @code{rtems_interrupt_disable()},
267@item @code{rtems_interrupt_enable()}, and
268@item @code{rtems_interrupt_flush()}
269@end itemize
270are disabled on SMP configurations and its use will lead to compiler warnings
271and linker errors.  In the unlikely case that interrupts must be disabled on
272the current processor, then the
273@itemize @bullet
274@item @code{rtems_interrupt_local_disable()}, and
275@item @code{rtems_interrupt_local_enable()}
276@end itemize
277macros are now available in all configurations.
278
279Since disabling of interrupts is not enough to ensure system wide mutual
280exclusion on SMP, a new low-level synchronization primitive was added - the
281interrupt locks.  They are a simple API layer on top of the SMP locks used for
282low-level synchronization in the operating system core.  Currently they are
283implemented as a ticket lock.  On uni-processor configurations they degenerate
284to simple interrupt disable/enable sequences.  It is disallowed to acquire a
285single interrupt lock in a nested way.  This will result in an infinite loop
286with interrupts disabled.  While converting legacy code to interrupt locks care
287must be taken to avoid this situation.
288
289@example
290@group
291void legacy_code_with_interrupt_disable_enable( void )
292@{
293  rtems_interrupt_level level;
294
295  rtems_interrupt_disable( level );
296  /* Some critical stuff */
297  rtems_interrupt_enable( level );
298@}
299
300RTEMS_INTERRUPT_LOCK_DEFINE( static, lock, "Name" )
301
302void smp_ready_code_with_interrupt_lock( void )
303@{
304  rtems_interrupt_lock_context lock_context;
305
306  rtems_interrupt_lock_acquire( &lock, &lock_context );
307  /* Some critical stuff */
308  rtems_interrupt_lock_release( &lock, &lock_context );
309@}
310@end group
311@end example
312
313The @code{rtems_interrupt_lock} structure is empty on uni-processor
314configurations.  Empty structures have a different size in C
315(implementation-defined, zero in case of GCC) and C++ (implementation-defined
316non-zero value, one in case of GCC).  Thus the
317@code{RTEMS_INTERRUPT_LOCK_DECLARE()}, @code{RTEMS_INTERRUPT_LOCK_DEFINE()},
318@code{RTEMS_INTERRUPT_LOCK_MEMBER()}, and
319@code{RTEMS_INTERRUPT_LOCK_REFERENCE()} macros are provided to ensure ABI
320compatibility.
321
322@subsubsection Highest Priority Task Assumption
323
324On a uniprocessor system, it is safe to assume that when the highest
325priority task in an application executes, it will execute without being
326preempted until it voluntarily blocks. Interrupts may occur while it is
327executing, but there will be no context switch to another task unless
328the highest priority task voluntarily initiates it.
329
330Given the assumption that no other tasks will have their execution
331interleaved with the highest priority task, it is possible for this
332task to be constructed such that it does not need to acquire a binary
333semaphore or mutex for protected access to shared data.
334
335In an SMP system, it cannot be assumed there will never be a single task
336executing. It should be assumed that every processor is executing another
337application task. Further, those tasks will be ones which would not have
338been executed in a uniprocessor configuration and should be assumed to
339have data synchronization conflicts with what was formerly the highest
340priority task which executed without conflict.
341
342@subsubsection Disable Preemption
343
344On a uniprocessor system, disabling preemption in a task is very similar
345to making the highest priority task assumption. While preemption is
346disabled, no task context switches will occur unless the task initiates
347them voluntarily. And, just as with the highest priority task assumption,
348there are N-1 processors also running tasks. Thus the assumption that no
349other tasks will run while the task has preemption disabled is violated.
350
351@subsection Task Unique Data and SMP
352
353Per task variables are a service commonly provided by real-time operating
354systems for application use. They work by allowing the application
355to specify a location in memory (typically a @code{void *}) which is
356logically added to the context of a task. On each task switch, the
357location in memory is stored and each task can have a unique value in
358the same memory location. This memory location is directly accessed as a
359variable in a program.
360
361This works well in a uniprocessor environment because there is one task
362executing and one memory location containing a task-specific value. But
363it is fundamentally broken on an SMP system because there are always N
364tasks executing. With only one location in memory, N-1 tasks will not
365have the correct value.
366
367This paradigm for providing task unique data values is fundamentally
368broken on SMP systems.
369
370@subsubsection Classic API Per Task Variables
371
372The Classic API provides three directives to support per task variables. These are:
373
374@itemize @bullet
375@item @code{@value{DIRPREFIX}task_variable_add} - Associate per task variable
376@item @code{@value{DIRPREFIX}task_variable_get} - Obtain value of a a per task variable
377@item @code{@value{DIRPREFIX}task_variable_delete} - Remove per task variable
378@end itemize
379
380As task variables are unsafe for use on SMP systems, the use of these services
381must be eliminated in all software that is to be used in an SMP environment.
382The task variables API is disabled on SMP. Its use will lead to compile-time
383and link-time errors. It is recommended that the application developer consider
384the use of POSIX Keys or Thread Local Storage (TLS). POSIX Keys are available
385in all RTEMS configurations.  For the availablity of TLS on a particular
386architecture please consult the @cite{RTEMS CPU Architecture Supplement}.
387
388The only remaining user of task variables in the RTEMS code base is the Ada
389support.  So basically Ada is not available on RTEMS SMP.
390
391@subsection Thread Dispatch Details
392
393This section gives background information to developers interested in the
394interrupt latencies introduced by thread dispatching.  A thread dispatch
395consists of all work which must be done to stop the currently executing thread
396on a processor and hand over this processor to an heir thread.
397
398On SMP systems, scheduling decisions on one processor must be propagated to
399other processors through inter-processor interrupts.  So, a thread dispatch
400which must be carried out on another processor happens not instantaneous.  Thus
401several thread dispatch requests might be in the air and it is possible that
402some of them may be out of date before the corresponding processor has time to
403deal with them.  The thread dispatch mechanism uses three per-processor
404variables,
405@itemize @bullet
406@item the executing thread,
407@item the heir thread, and
408@item an boolean flag indicating if a thread dispatch is necessary or not.
409@end itemize
410Updates of the heir thread and the thread dispatch necessary indicator are
411synchronized via explicit memory barriers without the use of locks.  A thread
412can be an heir thread on at most one processor in the system.  The thread context
413is protected by a TTAS lock embedded in the context to ensure that it is used
414on at most one processor at a time.  The thread post-switch actions use a
415per-processor lock.  This implementation turned out to be quite efficient and
416no lock contention was observed in the test suite.
417
418The current implementation of thread dispatching has some implications with
419respect to the interrupt latency.  It is crucial to preserve the system
420invariant that a thread can execute on at most one processor in the system at a
421time.  This is accomplished with a boolean indicator in the thread context.
422The processor architecture specific context switch code will mark that a thread
423context is no longer executing and waits that the heir context stopped
424execution before it restores the heir context and resumes execution of the heir
425thread (the boolean indicator is basically a TTAS lock).  So, there is one
426point in time in which a processor is without a thread.  This is essential to
427avoid cyclic dependencies in case multiple threads migrate at once.  Otherwise
428some supervising entity is necessary to prevent deadlocks.  Such a global
429supervisor would lead to scalability problems so this approach is not used.
430Currently the context switch is performed with interrupts disabled.  Thus in
431case the heir thread is currently executing on another processor, the time of
432disabled interrupts is prolonged since one processor has to wait for another
433processor to make progress.
434
435It is difficult to avoid this issue with the interrupt latency since interrupts
436normally store the context of the interrupted thread on its stack.  In case a
437thread is marked as not executing, we must not use its thread stack to store
438such an interrupt context.  We cannot use the heir stack before it stopped
439execution on another processor.  If we enable interrupts during this
440transition, then we have to provide an alternative thread independent stack for
441interrupts in this time frame.  This issue needs further investigation.
442
443The problematic situation occurs in case we have a thread which executes with
444thread dispatching disabled and should execute on another processor (e.g. it is
445an heir thread on another processor).  In this case the interrupts on this
446other processor are disabled until the thread enables thread dispatching and
447starts the thread dispatch sequence.  The scheduler (an exception is the
448scheduler with thread processor affinity support) tries to avoid such a
449situation and checks if a new scheduled thread already executes on a processor.
450In case the assigned processor differs from the processor on which the thread
451already executes and this processor is a member of the processor set managed by
452this scheduler instance, it will reassign the processors to keep the already
453executing thread in place.  Therefore normal scheduler requests will not lead
454to such a situation.  Explicit thread migration requests, however, can lead to
455this situation.  Explicit thread migrations may occur due to the scheduler
456helping protocol or explicit scheduler instance changes.  The situation can
457also be provoked by interrupts which suspend and resume threads multiple times
458and produce stale asynchronous thread dispatch requests in the system.
459
460@c
461@c
462@c
463@section Operations
464
465@subsection Setting Affinity to a Single Processor
466
467On some embedded applications targeting SMP systems, it may be beneficial to
468lock individual tasks to specific processors.  In this way, one can designate a
469processor for I/O tasks, another for computation, etc..  The following
470illustrates the code sequence necessary to assign a task an affinity for
471processor with index @code{processor_index}.
472
473@example
474@group
475#include <rtems.h>
476#include <assert.h>
477
478void pin_to_processor(rtems_id task_id, int processor_index)
479@{
480  rtems_status_code sc;
481  cpu_set_t         cpuset;
482
483  CPU_ZERO(&cpuset);
484  CPU_SET(processor_index, &cpuset);
485
486  sc = rtems_task_set_affinity(task_id, sizeof(cpuset), &cpuset);
487  assert(sc == RTEMS_SUCCESSFUL);
488@}
489@end group
490@end example
491
492It is important to note that the @code{cpuset} is not validated until the
493@code{@value{DIRPREFIX}task_set_affinity} call is made. At that point,
494it is validated against the current system configuration.
495
496@c
497@c
498@c
499@section Directives
500
501This section details the symmetric multiprocessing services.  A subsection
502is dedicated to each of these services and describes the calling sequence,
503related constants, usage, and status codes.
504
505@c
506@c rtems_get_processor_count
507@c
508@page
509@subsection GET_PROCESSOR_COUNT - Get processor count
510
511@subheading CALLING SEQUENCE:
512
513@ifset is-C
514@example
515uint32_t rtems_get_processor_count(void);
516@end example
517@end ifset
518
519@ifset is-Ada
520@end ifset
521
522@subheading DIRECTIVE STATUS CODES:
523
524The count of processors in the system.
525
526@subheading DESCRIPTION:
527
528On uni-processor configurations a value of one will be returned.
529
530On SMP configurations this returns the value of a global variable set during
531system initialization to indicate the count of utilized processors.  The
532processor count depends on the physically or virtually available processors and
533application configuration.  The value will always be less than or equal to the
534maximum count of application configured processors.
535
536@subheading NOTES:
537
538None.
539
540@c
541@c rtems_get_current_processor
542@c
543@page
544@subsection GET_CURRENT_PROCESSOR - Get current processor index
545
546@subheading CALLING SEQUENCE:
547
548@ifset is-C
549@example
550uint32_t rtems_get_current_processor(void);
551@end example
552@end ifset
553
554@ifset is-Ada
555@end ifset
556
557@subheading DIRECTIVE STATUS CODES:
558
559The index of the current processor.
560
561@subheading DESCRIPTION:
562
563On uni-processor configurations a value of zero will be returned.
564
565On SMP configurations an architecture specific method is used to obtain the
566index of the current processor in the system.  The set of processor indices is
567the range of integers starting with zero up to the processor count minus one.
568
569Outside of sections with disabled thread dispatching the current processor
570index may change after every instruction since the thread may migrate from one
571processor to another.  Sections with disabled interrupts are sections with
572thread dispatching disabled.
573
574@subheading NOTES:
575
576None.
577
578@c
579@c rtems_scheduler_ident
580@c
581@page
582@subsection SCHEDULER_IDENT - Get ID of a scheduler
583
584@subheading CALLING SEQUENCE:
585
586@ifset is-C
587@example
588rtems_status_code rtems_scheduler_ident(
589  rtems_name  name,
590  rtems_id   *id
591);
592@end example
593@end ifset
594
595@ifset is-Ada
596@end ifset
597
598@subheading DIRECTIVE STATUS CODES:
599
600@code{@value{RPREFIX}SUCCESSFUL} - successful operation@*
601@code{@value{RPREFIX}INVALID_ADDRESS} - @code{id} is NULL@*
602@code{@value{RPREFIX}INVALID_NAME} - invalid scheduler name@*
603@code{@value{RPREFIX}UNSATISFIED} - - a scheduler with this name exists, but
604the processor set of this scheduler is empty
605
606@subheading DESCRIPTION:
607
608Identifies a scheduler by its name.  The scheduler name is determined by the
609scheduler configuration.  @xref{Configuring a System Configuring
610Clustered/Partitioned Schedulers}.
611
612@subheading NOTES:
613
614None.
615
616@c
617@c rtems_scheduler_get_processor_set
618@c
619@page
620@subsection SCHEDULER_GET_PROCESSOR_SET - Get processor set of a scheduler
621
622@subheading CALLING SEQUENCE:
623
624@ifset is-C
625@example
626rtems_status_code rtems_scheduler_get_processor_set(
627  rtems_id   scheduler_id,
628  size_t     cpusetsize,
629  cpu_set_t *cpuset
630);
631@end example
632@end ifset
633
634@ifset is-Ada
635@end ifset
636
637@subheading DIRECTIVE STATUS CODES:
638
639@code{@value{RPREFIX}SUCCESSFUL} - successful operation@*
640@code{@value{RPREFIX}INVALID_ADDRESS} - @code{cpuset} is NULL@*
641@code{@value{RPREFIX}INVALID_ID} - invalid scheduler id@*
642@code{@value{RPREFIX}INVALID_NUMBER} - the affinity set buffer is too small for
643set of processors owned by the scheduler
644
645@subheading DESCRIPTION:
646
647Returns the processor set owned by the scheduler in @code{cpuset}.  A set bit
648in the processor set means that this processor is owned by the scheduler and a
649cleared bit means the opposite.
650
651@subheading NOTES:
652
653None.
654
655@c
656@c rtems_task_get_scheduler
657@c
658@page
659@subsection TASK_GET_SCHEDULER - Get scheduler of a task
660
661@subheading CALLING SEQUENCE:
662
663@ifset is-C
664@example
665rtems_status_code rtems_task_get_scheduler(
666  rtems_id  task_id,
667  rtems_id *scheduler_id
668);
669@end example
670@end ifset
671
672@ifset is-Ada
673@end ifset
674
675@subheading DIRECTIVE STATUS CODES:
676
677@code{@value{RPREFIX}SUCCESSFUL} - successful operation@*
678@code{@value{RPREFIX}INVALID_ADDRESS} - @code{scheduler_id} is NULL@*
679@code{@value{RPREFIX}INVALID_ID} - invalid task id
680
681@subheading DESCRIPTION:
682
683Returns the scheduler identifier of a task identified by @code{task_id} in
684@code{scheduler_id}.
685
686@subheading NOTES:
687
688None.
689
690@c
691@c rtems_task_set_scheduler
692@c
693@page
694@subsection TASK_SET_SCHEDULER - Set scheduler of a task
695
696@subheading CALLING SEQUENCE:
697
698@ifset is-C
699@example
700rtems_status_code rtems_task_set_scheduler(
701  rtems_id task_id,
702  rtems_id scheduler_id
703);
704@end example
705@end ifset
706
707@ifset is-Ada
708@end ifset
709
710@subheading DIRECTIVE STATUS CODES:
711
712@code{@value{RPREFIX}SUCCESSFUL} - successful operation@*
713@code{@value{RPREFIX}INVALID_ID} - invalid task or scheduler id@*
714@code{@value{RPREFIX}INCORRECT_STATE} - the task is in the wrong state to
715perform a scheduler change
716
717@subheading DESCRIPTION:
718
719Sets the scheduler of a task identified by @code{task_id} to the scheduler
720identified by @code{scheduler_id}.  The scheduler of a task is initialized to
721the scheduler of the task that created it.
722
723@subheading NOTES:
724
725None.
726
727@subheading EXAMPLE:
728
729@example
730@group
731#include <rtems.h>
732#include <assert.h>
733
734void task(rtems_task_argument arg);
735
736void example(void)
737@{
738  rtems_status_code sc;
739  rtems_id          task_id;
740  rtems_id          scheduler_id;
741  rtems_name        scheduler_name;
742
743  scheduler_name = rtems_build_name('W', 'O', 'R', 'K');
744
745  sc = rtems_scheduler_ident(scheduler_name, &scheduler_id);
746  assert(sc == RTEMS_SUCCESSFUL);
747
748  sc = rtems_task_create(
749    rtems_build_name('T', 'A', 'S', 'K'),
750    1,
751    RTEMS_MINIMUM_STACK_SIZE,
752    RTEMS_DEFAULT_MODES,
753    RTEMS_DEFAULT_ATTRIBUTES,
754    &task_id
755  );
756  assert(sc == RTEMS_SUCCESSFUL);
757
758  sc = rtems_task_set_scheduler(task_id, scheduler_id);
759  assert(sc == RTEMS_SUCCESSFUL);
760
761  sc = rtems_task_start(task_id, task, 0);
762  assert(sc == RTEMS_SUCCESSFUL);
763@}
764@end group
765@end example
766
767@c
768@c rtems_task_get_affinity
769@c
770@page
771@subsection TASK_GET_AFFINITY - Get task processor affinity
772
773@subheading CALLING SEQUENCE:
774
775@ifset is-C
776@example
777rtems_status_code rtems_task_get_affinity(
778  rtems_id   id,
779  size_t     cpusetsize,
780  cpu_set_t *cpuset
781);
782@end example
783@end ifset
784
785@ifset is-Ada
786@end ifset
787
788@subheading DIRECTIVE STATUS CODES:
789
790@code{@value{RPREFIX}SUCCESSFUL} - successful operation@*
791@code{@value{RPREFIX}INVALID_ADDRESS} - @code{cpuset} is NULL@*
792@code{@value{RPREFIX}INVALID_ID} - invalid task id@*
793@code{@value{RPREFIX}INVALID_NUMBER} - the affinity set buffer is too small for
794the current processor affinity set of the task
795
796@subheading DESCRIPTION:
797
798Returns the current processor affinity set of the task in @code{cpuset}.  A set
799bit in the affinity set means that the task can execute on this processor and a
800cleared bit means the opposite.
801
802@subheading NOTES:
803
804None.
805
806@c
807@c rtems_task_set_affinity
808@c
809@page
810@subsection TASK_SET_AFFINITY - Set task processor affinity
811
812@subheading CALLING SEQUENCE:
813
814@ifset is-C
815@example
816rtems_status_code rtems_task_set_affinity(
817  rtems_id         id,
818  size_t           cpusetsize,
819  const cpu_set_t *cpuset
820);
821@end example
822@end ifset
823
824@ifset is-Ada
825@end ifset
826
827@subheading DIRECTIVE STATUS CODES:
828
829@code{@value{RPREFIX}SUCCESSFUL} - successful operation@*
830@code{@value{RPREFIX}INVALID_ADDRESS} - @code{cpuset} is NULL@*
831@code{@value{RPREFIX}INVALID_ID} - invalid task id@*
832@code{@value{RPREFIX}INVALID_NUMBER} - invalid processor affinity set
833
834@subheading DESCRIPTION:
835
836Sets the processor affinity set for the task specified by @code{cpuset}.  A set
837bit in the affinity set means that the task can execute on this processor and a
838cleared bit means the opposite.
839
840@subheading NOTES:
841
842This function will not change the scheduler of the task.  The intersection of
843the processor affinity set and the set of processors owned by the scheduler of
844the task must be non-empty.  It is not an error if the processor affinity set
845contains processors that are not part of the set of processors owned by the
846scheduler instance of the task.  A task will simply not run under normal
847circumstances on these processors since the scheduler ignores them.  Some
848locking protocols may temporarily use processors that are not included in the
849processor affinity set of the task.  It is also not an error if the processor
850affinity set contains processors that are not part of the system.
Note: See TracBrowser for help on using the repository browser.