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

Last change on this file was b3b6d21e, checked in by Joel Sherrill <joel@…>, on 02/16/22 at 22:28:59

cpukit/rtems/src/[s-z]*.c: Change license to BSD-2

Updates #3053.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSImplClassicTask
7 *
8 * @brief This source file contains the implementation of
9 *   rtems_task_mode().
10 */
11
12/*
13 *  COPYRIGHT (c) 1989-2014.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 *    notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in the
23 *    documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifdef HAVE_CONFIG_H
39#include "config.h"
40#endif
41
42#include <rtems/rtems/tasksdata.h>
43#include <rtems/rtems/modesimpl.h>
44#include <rtems/rtems/signalimpl.h>
45#include <rtems/score/isrlevel.h>
46#include <rtems/score/schedulerimpl.h>
47#include <rtems/score/smpimpl.h>
48#include <rtems/score/threadimpl.h>
49
50rtems_status_code rtems_task_mode(
51  rtems_mode  mode_set,
52  rtems_mode  mask,
53  rtems_mode *previous_mode_set
54)
55{
56  Thread_Control     *executing;
57  RTEMS_API_Control  *api;
58  ASR_Information    *asr;
59  rtems_mode          old_mode;
60
61  executing = _Thread_Get_executing();
62
63  if ( !previous_mode_set )
64    return RTEMS_INVALID_ADDRESS;
65
66#if defined(RTEMS_SMP)
67  if (
68    ( mask & RTEMS_PREEMPT_MASK ) != 0 &&
69    !_Modes_Is_preempt_mode_supported( mode_set, executing )
70  ) {
71    return RTEMS_NOT_IMPLEMENTED;
72  }
73#endif
74
75#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
76  if (
77    ( mask & RTEMS_INTERRUPT_MASK ) != 0 &&
78    !_Modes_Is_interrupt_level_supported( mode_set )
79  ) {
80    return RTEMS_NOT_IMPLEMENTED;
81  }
82#endif
83
84  /*
85   * Complete all error checking before doing any operations which
86   * impact the executing thread. There should be no errors returned
87   * past this point.
88   */
89
90  api = executing->API_Extensions[ THREAD_API_RTEMS ];
91  asr = &api->Signal;
92
93  old_mode  = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
94
95  if ( executing->CPU_budget.operations == NULL )
96    old_mode |= RTEMS_NO_TIMESLICE;
97  else
98    old_mode |= RTEMS_TIMESLICE;
99
100  old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
101  old_mode |= _ISR_Get_level();
102
103  *previous_mode_set = old_mode;
104
105  if ( ( mask & RTEMS_TIMESLICE_MASK ) != 0 ) {
106    _Modes_Apply_timeslice_to_thread( mode_set, executing );
107  }
108
109  if ( ( mask & RTEMS_INTERRUPT_MASK ) != 0 ) {
110    _ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) );
111  }
112
113  if ( ( mask & ( RTEMS_ASR_MASK | RTEMS_PREEMPT_MASK ) ) != 0 ) {
114    bool             need_thread_dispatch;
115    ISR_lock_Context lock_context;
116
117    need_thread_dispatch = false;
118
119    _Thread_State_acquire( executing, &lock_context );
120
121    if ( ( mask & RTEMS_ASR_MASK ) != 0 ) {
122      bool previous_asr_is_enabled;
123
124      previous_asr_is_enabled = asr->is_enabled;
125      asr->is_enabled = !_Modes_Is_asr_disabled( mode_set );
126
127      if (
128        !previous_asr_is_enabled &&
129          asr->is_enabled &&
130          asr->signals_pending != 0
131      ) {
132        need_thread_dispatch = true;
133        _Thread_Append_post_switch_action( executing, &api->Signal_action );
134      }
135    }
136
137    if ( ( mask & RTEMS_PREEMPT_MASK ) != 0 ) {
138      bool previous_is_preemptible;
139
140      previous_is_preemptible = executing->is_preemptible;
141      executing->is_preemptible = _Modes_Is_preempt( mode_set );
142
143      if ( executing->is_preemptible && !previous_is_preemptible ) {
144        need_thread_dispatch = true;
145        _Scheduler_Schedule( executing );
146      }
147    }
148
149    if ( need_thread_dispatch ) {
150      Per_CPU_Control *cpu_self;
151
152      cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
153      _Thread_State_release( executing, &lock_context );
154      _Thread_Dispatch_direct( cpu_self );
155    } else {
156      _Thread_State_release( executing, &lock_context );
157    }
158  }
159
160  return RTEMS_SUCCESSFUL;
161}
Note: See TracBrowser for help on using the repository browser.