source: rtems/cpukit/rtems/include/rtems/rtems/tasks.h @ 38b59a6

4.115
Last change on this file since 38b59a6 was 38b59a6, checked in by Sebastian Huber <sebastian.huber@…>, on 05/02/14 at 08:31:09

score: Implement forced thread migration

The current implementation of task migration in RTEMS has some
implications with respect to the interrupt latency. It is crucial to
preserve the system invariant that a task can execute on at most one
processor in the system at a time. This is accomplished with a boolean
indicator in the task context. The processor architecture specific
low-level task context switch code will mark that a task context is no
longer executing and waits that the heir context stopped execution
before it restores the heir context and resumes execution of the heir
task. So there is one point in time in which a processor is without a
task. This is essential to avoid cyclic dependencies in case multiple
tasks migrate at once. Otherwise some supervising entity is necessary to
prevent life-locks. Such a global supervisor would lead to scalability
problems so this approach is not used. Currently the thread dispatch is
performed with interrupts disabled. So in case the heir task is
currently executing on another processor then this prolongs the time of
disabled interrupts since one processor has to wait for another
processor to make progress.

It is difficult to avoid this issue with the interrupt latency since
interrupts normally store the context of the interrupted task on its
stack. In case a task is marked as not executing we must not use its
task stack to store such an interrupt context. We cannot use the heir
stack before it stopped execution on another processor. So if we enable
interrupts during this transition we have to provide an alternative task
independent stack for this time frame. This issue needs further
investigation.

  • Property mode set to 100644
