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

4.115
Last change on this file since e6b31b27 was 4054c916, checked in by Sebastian Huber <sebastian.huber@…>, on 03/20/15 at 12:41:27

score: Add scheduler acquire/release

This is currently a global lock for all scheduler instances. It should
get replaced with one lock per scheduler instance in the future.

Update #2273.

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