source: rtems/cpukit/rtems/src/taskmode.c @ 1ada3e55

5
Last change on this file since 1ada3e55 was 1ada3e55, checked in by Sebastian Huber <sebastian.huber@…>, on 02/15/20 at 10:09:16

score: Add _SMP_Need_inter_processor_interrupts()

Test for the proper system condition instead of using the
rtems_configuration_is_smp_enabled() workaround.

Update #3876.

  • Property mode set to 100644
File size: 3.9 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/tasksdata.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/smpimpl.h>
27#include <rtems/score/threadimpl.h>
28#include <rtems/config.h>
29
30rtems_status_code rtems_task_mode(
31  rtems_mode  mode_set,
32  rtems_mode  mask,
33  rtems_mode *previous_mode_set
34)
35{
36  ISR_lock_Context    lock_context;
37  Thread_Control     *executing;
38  RTEMS_API_Control  *api;
39  ASR_Information    *asr;
40  bool                preempt_enabled;
41  bool                needs_asr_dispatching;
42  rtems_mode          old_mode;
43
44  if ( !previous_mode_set )
45    return RTEMS_INVALID_ADDRESS;
46
47#if defined(RTEMS_SMP)
48  if (
49    ( mask & RTEMS_PREEMPT_MASK ) != 0
50      && !_Modes_Is_preempt( mode_set )
51      && rtems_configuration_is_smp_enabled()
52  ) {
53    return RTEMS_NOT_IMPLEMENTED;
54  }
55#endif
56
57#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
58  if (
59    ( mask & RTEMS_INTERRUPT_MASK ) != 0
60      && _Modes_Get_interrupt_level( mode_set ) != 0
61#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
62      && _SMP_Need_inter_processor_interrupts()
63#endif
64  ) {
65    return RTEMS_NOT_IMPLEMENTED;
66  }
67#endif
68
69  /*
70   * Complete all error checking before doing any operations which
71   * impact the executing thread. There should be no errors returned
72   * past this point.
73   */
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  preempt_enabled = false;
95  if ( mask & RTEMS_PREEMPT_MASK ) {
96    bool is_preempt_enabled = _Modes_Is_preempt( mode_set );
97
98    preempt_enabled = !executing->is_preemptible && is_preempt_enabled;
99    executing->is_preemptible = is_preempt_enabled;
100  }
101
102  if ( mask & RTEMS_TIMESLICE_MASK ) {
103    if ( _Modes_Is_timeslice(mode_set) ) {
104      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
105      executing->cpu_time_budget =
106        rtems_configuration_get_ticks_per_timeslice();
107    } else
108      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
109  }
110
111  /*
112   *  Set the new interrupt level
113   */
114  if ( mask & RTEMS_INTERRUPT_MASK ) {
115    _Modes_Set_interrupt_level( mode_set );
116  }
117
118  /*
119   *  This is specific to the RTEMS API
120   */
121  needs_asr_dispatching = false;
122  if ( mask & RTEMS_ASR_MASK ) {
123    bool is_asr_enabled = !_Modes_Is_asr_disabled( mode_set );
124
125    _Thread_State_acquire( executing, &lock_context );
126
127    if ( is_asr_enabled != asr->is_enabled ) {
128      asr->is_enabled = is_asr_enabled;
129
130      if ( _ASR_Swap_signals( asr ) != 0 ) {
131        needs_asr_dispatching = true;
132        _Thread_Add_post_switch_action(
133          executing,
134          &api->Signal_action,
135          _Signal_Action_handler
136        );
137      }
138    }
139
140    _Thread_State_release( executing, &lock_context );
141  }
142
143  if ( preempt_enabled || needs_asr_dispatching ) {
144    Per_CPU_Control  *cpu_self;
145
146    cpu_self = _Thread_Dispatch_disable();
147    _Thread_State_acquire( executing, &lock_context );
148    _Scheduler_Schedule( executing );
149    _Thread_State_release( executing, &lock_context );
150    _Thread_Dispatch_direct( cpu_self );
151  }
152
153  return RTEMS_SUCCESSFUL;
154}
Note: See TracBrowser for help on using the repository browser.