Changeset d19cce29 in rtems for cpukit/score/src/threaddispatchdisablelevel.c
- Timestamp:
- 08/05/13 12:54:11 (11 years ago)
- Branches:
- 4.11, 5, master
- Children:
- c6c998b
- Parents:
- 8581725
- git-author:
- Sebastian Huber <sebastian.huber@…> (08/05/13 12:54:11)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (08/09/13 21:02:38)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/score/src/threaddispatchdisablelevel.c
r8581725 rd19cce29 16 16 */ 17 17 18 #include <rtems/system.h>19 #include <rtems/score/apiext.h>20 #include <rtems/score/context.h>21 #include <rtems/score/interr.h>22 #include <rtems/score/isr.h>23 #include <rtems/score/priority.h>24 18 #include <rtems/score/threaddispatch.h> 19 #include <rtems/score/assert.h> 25 20 26 21 #define NO_OWNER_CPU 0xffffffffU 27 22 28 void _Thread_Dispatch_initialization( void ) 23 typedef struct { 24 SMP_lock_Control lock; 25 uint32_t owner_cpu; 26 uint32_t nest_level; 27 } Giant_Control; 28 29 static Giant_Control _Giant = { 30 .lock = SMP_LOCK_INITIALIZER, 31 .owner_cpu = NO_OWNER_CPU, 32 .nest_level = 0 33 }; 34 35 static void _Giant_Do_acquire( uint32_t self_cpu_index ) 29 36 { 30 Thread_Dispatch_disable_level_lock_control *level_lock = 31 &_Thread_Dispatch_disable_level_lock; 37 Giant_Control *giant = &_Giant; 32 38 33 _Thread_Dispatch_disable_level = 0; 34 _SMP_lock_Initialize( &level_lock->lock ); 35 level_lock->owner_cpu = NO_OWNER_CPU; 36 _Thread_Dispatch_set_disable_level( 1 ); 39 if ( giant->owner_cpu != self_cpu_index ) { 40 _SMP_lock_Acquire( &giant->lock ); 41 giant->owner_cpu = self_cpu_index; 42 giant->nest_level = 1; 43 } else { 44 ++giant->nest_level; 45 } 37 46 } 38 47 39 uint32_t _Thread_Dispatch_get_disable_level(void)48 static void _Giant_Do_release( void ) 40 49 { 41 return _Thread_Dispatch_disable_level; 50 Giant_Control *giant = &_Giant; 51 52 --giant->nest_level; 53 if ( giant->nest_level == 0 ) { 54 giant->owner_cpu = NO_OWNER_CPU; 55 _SMP_lock_Release( &giant->lock ); 56 } 42 57 } 43 58 44 59 uint32_t _Thread_Dispatch_increment_disable_level( void ) 45 60 { 46 Thread_Dispatch_disable_level_lock_control *level_lock = 47 &_Thread_Dispatch_disable_level_lock; 61 Giant_Control *giant = &_Giant; 48 62 ISR_Level isr_level; 49 uint32_t self_cpu ;63 uint32_t self_cpu_index; 50 64 uint32_t disable_level; 65 Per_CPU_Control *self_cpu; 51 66 52 67 _ISR_Disable( isr_level ); 53 68 54 69 /* 55 * We must obtain the processor ID after interrupts are disabled since a56 * non-optimizing compiler may store the value on the stack and read it back.70 * We must obtain the processor ID after interrupts are disabled to prevent 71 * thread migration. 57 72 */ 58 self_cpu = _SMP_Get_current_processor();73 self_cpu_index = _SMP_Get_current_processor(); 59 74 60 if ( level_lock->owner_cpu != self_cpu ) { 61 _SMP_lock_Acquire( &level_lock->lock ); 62 level_lock->owner_cpu = self_cpu; 63 level_lock->nest_level = 1; 64 } else { 65 ++level_lock->nest_level; 66 } 75 _Giant_Do_acquire( self_cpu_index ); 67 76 68 disable_level = _Thread_Dispatch_disable_level; 77 self_cpu = _Per_CPU_Get_by_index( self_cpu_index ); 78 disable_level = self_cpu->thread_dispatch_disable_level; 69 79 ++disable_level; 70 _Thread_Dispatch_disable_level = disable_level;80 self_cpu->thread_dispatch_disable_level = disable_level; 71 81 72 82 _ISR_Enable( isr_level ); … … 77 87 uint32_t _Thread_Dispatch_decrement_disable_level( void ) 78 88 { 79 Thread_Dispatch_disable_level_lock_control *level_lock =80 &_Thread_Dispatch_disable_level_lock;81 89 ISR_Level isr_level; 82 90 uint32_t disable_level; 91 Per_CPU_Control *self_cpu; 83 92 84 93 _ISR_Disable( isr_level ); 85 94 86 disable_level = _Thread_Dispatch_disable_level; 95 self_cpu = _Per_CPU_Get(); 96 disable_level = self_cpu->thread_dispatch_disable_level; 87 97 --disable_level; 88 _Thread_Dispatch_disable_level = disable_level;98 self_cpu->thread_dispatch_disable_level = disable_level; 89 99 90 --level_lock->nest_level; 91 if ( level_lock->nest_level == 0 ) { 92 level_lock->owner_cpu = NO_OWNER_CPU; 93 _SMP_lock_Release( &level_lock->lock ); 94 } 100 _Giant_Do_release(); 95 101 96 102 _ISR_Enable( isr_level ); … … 111 117 uint32_t _Thread_Dispatch_set_disable_level(uint32_t value) 112 118 { 119 ISR_Level isr_level; 120 uint32_t disable_level; 121 122 _ISR_Disable( isr_level ); 123 disable_level = _Thread_Dispatch_disable_level; 124 _ISR_Enable( isr_level ); 125 113 126 /* 114 127 * If we need the dispatch level to go higher … … 116 129 */ 117 130 118 while ( value > _Thread_Dispatch_disable_level ) {119 _Thread_Dispatch_increment_disable_level();131 while ( value > disable_level ) { 132 disable_level = _Thread_Dispatch_increment_disable_level(); 120 133 } 121 134 … … 125 138 */ 126 139 127 while ( value < _Thread_Dispatch_disable_level ) {128 _Thread_Dispatch_decrement_disable_level();140 while ( value < disable_level ) { 141 disable_level = _Thread_Dispatch_decrement_disable_level(); 129 142 } 130 143 131 144 return value; 132 145 } 146 147 void _Giant_Acquire( void ) 148 { 149 ISR_Level isr_level; 150 151 _ISR_Disable( isr_level ); 152 _Assert( _Thread_Dispatch_disable_level != 0 ); 153 _Giant_Do_acquire( _SMP_Get_current_processor() ); 154 _ISR_Enable( isr_level ); 155 } 156 157 void _Giant_Release( void ) 158 { 159 ISR_Level isr_level; 160 161 _ISR_Disable( isr_level ); 162 _Assert( _Thread_Dispatch_disable_level != 0 ); 163 _Giant_Do_release(); 164 _ISR_Enable( isr_level ); 165 }
Note: See TracChangeset
for help on using the changeset viewer.