source: rtems/cpukit/rtems/src/taskmode.c @ e785fbaa

4.115
Last change on this file since e785fbaa was e785fbaa, checked in by Sebastian Huber <sebastian.huber@…>, on 04/04/14 at 11:58:26

score: Delete _Thread_Ticks_per_timeslice

Use the Configuration instead.

  • 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 =
109        rtems_configuration_get_ticks_per_timeslice();
110    } else
111      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
112  }
113
114  /*
115   *  Set the new interrupt level
116   */
117  if ( mask & RTEMS_INTERRUPT_MASK )
118    _Modes_Set_interrupt_level( mode_set );
119
120  /*
121   *  This is specific to the RTEMS API
122   */
123  needs_asr_dispatching = false;
124  if ( mask & RTEMS_ASR_MASK ) {
125    bool is_asr_enabled = !_Modes_Is_asr_disabled( mode_set );
126
127    if ( is_asr_enabled != asr->is_enabled ) {
128      asr->is_enabled = is_asr_enabled;
129      _ASR_Swap_signals( asr );
130      if ( _ASR_Are_signals_pending( asr ) ) {
131        needs_asr_dispatching = true;
132        _Thread_Add_post_switch_action(
133          executing,
134          &api->Signal_action
135        );
136      }
137    }
138  }
139
140  _RTEMS_Tasks_Dispatch_if_necessary( executing, needs_asr_dispatching );
141
142  return RTEMS_SUCCESSFUL;
143}
Note: See TracBrowser for help on using the repository browser.