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

5
Last change on this file since bd12dda was bd12dda, checked in by Sebastian Huber <sebastian.huber@…>, on 05/11/16 at 09:54:49

score: Use thread state lock for current state

In addition protect scheduler of thread by thread state lock. Enables
use of scheduler per-instance locks.

Update #2555.

  • Property mode set to 100644
File size: 3.4 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/rtems/signalimpl.h>
25#include <rtems/score/schedulerimpl.h>
26#include <rtems/score/threadimpl.h>
27#include <rtems/config.h>
28
29rtems_status_code rtems_task_mode(
30  rtems_mode  mode_set,
31  rtems_mode  mask,
32  rtems_mode *previous_mode_set
33)
34{
35  ISR_lock_Context    lock_context;
36  Thread_Control     *executing;
37  RTEMS_API_Control  *api;
38  ASR_Information    *asr;
39  bool                preempt_enabled;
40  bool                needs_asr_dispatching;
41  rtems_mode          old_mode;
42
43  if ( !previous_mode_set )
44    return RTEMS_INVALID_ADDRESS;
45
46  executing     = _Thread_Get_executing();
47  api = executing->API_Extensions[ THREAD_API_RTEMS ];
48  asr = &api->Signal;
49
50  old_mode  = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
51
52  if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE )
53    old_mode |= RTEMS_NO_TIMESLICE;
54  else
55    old_mode |= RTEMS_TIMESLICE;
56
57  old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
58  old_mode |= _ISR_Get_level();
59
60  *previous_mode_set = old_mode;
61
62  /*
63   *  These are generic thread scheduling characteristics.
64   */
65  preempt_enabled = false;
66  if ( mask & RTEMS_PREEMPT_MASK ) {
67#if defined( RTEMS_SMP )
68    if ( rtems_configuration_is_smp_enabled() &&
69         !_Modes_Is_preempt( mode_set ) ) {
70      return RTEMS_NOT_IMPLEMENTED;
71    }
72#endif
73    bool is_preempt_enabled = _Modes_Is_preempt( mode_set );
74
75    preempt_enabled = !executing->is_preemptible && is_preempt_enabled;
76    executing->is_preemptible = is_preempt_enabled;
77  }
78
79  if ( mask & RTEMS_TIMESLICE_MASK ) {
80    if ( _Modes_Is_timeslice(mode_set) ) {
81      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
82      executing->cpu_time_budget =
83        rtems_configuration_get_ticks_per_timeslice();
84    } else
85      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
86  }
87
88  /*
89   *  Set the new interrupt level
90   */
91  if ( mask & RTEMS_INTERRUPT_MASK )
92    _Modes_Set_interrupt_level( mode_set );
93
94  /*
95   *  This is specific to the RTEMS API
96   */
97  needs_asr_dispatching = false;
98  if ( mask & RTEMS_ASR_MASK ) {
99    bool is_asr_enabled = !_Modes_Is_asr_disabled( mode_set );
100
101    _Thread_State_acquire( executing, &lock_context );
102
103    if ( is_asr_enabled != asr->is_enabled ) {
104      asr->is_enabled = is_asr_enabled;
105
106      if ( _ASR_Swap_signals( asr ) != 0 ) {
107        needs_asr_dispatching = true;
108        _Thread_Add_post_switch_action(
109          executing,
110          &api->Signal_action,
111          _Signal_Action_handler
112        );
113      }
114    }
115
116    _Thread_State_release( executing, &lock_context );
117  }
118
119  if ( preempt_enabled || needs_asr_dispatching ) {
120    Per_CPU_Control  *cpu_self;
121
122    cpu_self = _Thread_Dispatch_disable();
123    _Thread_State_acquire( executing, &lock_context );
124    _Scheduler_Schedule( executing );
125    _Thread_State_release( executing, &lock_context );
126    _Thread_Dispatch_enable( cpu_self );
127  }
128
129  return RTEMS_SUCCESSFUL;
130}
Note: See TracBrowser for help on using the repository browser.