File size: 20.3 KB
Line 
1/**
2 * @file rtems/rtems/tasks.h
3 *
4 * @defgroup ClassicTasks Tasks
5 *
6 * @ingroup ClassicRTEMS
7 * @brief RTEMS Tasks
8 *
9 * This include file contains all constants and structures associated
10 * with RTEMS tasks. This manager provides a comprehensive set of directives
11 * to create, delete, and administer tasks.
12 *
13 * Directives provided are:
14 *
15 * - create a task
16 * - get an ID of a task
17 * - start a task
18 * - restart a task
19 * - delete a task
20 * - suspend a task
21 * - resume a task
22 * - set a task's priority
23 * - change the current task's mode
24 * - get a task notepad entry
25 * - set a task notepad entry
26 * - wake up after interval
27 * - wake up when specified
28 */
29
30/*
31 * COPYRIGHT (c) 1989-2014.
32 * On-Line Applications Research Corporation (OAR).
33 *
34 * The license and distribution terms for this file may be
35 * found in the file LICENSE in this distribution or at
36 * http://www.rtems.org/license/LICENSE.
37 */
38
39#ifndef _RTEMS_RTEMS_TASKS_H
40#define _RTEMS_RTEMS_TASKS_H
41
42#include <rtems/score/object.h>
43#include <rtems/score/thread.h>
44#include <rtems/rtems/types.h>
45#include <rtems/rtems/event.h>
46#include <rtems/rtems/asr.h>
47#include <rtems/rtems/attr.h>
48#include <rtems/rtems/status.h>
49
50#ifdef __cplusplus
51extern "C" {
52#endif
53
54/**
55 *  @defgroup ClassicTasks Tasks
56 *
57 *  @ingroup ClassicRTEMS
58 *
59 *  This encapsulates the functionality of the Classic API Task Manager.
60 *  This functionality includes task services such as creation, deletion,
61 *  delays, suspend/resume, and manipulation of execution mode and priority.
62 */
63/**@{*/
64
65/**
66 *  Constant to be used as the ID of current task
67 */
68#define RTEMS_SELF                OBJECTS_ID_OF_SELF
69
70/**
71 *  This constant is passed to the rtems_task_wake_after directive as the
72 *  interval when a task wishes to yield the CPU.
73 */
74#define RTEMS_YIELD_PROCESSOR WATCHDOG_NO_TIMEOUT
75
76/**
77 *  Define the type for an RTEMS API task priority.
78 */
79typedef Priority_Control rtems_task_priority;
80
81/**
82 *  This is the constant used with the rtems_task_set_priority
83 *  directive to indicate that the caller wants to obtain its
84 *  current priority rather than set it as the name of the
85 *  directive indicates.
86 */
87#define RTEMS_NO_PRIORITY           RTEMS_CURRENT_PRIORITY
88
89/**
90 *  This constant is the least valid value for a Classic API
91 *  task priority.
92 */
93#define RTEMS_MINIMUM_PRIORITY      (PRIORITY_MINIMUM + 1)
94
95/**
96 *  This constant is the maximum valid value for a Classic API
97 *  task priority.
98 *
99 *  @note This is actually the priority of the IDLE thread so
100 *        using this priority will result in having a task
101 *        which never executes.  This could be useful if you
102 *        want to ensure that a task does not executes during
103 *        certain operations such as a system mode change.
104 */
105#define RTEMS_MAXIMUM_PRIORITY      PRIORITY_MAXIMUM
106
107/**
108 *  The following constant is passed to rtems_task_set_priority when the
109 *  caller wants to obtain the current priority.
110 */
111#define RTEMS_CURRENT_PRIORITY      PRIORITY_MINIMUM
112
113/** This is used to indicate the lowest numbered notepad */
114#define RTEMS_NOTEPAD_FIRST 0
115/** This is used to indicate the notepad location 0. */
116#define RTEMS_NOTEPAD_0    0
117/** This is used to indicate the notepad location 1. */
118#define RTEMS_NOTEPAD_1    1
119/** This is used to indicate the notepad location 2. */
120#define RTEMS_NOTEPAD_2    2
121/** This is used to indicate the notepad location 3. */
122#define RTEMS_NOTEPAD_3    3
123/** This is used to indicate the notepad location 4. */
124#define RTEMS_NOTEPAD_4    4
125/** This is used to indicate the notepad location 5. */
126#define RTEMS_NOTEPAD_5    5
127/** This is used to indicate the notepad location 6. */
128#define RTEMS_NOTEPAD_6    6
129/** This is used to indicate the notepad location 7. */
130#define RTEMS_NOTEPAD_7    7
131/** This is used to indicate the notepad location 8. */
132#define RTEMS_NOTEPAD_8    8
133/** This is used to indicate the notepad location 9. */
134#define RTEMS_NOTEPAD_9    9
135/** This is used to indicate the notepad location 10. */
136#define RTEMS_NOTEPAD_10   10
137/** This is used to indicate the notepad location 11. */
138#define RTEMS_NOTEPAD_11   11
139/** This is used to indicate the notepad location 12. */
140#define RTEMS_NOTEPAD_12   12
141/** This is used to indicate the notepad location 13. */
142#define RTEMS_NOTEPAD_13   13
143/** This is used to indicate the notepad location 14. */
144#define RTEMS_NOTEPAD_14   14
145/** This is used to indicate the notepad location 15. */
146#define RTEMS_NOTEPAD_15   15
147/** This is used to indicate the highest numbered notepad. */
148#define RTEMS_NOTEPAD_LAST RTEMS_NOTEPAD_15
149
150/** This is used to indicate the number of notepads available. */
151#define RTEMS_NUMBER_NOTEPADS  (RTEMS_NOTEPAD_LAST+1)
152
153/**
154 *  External API name for Thread_Control
155 */
156typedef Thread_Control rtems_tcb;
157
158/**
159 *  The following defines the "return type" of an RTEMS task.
160 */
161typedef void rtems_task;
162
163/**
164 *  The following defines the argument to an RTEMS task.
165 */
166typedef Thread_Entry_numeric_type rtems_task_argument;
167
168/**
169 *  The following defines the type for the entry point of an RTEMS task.
170 */
171typedef rtems_task ( *rtems_task_entry )(
172                      rtems_task_argument
173                   );
174
175/**
176 *  The following records define the Initialization Tasks Table.
177 *  Each entry contains the information required by RTEMS to
178 *  create and start a user task automatically at executive
179 *  initialization time.
180 */
181typedef struct {
182  /** This is the Initialization Task's name. */
183  rtems_name            name;
184  /** This is the Initialization Task's stack size. */
185  size_t                stack_size;
186  /** This is the Initialization Task's priority. */
187  rtems_task_priority   initial_priority;
188  /** This is the Initialization Task's attributes. */
189  rtems_attribute       attribute_set;
190  /** This is the Initialization Task's entry point. */
191  rtems_task_entry      entry_point;
192  /** This is the Initialization Task's initial mode. */
193  rtems_mode            mode_set;
194  /** This is the Initialization Task's argument. */
195  rtems_task_argument   argument;
196} rtems_initialization_tasks_table;
197
198/**
199 * @brief RTEMS Task Create
200 *
201 * This routine implements the rtems_task_create directive. The task
202 * will have the name name. The attribute_set can be used to indicate
203 * that the task will be globally accessible or utilize floating point.
204 * The task's stack will be stack_size bytes. The task will begin
205 * execution with initial_priority and initial_modes. It returns the
206 * id of the created task in ID.
207 *
208 * @param[in] name is the user defined thread name
209 * @param[in] initial_priority is the thread priority
210 * @param[in] stack_size is the stack size in bytes
211 * @param[in] initial_modes is the initial thread mode
212 * @param[in] attribute_set is the thread attributes
213 * @param[in] id is the pointer to thread id
214 *
215 * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
216 *              and *id thread id filled in
217 */
218rtems_status_code rtems_task_create(
219  rtems_name           name,
220  rtems_task_priority  initial_priority,
221  size_t               stack_size,
222  rtems_mode           initial_modes,
223  rtems_attribute      attribute_set,
224  rtems_id            *id
225);
226
227/**
228 * @brief RTEMS Task Name to Id
229 *
230 * This routine implements the rtems_task_ident directive.
231 * This directive returns the task ID associated with name.
232 * If more than one task is named name, then the task to
233 * which the ID belongs is arbitrary. node indicates the
234 * extent of the search for the ID of the task named name.
235 * The search can be limited to a particular node or allowed to
236 * encompass all nodes.
237 *
238 * @param[in] name is the user defined thread name
239 * @param[in] node is(are) the node(s) to be searched
240 * @param[in] id is the pointer to thread id
241 *
242 * @retval This method returns RTEMS_SUCCESSFUL if there was not an
243 *         error. Otherwise, a status code is returned indicating the
244 *         source of the error. If successful, the id will
245 *         be filled in with the thread id.
246 */
247rtems_status_code rtems_task_ident(
248  rtems_name    name,
249  uint32_t      node,
250  rtems_id     *id
251);
252
253/**
254 * @brief RTEMS Delete Task
255 *
256 * This routine implements the rtems_task_delete directive. The
257 * task indicated by ID is deleted. The executive halts execution
258 * of the thread and frees the thread control block.
259 *
260 * @param[in] id is the thread id
261 *
262 * @retval This method returns RTEMS_SUCCESSFUL if there was not an
263 *         error and id is not the requesting thread. Status code is
264 *         returned indicating the source of the error. Nothing
265 *         is returned if id is the requesting thread (always succeeds).
266 */
267rtems_status_code rtems_task_delete(
268  rtems_id   id
269);
270
271/**
272 * @brief RTEMS Get Task Node
273 *
274 * This routine implements the rtems_task_get_note directive. The
275 * value of the indicated notepad for the task associated with ID
276 * is returned in note.
277 *
278 * @param[in] id is the thread id
279 * @param[in] notepad is the notepad number
280 * @param[out] note is the pointer to note
281 *
282 * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
283 */
284rtems_status_code rtems_task_get_note(
285  rtems_id    id,
286  uint32_t    notepad,
287  uint32_t   *note
288);
289
290/**
291 * @brief RTEMS Set Task Note
292 *
293 * This routine implements the rtems_task_set_note directive. The
294 * value of the indicated notepad for the task associated with ID
295 * is returned in note.
296 *
297 * @param[in] id is the thread id
298 * @param[in] notepad is the notepad number
299 * @param[in] note is the note value
300 *
301 * @return This method returns RTEMS_SUCCESSFUL if there was not an
302 *         error. Otherwise, a status code is returned indicating the
303 *         source of the error.
304 */
305rtems_status_code rtems_task_set_note(
306  rtems_id   id,
307  uint32_t   notepad,
308  uint32_t   note
309);
310
311/**
312 * @brief RTEMS Task Mode
313 *
314 * This routine implements the rtems_task_mode directive. The current
315 * values of the modes indicated by mask of the calling task are changed
316 * to that indicated in mode_set. The former mode of the task is
317 * returned in mode_set.
318 *
319 * @param[in] mode_set is the new mode
320 * @param[in] mask is the mask
321 * @param[in] previous_mode_set is the address of previous mode set
322 *
323 * @retval RTEMS_SUCCESSFUL and previous_mode_set filled in with the
324 * previous mode set
325 */
326rtems_status_code rtems_task_mode(
327  rtems_mode  mode_set,
328  rtems_mode  mask,
329  rtems_mode *previous_mode_set
330);
331
332/**
333 * @brief RTEMS Task Restart
334 *
335 * This routine implements the rtems_task_restart directive. The
336 * task associated with ID is restarted at its initial entry
337 * point with the new argument.
338 *
339 * @param[in] id is the thread id
340 * @param[in] arg is the thread argument
341 *
342 * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
343 */
344rtems_status_code rtems_task_restart(
345  rtems_id   id,
346  uint32_t   arg
347);
348
349/**
350 * @brief RTEMS Suspend Task
351 *
352 * This routine implements the rtems_task_suspend directive. The
353 * SUSPENDED state is set for task associated with ID. Note that the
354 * suspended state can be in addition to other waiting states.
355 *
356 * @param[in] id is the thread id
357 *
358 * @retval This method returns RTEMS_SUCCESSFUL if there was not an
359 *         error. Otherwise, a status code is returned indicating the
360 *         source of the error.
361 */
362rtems_status_code rtems_task_suspend(
363  rtems_id   id
364);
365
366/**
367 * @brief RTEMS Resume Task
368 *
369 * This routine implements the rtems_task_resume Directive. The
370 * SUSPENDED state is cleared for task associated with ID.
371 *
372 * @param[in] id is the thread id
373 *
374 * @retval This method returns RTEMS_SUCCESSFUL if there was not an
375 *         error. Otherwise, a status code is returned indicating the
376 *         source of the error.
377 */
378rtems_status_code rtems_task_resume(
379  rtems_id   id
380);
381
382/**
383 * @brief RTEMS Set Task Priority
384 *
385 * This routine implements the rtems_task_set_priority directive. The
386 * current priority of the task associated with ID is set to
387 * new_priority. The former priority of that task is returned
388 * in old_priority.
389 *
390 * @param[in] id is the thread to extract
391 * @param[in] new_priority is the thread to extract
392 * @param[in] old_priority is the thread to extract
393 *
394 * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
395 * and *old_priority filled in with the previous previous priority
396 */
397rtems_status_code rtems_task_set_priority(
398  rtems_id             id,
399  rtems_task_priority  new_priority,
400  rtems_task_priority *old_priority
401);
402
403/**
404 *  @brief RTEMS Start Task
405 *
406 *  RTEMS Task Manager
407 *
408 *  This routine implements the rtems_task_start directive.  The
409 *  starting execution point of the task associated with ID is
410 *  set to entry_point with the initial argument.
411 */
412rtems_status_code rtems_task_start(
413  rtems_id             id,
414  rtems_task_entry     entry_point,
415  rtems_task_argument  argument
416);
417
418/**
419 * @brief RTEMS Task Wake When
420 *
421 * This routine implements the rtems_task_wake_when directive. The
422 * calling task is blocked until the current time of day is
423 * equal to that indicated by time_buffer.
424 *
425 * @param[in] time_buffer is the pointer to the time and date structure
426 *
427 * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
428 */
429rtems_status_code rtems_task_wake_when(
430  rtems_time_of_day *time_buffer
431);
432
433/**
434 * @brief RTEMS Task Wake After
435 *
436 * This routine implements the rtems_task_wake_after directive. The
437 * calling task is blocked until the indicated number of clock
438 * ticks have occurred.
439 *
440 * @param[in] ticks is the number of ticks to wait
441 * @retval RTEMS_SUCCESSFUL
442 */
443rtems_status_code rtems_task_wake_after(
444  rtems_interval  ticks
445);
446
447/**
448 *  @brief rtems_task_is_suspended
449 *
450 *  This directive returns a status indicating whether or not
451 *  the specified task is suspended.
452 */
453rtems_status_code rtems_task_is_suspended(
454  rtems_id   id
455);
456
457#if !defined(RTEMS_SMP)
458/**
459 *  @brief RTEMS Add Task Variable
460 *
461 *  This directive adds a per task variable.
462 *
463 *  @note This service is not available in SMP configurations.
464 */
465rtems_status_code rtems_task_variable_add(
466  rtems_id  tid,
467  void    **ptr,
468  void    (*dtor)(void *)
469);
470
471/**
472 *  @brief Get a per-task variable
473 *
474 *  This directive gets the value of a task variable.
475 *
476 *  @note This service is not available in SMP configurations.
477 */
478rtems_status_code rtems_task_variable_get(
479  rtems_id tid,
480  void **ptr,
481  void **result
482);
483
484/**
485 *  @brief RTEMS Delete Task Variable
486 *
487 *  This directive removes a per task variable.
488 *
489 *  @note This service is not available in SMP configurations.
490 */
491rtems_status_code rtems_task_variable_delete(
492  rtems_id  tid,
493  void    **ptr
494);
495#endif
496
497#if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
498/**
499 * @brief Gets the processor affinity set of a task.
500 *
501 * @param[in] id Identifier of the task.  Use @ref RTEMS_SELF to select the
502 * executing task.
503 * @param[in] cpusetsize Size of the specified affinity set buffer in
504 * bytes.  This value must be positive.
505 * @param[out] cpuset The current processor affinity set of the task.  A set
506 * bit in the affinity set means that the task can execute on this processor
507 * and a cleared bit means the opposite.
508 *
509 * @retval RTEMS_SUCCESSFUL Successful operation.
510 * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL.
511 * @retval RTEMS_INVALID_ID Invalid task identifier.
512 * @retval RTEMS_INVALID_NUMBER The affinity set buffer is too small for the
513 * current processor affinity set of the task.
514 */
515rtems_status_code rtems_task_get_affinity(
516  rtems_id             id,
517  size_t               cpusetsize,
518  cpu_set_t           *cpuset
519);
520
521/**
522 * @brief Sets the processor affinity set of a task.
523 *
524 * @param[in] id Identifier of the task.  Use @ref RTEMS_SELF to select the
525 * executing task.
526 * @param[in] cpusetsize Size of the specified affinity set buffer in
527 * bytes.  This value must be positive.
528 * @param[in] cpuset The new processor affinity set for the task.  A set bit in
529 * the affinity set means that the task can execute on this processor and a
530 * cleared bit means the opposite.
531 *
532 * @retval RTEMS_SUCCESSFUL Successful operation.
533 * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL.
534 * @retval RTEMS_INVALID_ID Invalid task identifier.
535 * @retval RTEMS_INVALID_NUMBER Invalid processor affinity set.
536 */
537rtems_status_code rtems_task_set_affinity(
538  rtems_id         id,
539  size_t           cpusetsize,
540  const cpu_set_t *cpuset
541);
542#endif
543
544/**
545 * @brief Gets the scheduler of a task.
546 *
547 * @param[in] id Identifier of the task.  Use @ref RTEMS_SELF to select the
548 * executing task.
549 * @param[out] scheduler_id Identifier of the scheduler.
550 *
551 * @retval RTEMS_SUCCESSFUL Successful operation.
552 * @retval RTEMS_INVALID_ADDRESS The @a scheduler_id parameter is @c NULL.
553 * @retval RTEMS_INVALID_ID Invalid task identifier.
554 */
555rtems_status_code rtems_task_get_scheduler(
556  rtems_id  id,
557  rtems_id *scheduler_id
558);
559
560/**
561 * @brief Sets the scheduler of a task.
562 *
563 * The scheduler of a task is initialized to the scheduler of the task that
564 * created it.
565 *
566 * @param[in] id Identifier of the task.  Use @ref RTEMS_SELF to select the
567 * executing task.
568 * @param[in] scheduler_id Identifier of the scheduler.
569 *
570 * @retval RTEMS_SUCCESSFUL Successful operation.
571 * @retval RTEMS_INVALID_ID Invalid task or scheduler identifier.
572 *
573 * @see rtems_scheduler_ident().
574 */
575rtems_status_code rtems_task_set_scheduler(
576  rtems_id id,
577  rtems_id scheduler_id
578);
579
580/**
581 *  @brief RTEMS Get Self Task Id
582 *
583 *  This directive returns the ID of the currently executing task.
584 */
585rtems_id rtems_task_self(void);
586
587/**
588 * @brief Identifies a scheduler by its name.
589 *
590 * The scheduler name is determined by the scheduler configuration.
591 *
592 * @param[in] name The scheduler name.
593 * @param[out] id The scheduler identifier associated with the name.
594 *
595 * @retval RTEMS_SUCCESSFUL Successful operation.
596 * @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL.
597 * @retval RTEMS_INVALID_NAME Invalid scheduler name.
598 * @retval RTEMS_UNSATISFIED A scheduler with this name exists, but the
599 * processor set of this scheduler is empty.
600 */
601rtems_status_code rtems_scheduler_ident(
602  rtems_name  name,
603  rtems_id   *id
604);
605
606#if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
607/**
608 * @brief Gets the set of processors owned by the scheduler.
609 *
610 * @param[in] scheduler_id Identifier of the scheduler.
611 * @param[in] cpusetsize Size of the specified processor set buffer in
612 * bytes.  This value must be positive.
613 * @param[out] cpuset The processor set owned by the scheduler.  A set bit in
614 * the processor set means that this processor is owned by the scheduler and a
615 * cleared bit means the opposite.
616 *
617 * @retval RTEMS_SUCCESSFUL Successful operation.
618 * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL.
619 * @retval RTEMS_INVALID_ID Invalid scheduler identifier.
620 * @retval RTEMS_INVALID_NUMBER The processor set buffer is too small for the
621 * set of processors owned by the scheduler.
622 */
623rtems_status_code rtems_scheduler_get_processor_set(
624  rtems_id   scheduler_id,
625  size_t     cpusetsize,
626  cpu_set_t *cpuset
627);
628#endif
629
630/**@}*/
631
632/**
633 *  This is the API specific information required by each thread for
634 *  the RTEMS API to function correctly.
635 *
636 *  @note Notepads must be the last entry in the structure and memory
637 *        will be taken away from this structure when allocated if
638 *        notespads are disabled by the application configuration.
639 */
640typedef struct {
641  /** This field contains the event control for this task. */
642  Event_Control            Event;
643  /** This field contains the system event control for this task. */
644  Event_Control            System_event;
645  /** This field contains the Classic API Signal information for this task. */
646  ASR_Information          Signal;
647
648  /**
649   * @brief Signal post-switch action in case signals are pending.
650   */
651  Thread_Action            Signal_action;
652
653  /**
654   *  This field contains the notepads for this task.
655   *
656   *  @note MUST BE LAST ENTRY.
657   */
658  uint32_t                 Notepads[ RTEMS_ZERO_LENGTH_ARRAY ];
659}  RTEMS_API_Control;
660
661/**
662 *  When the user configures a set of Classic API initialization tasks,
663 *  This variable will point to the method used to initialize them.
664 *
665 *  @note It is instantiated and initialized by confdefs.h based upon
666 *        application requirements.
667 */
668extern void (*_RTEMS_tasks_Initialize_user_tasks_p)(void);
669
670/**
671 *  @brief _RTEMS_tasks_Initialize_user_tasks_body
672 *
673 *  This routine creates and starts all configured user
674 *  initialization threads.
675 *
676 *  Input parameters: NONE
677 *
678 *  Output parameters:  NONE
679 *
680 *  RTEMS Task Manager
681 */
682
683extern void _RTEMS_tasks_Initialize_user_tasks_body( void );
684
685#ifdef __cplusplus
686}
687#endif
688
689#endif
690/* end of include file */
Note: See TracBrowser for help on using the repository browser.