source: rtems/cpukit/rtems/src/taskmode.c @ 6fd1bdb7

4.115
Last change on this file since 6fd1bdb7 was 6fd1bdb7, checked in by Sebastian Huber <sebastian.huber@…>, on 03/14/14 at 10:53:43

rtems: Use thread action for signals

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief RTEMS Task Mode
5 *  @ingroup ClassicTasks
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2014.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/rtems/tasks.h>
22#include <rtems/rtems/asrimpl.h>
23#include <rtems/rtems/modesimpl.h>
24#include <rtems/score/threadimpl.h>
25#include <rtems/config.h>
26
27static void _RTEMS_Tasks_Dispatch_if_necessary(
28  Thread_Control *executing,
29  bool            needs_asr_dispatching
30)
31{
32  if ( _Thread_Dispatch_is_enabled() ) {
33    bool dispatch_necessary = needs_asr_dispatching;
34
35    /*
36     * FIXME: This locking approach is brittle.  It only works since the
37     * current simple SMP scheduler has no support for the non-preempt mode.
38     */
39#if defined( RTEMS_SMP )
40    ISR_Level level;
41
42    _ISR_Disable_without_giant( level );
43#endif
44
45    if ( !_Thread_Is_heir( executing ) && executing->is_preemptible ) {
46      dispatch_necessary = true;
47      _Thread_Dispatch_necessary = dispatch_necessary;
48    }
49
50#if defined( RTEMS_SMP )
51    _ISR_Enable_without_giant( level );
52#endif
53
54    if ( dispatch_necessary ) {
55      _Thread_Dispatch();
56    }
57  }
58}
59
60rtems_status_code rtems_task_mode(
61  rtems_mode  mode_set,
62  rtems_mode  mask,
63  rtems_mode *previous_mode_set
64)
65{
66  Thread_Control     *executing;
67  RTEMS_API_Control  *api;
68  ASR_Information    *asr;
69  bool                needs_asr_dispatching;
70  rtems_mode          old_mode;
71
72  if ( !previous_mode_set )
73    return RTEMS_INVALID_ADDRESS;
74
75  executing     = _Thread_Get_executing();
76  api = executing->API_Extensions[ THREAD_API_RTEMS ];
77  asr = &api->Signal;
78
79  old_mode  = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
80
81  if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE )
82    old_mode |= RTEMS_NO_TIMESLICE;
83  else
84    old_mode |= RTEMS_TIMESLICE;
85
86  old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
87  old_mode |= _ISR_Get_level();
88
89  *previous_mode_set = old_mode;
90
91  /*
92   *  These are generic thread scheduling characteristics.
93   */
94  if ( mask & RTEMS_PREEMPT_MASK ) {
95#if defined( RTEMS_SMP )
96    if ( rtems_configuration_is_smp_enabled() &&
97         !_Modes_Is_preempt( mode_set ) ) {
98      return RTEMS_NOT_IMPLEMENTED;
99    }
100#endif
101
102    executing->is_preemptible = _Modes_Is_preempt( mode_set );
103  }
104
105  if ( mask & RTEMS_TIMESLICE_MASK ) {
106    if ( _Modes_Is_timeslice(mode_set) ) {
107      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
108      executing->cpu_time_budget  = _Thread_Ticks_per_timeslice;
109    } else
110      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
111  }
112
113  /*
114   *  Set the new interrupt level
115   */
116  if ( mask & RTEMS_INTERRUPT_MASK )
117    _Modes_Set_interrupt_level( mode_set );
118
119  /*
120   *  This is specific to the RTEMS API
121   */
122  needs_asr_dispatching = false;
123  if ( mask & RTEMS_ASR_MASK ) {
124    bool is_asr_enabled = !_Modes_Is_asr_disabled( mode_set );
125
126    if ( is_asr_enabled != asr->is_enabled ) {
127      asr->is_enabled = is_asr_enabled;
128      _ASR_Swap_signals( asr );
129      if ( _ASR_Are_signals_pending( asr ) ) {
130        needs_asr_dispatching = true;
131        _Thread_Add_post_switch_action(
132          executing,
133          &api->Signal_action
134        );
135      }
136    }
137  }
138
139  _RTEMS_Tasks_Dispatch_if_necessary( executing, needs_asr_dispatching );
140
141  return RTEMS_SUCCESSFUL;
142}
Note: See TracBrowser for help on using the repository browser.