forked from Imagelibrary/rtems
score: _Thread_Dispatch_disable_critical()
Thread dispatching is disabled in case interrupts are disabled. To get an accurate thread dispatch disabled time it is important to use the interrupt disabled instant in case a transition from an interrupt disabled section to a thread dispatch level section happens.
This commit is contained in:
@@ -84,7 +84,7 @@ void _Event_Seize(
|
||||
executing->Wait.return_argument = event_out;
|
||||
_Thread_Wait_flags_set( executing, intend_to_block );
|
||||
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
|
||||
_Thread_Lock_release_default( executing, lock_context );
|
||||
_Giant_Acquire( cpu_self );
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ void _Event_Surrender(
|
||||
if ( unblock ) {
|
||||
Per_CPU_Control *cpu_self;
|
||||
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
|
||||
_Thread_Lock_release_default( the_thread, lock_context );
|
||||
_Giant_Acquire( cpu_self );
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@ RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(
|
||||
if ( current > ceiling ) {
|
||||
Per_CPU_Control *cpu_self;
|
||||
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
|
||||
_Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
|
||||
_Thread_Raise_priority( executing, ceiling );
|
||||
_Thread_Dispatch_enable( cpu_self );
|
||||
|
||||
@@ -68,6 +68,12 @@ typedef struct {
|
||||
#else
|
||||
ISR_Level isr_level;
|
||||
#endif
|
||||
#if defined( RTEMS_PROFILING )
|
||||
/**
|
||||
* @brief The last interrupt disable instant in CPU counter ticks.
|
||||
*/
|
||||
CPU_Counter_ticks ISR_disable_instant;
|
||||
#endif
|
||||
} ISR_lock_Context;
|
||||
|
||||
/**
|
||||
@@ -304,6 +310,13 @@ typedef struct {
|
||||
_ISR_Flash( ( _context )->isr_level )
|
||||
#endif
|
||||
|
||||
#if defined( RTEMS_PROFILING )
|
||||
#define _ISR_lock_ISR_disable_profile( _context ) \
|
||||
( _context )->ISR_disable_instant = _CPU_Counter_read();
|
||||
#else
|
||||
#define _ISR_lock_ISR_disable_profile( _context )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Disables interrupts and saves the previous interrupt state in the ISR
|
||||
* lock context.
|
||||
@@ -316,10 +329,16 @@ typedef struct {
|
||||
*/
|
||||
#if defined( RTEMS_SMP )
|
||||
#define _ISR_lock_ISR_disable( _context ) \
|
||||
_ISR_Disable_without_giant( ( _context )->Lock_context.isr_level )
|
||||
do { \
|
||||
_ISR_Disable_without_giant( ( _context )->Lock_context.isr_level ); \
|
||||
_ISR_lock_ISR_disable_profile( _context ) \
|
||||
} while ( 0 )
|
||||
#else
|
||||
#define _ISR_lock_ISR_disable( _context ) \
|
||||
_ISR_Disable( ( _context )->isr_level )
|
||||
do { \
|
||||
_ISR_Disable( ( _context )->isr_level ); \
|
||||
_ISR_lock_ISR_disable_profile( _context ) \
|
||||
} while ( 0 )
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,7 +102,7 @@ RTEMS_INLINE_ROUTINE void _MRSP_Claim_ownership(
|
||||
mrsp->initial_priority_of_owner = initial_priority;
|
||||
_Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
|
||||
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
|
||||
_ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
|
||||
|
||||
_Thread_Raise_priority( new_owner, ceiling_priority );
|
||||
@@ -230,7 +230,7 @@ RTEMS_INLINE_ROUTINE MRSP_Status _MRSP_Wait_for_ownership(
|
||||
|
||||
_MRSP_Giant_release( &giant_lock_context );
|
||||
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
|
||||
_ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
|
||||
|
||||
_Thread_Raise_priority( executing, ceiling_priority );
|
||||
@@ -388,7 +388,7 @@ RTEMS_INLINE_ROUTINE MRSP_Status _MRSP_Release(
|
||||
|
||||
_MRSP_Giant_release( &giant_lock_context );
|
||||
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
|
||||
_ISR_lock_Release_and_ISR_enable( &mrsp->Lock, lock_context );
|
||||
|
||||
_MRSP_Restore_priority( executing, initial_priority );
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define _RTEMS_SCORE_PROFILING
|
||||
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <rtems/score/isrlock.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -55,6 +56,26 @@ static inline void _Profiling_Thread_dispatch_disable(
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void _Profiling_Thread_dispatch_disable_critical(
|
||||
Per_CPU_Control *cpu,
|
||||
uint32_t previous_thread_dispatch_disable_level,
|
||||
const ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
#if defined( RTEMS_PROFILING )
|
||||
if ( previous_thread_dispatch_disable_level == 0 ) {
|
||||
Per_CPU_Stats *stats = &cpu->Stats;
|
||||
|
||||
stats->thread_dispatch_disabled_instant = lock_context->ISR_disable_instant;
|
||||
++stats->thread_dispatch_disabled_count;
|
||||
}
|
||||
#else
|
||||
(void) cpu;
|
||||
(void) previous_thread_dispatch_disable_level;
|
||||
(void) lock_context;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void _Profiling_Thread_dispatch_enable(
|
||||
Per_CPU_Control *cpu,
|
||||
uint32_t new_thread_dispatch_disable_level
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define _RTEMS_SCORE_THREADDISPATCH_H
|
||||
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <rtems/score/smplock.h>
|
||||
#include <rtems/score/isrlock.h>
|
||||
#include <rtems/score/profiling.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -242,16 +242,25 @@ void _Thread_Do_dispatch( Per_CPU_Control *cpu_self, ISR_Level level );
|
||||
*
|
||||
* This function does not acquire the Giant lock.
|
||||
*
|
||||
* @param[in] lock_context The lock context of the corresponding
|
||||
* _ISR_lock_ISR_disable() that started the critical section.
|
||||
*
|
||||
* @return The current processor.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable_critical( void )
|
||||
RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable_critical(
|
||||
const ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
Per_CPU_Control *cpu_self;
|
||||
uint32_t disable_level;
|
||||
|
||||
cpu_self = _Per_CPU_Get();
|
||||
disable_level = cpu_self->thread_dispatch_disable_level;
|
||||
_Profiling_Thread_dispatch_disable( cpu_self, disable_level );
|
||||
_Profiling_Thread_dispatch_disable_critical(
|
||||
cpu_self,
|
||||
disable_level,
|
||||
lock_context
|
||||
);
|
||||
cpu_self->thread_dispatch_disable_level = disable_level + 1;
|
||||
|
||||
return cpu_self;
|
||||
@@ -267,17 +276,16 @@ RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable_critical( void )
|
||||
RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable( void )
|
||||
{
|
||||
Per_CPU_Control *cpu_self;
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
#if defined( RTEMS_SMP ) || defined( RTEMS_PROFILING )
|
||||
ISR_Level level;
|
||||
|
||||
_ISR_Disable_without_giant( level );
|
||||
_ISR_lock_ISR_disable( &lock_context );
|
||||
#endif
|
||||
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
|
||||
|
||||
#if defined( RTEMS_SMP ) || defined( RTEMS_PROFILING )
|
||||
_ISR_Enable_without_giant( level );
|
||||
_ISR_lock_ISR_enable( &lock_context );
|
||||
#endif
|
||||
|
||||
return cpu_self;
|
||||
|
||||
@@ -67,7 +67,7 @@ void _Thread_queue_Enqueue_critical(
|
||||
( *operations->enqueue )( the_thread_queue, the_thread );
|
||||
|
||||
_Thread_Wait_flags_set( the_thread, THREAD_QUEUE_INTEND_TO_BLOCK );
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
|
||||
_Thread_queue_Release( the_thread_queue, lock_context );
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
@@ -138,7 +138,7 @@ void _Thread_queue_Unblock_critical(
|
||||
if ( unblock ) {
|
||||
Per_CPU_Control *cpu_self;
|
||||
|
||||
cpu_self = _Thread_Dispatch_disable_critical();
|
||||
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
|
||||
_Thread_queue_Release( the_thread_queue, lock_context );
|
||||
|
||||
_Thread_queue_Unblock( the_thread );
|
||||
|
||||
Reference in New Issue
Block a user