File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include <rtems/rtems/tasksdata.h>
0043 #include <rtems/rtems/modesimpl.h>
0044 #include <rtems/rtems/signalimpl.h>
0045 #include <rtems/score/isrlevel.h>
0046 #include <rtems/score/schedulerimpl.h>
0047 #include <rtems/score/smpimpl.h>
0048 #include <rtems/score/threadimpl.h>
0049
0050 rtems_status_code rtems_task_mode(
0051 rtems_mode mode_set,
0052 rtems_mode mask,
0053 rtems_mode *previous_mode_set
0054 )
0055 {
0056 Thread_Control *executing;
0057 RTEMS_API_Control *api;
0058 ASR_Information *asr;
0059 rtems_mode old_mode;
0060
0061 executing = _Thread_Get_executing();
0062
0063 if ( !previous_mode_set )
0064 return RTEMS_INVALID_ADDRESS;
0065
0066 #if defined(RTEMS_SMP)
0067 if (
0068 ( mask & RTEMS_PREEMPT_MASK ) != 0 &&
0069 !_Modes_Is_preempt_mode_supported( mode_set, executing )
0070 ) {
0071 return RTEMS_NOT_IMPLEMENTED;
0072 }
0073 #endif
0074
0075 #if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
0076 if (
0077 ( mask & RTEMS_INTERRUPT_MASK ) != 0 &&
0078 !_Modes_Is_interrupt_level_supported( mode_set )
0079 ) {
0080 return RTEMS_NOT_IMPLEMENTED;
0081 }
0082 #endif
0083
0084
0085
0086
0087
0088
0089
0090 api = executing->API_Extensions[ THREAD_API_RTEMS ];
0091 asr = &api->Signal;
0092
0093 old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
0094
0095 if ( executing->CPU_budget.operations == NULL )
0096 old_mode |= RTEMS_NO_TIMESLICE;
0097 else
0098 old_mode |= RTEMS_TIMESLICE;
0099
0100 old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
0101 old_mode |= _ISR_Get_level();
0102
0103 *previous_mode_set = old_mode;
0104
0105 if ( ( mask & RTEMS_TIMESLICE_MASK ) != 0 ) {
0106 _Modes_Apply_timeslice_to_thread( mode_set, executing );
0107 }
0108
0109 if ( ( mask & RTEMS_INTERRUPT_MASK ) != 0 ) {
0110 _ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) );
0111 }
0112
0113 if ( ( mask & ( RTEMS_ASR_MASK | RTEMS_PREEMPT_MASK ) ) != 0 ) {
0114 bool need_thread_dispatch;
0115 ISR_lock_Context lock_context;
0116
0117 need_thread_dispatch = false;
0118
0119 _Thread_State_acquire( executing, &lock_context );
0120
0121 if ( ( mask & RTEMS_ASR_MASK ) != 0 ) {
0122 bool previous_asr_is_enabled;
0123
0124 previous_asr_is_enabled = asr->is_enabled;
0125 asr->is_enabled = !_Modes_Is_asr_disabled( mode_set );
0126
0127 if (
0128 !previous_asr_is_enabled &&
0129 asr->is_enabled &&
0130 asr->signals_pending != 0
0131 ) {
0132 need_thread_dispatch = true;
0133 _Thread_Append_post_switch_action( executing, &api->Signal_action );
0134 }
0135 }
0136
0137 if ( ( mask & RTEMS_PREEMPT_MASK ) != 0 ) {
0138 bool previous_is_preemptible;
0139
0140 previous_is_preemptible = executing->is_preemptible;
0141 executing->is_preemptible = _Modes_Is_preempt( mode_set );
0142
0143 if ( executing->is_preemptible && !previous_is_preemptible ) {
0144 need_thread_dispatch = true;
0145 _Scheduler_Schedule( executing );
0146 }
0147 }
0148
0149 if ( need_thread_dispatch ) {
0150 Per_CPU_Control *cpu_self;
0151
0152 cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
0153 _Thread_State_release( executing, &lock_context );
0154 _Thread_Dispatch_direct( cpu_self );
0155 } else {
0156 _Thread_State_release( executing, &lock_context );
0157 }
0158 }
0159
0160 return RTEMS_SUCCESSFUL;
0161 }