19 #ifndef _RTEMS_PERCPU_H 20 #define _RTEMS_PERCPU_H 39 #if defined(RTEMS_SMP) 40 #if defined(RTEMS_PROFILING) 41 #define PER_CPU_CONTROL_SIZE_APPROX \ 42 ( 512 + CPU_PER_CPU_CONTROL_SIZE + CPU_INTERRUPT_FRAME_SIZE ) 43 #elif defined(RTEMS_DEBUG) || CPU_SIZEOF_POINTER > 4 44 #define PER_CPU_CONTROL_SIZE_APPROX \ 45 ( 256 + CPU_PER_CPU_CONTROL_SIZE + CPU_INTERRUPT_FRAME_SIZE ) 47 #define PER_CPU_CONTROL_SIZE_APPROX \ 48 ( 180 + CPU_PER_CPU_CONTROL_SIZE + CPU_INTERRUPT_FRAME_SIZE ) 57 #if PER_CPU_CONTROL_SIZE_APPROX > 1024 58 #define PER_CPU_CONTROL_SIZE_LOG2 11 59 #elif PER_CPU_CONTROL_SIZE_APPROX > 512 60 #define PER_CPU_CONTROL_SIZE_LOG2 10 61 #elif PER_CPU_CONTROL_SIZE_APPROX > 256 62 #define PER_CPU_CONTROL_SIZE_LOG2 9 63 #elif PER_CPU_CONTROL_SIZE_APPROX > 128 64 #define PER_CPU_CONTROL_SIZE_LOG2 8 66 #define PER_CPU_CONTROL_SIZE_LOG2 7 69 #define PER_CPU_CONTROL_SIZE ( 1 << PER_CPU_CONTROL_SIZE_LOG2 ) 74 struct Record_Control;
93 #if defined( RTEMS_SMP ) 176 typedef void ( *Per_CPU_Job_handler )(
void *arg );
188 Per_CPU_Job_handler handler;
201 #define PER_CPU_JOB_DONE 1 237 #if defined( RTEMS_PROFILING ) 243 CPU_Counter_ticks thread_dispatch_disabled_instant;
249 CPU_Counter_ticks max_thread_dispatch_disabled_time;
258 CPU_Counter_ticks max_interrupt_time;
264 CPU_Counter_ticks max_interrupt_delay;
272 uint64_t thread_dispatch_disabled_count;
283 uint64_t total_thread_dispatch_disabled_time;
291 uint64_t interrupt_count;
301 uint64_t total_interrupt_time;
348 #if CPU_PER_CPU_CONTROL_SIZE > 0 407 bool reserved_for_executing_alignment[ 3 ];
438 #if defined(RTEMS_SMP) 477 #if defined( RTEMS_SMP ) 598 struct Record_Control *record;
603 #if defined( RTEMS_SMP ) 606 char unused_space_for_cache_line_alignment
622 #define _Per_CPU_Acquire( cpu, lock_context ) \ 623 _ISR_lock_Acquire( &( cpu )->Lock, lock_context ) 625 #define _Per_CPU_Release( cpu, lock_context ) \ 626 _ISR_lock_Release( &( cpu )->Lock, lock_context ) 635 #if defined( _CPU_Get_current_per_CPU_control ) 636 #define _Per_CPU_Get_snapshot() _CPU_Get_current_per_CPU_control() 638 #define _Per_CPU_Get_snapshot() \ 639 ( &_Per_CPU_Information[ _SMP_Get_current_processor() ].per_cpu ) 642 #if defined( RTEMS_SMP ) 654 #define _Per_CPU_Get() _Per_CPU_Get_snapshot() 659 return &_Per_CPU_Information[ index ].per_cpu;
662 static inline uint32_t _Per_CPU_Get_index(
const Per_CPU_Control *cpu )
664 #if defined(RTEMS_SMP) 668 return ( uint32_t ) ( per_cpu_envelope - &_Per_CPU_Information[ 0 ] );
682 static inline bool _Per_CPU_Is_processor_online(
686 #if defined( RTEMS_SMP ) 695 static inline bool _Per_CPU_Is_boot_processor(
699 #if defined( RTEMS_SMP ) 712 #if defined(RTEMS_SMP) 717 cpu_max = _SMP_Get_processor_maximum();
718 previous_cpu = _Per_CPU_Get_by_index( 0 );
721 _Per_CPU_Acquire( previous_cpu, lock_context );
723 for ( cpu_index = 1 ; cpu_index < cpu_max ; ++cpu_index ) {
726 cpu = _Per_CPU_Get_by_index( cpu_index );
739 #if defined(RTEMS_SMP) 744 cpu_max = _SMP_Get_processor_maximum();
745 cpu = _Per_CPU_Get_by_index( cpu_max - 1 );
747 for ( cpu_index = cpu_max - 1 ; cpu_index > 0 ; --cpu_index ) {
750 previous_cpu = _Per_CPU_Get_by_index( cpu_index - 1 );
755 _Per_CPU_Release( cpu, lock_context );
762 #if defined( RTEMS_SMP ) 771 void _Per_CPU_State_change(
803 uint32_t timeout_in_ns
846 #define _Thread_Dispatch_disable_level \ 847 _Per_CPU_Get()->thread_dispatch_disable_level 848 #define _Thread_Heir \ 851 #if defined(_CPU_Get_thread_executing) 852 #define _Thread_Executing \ 853 _CPU_Get_thread_executing() 855 #define _Thread_Executing \ 856 _Per_CPU_Get_executing( _Per_CPU_Get() ) 859 #define _ISR_Nest_level \ 860 _Per_CPU_Get()->isr_nest_level 861 #define _CPU_Interrupt_stack_low \ 862 _Per_CPU_Get()->interrupt_stack_low 863 #define _CPU_Interrupt_stack_high \ 864 _Per_CPU_Get()->interrupt_stack_high 865 #define _Thread_Dispatch_necessary \ 866 _Per_CPU_Get()->dispatch_necessary 882 #if defined(RTEMS_SMP) && !defined(_CPU_Get_thread_executing) 890 #if defined(RTEMS_SMP) && !defined(_CPU_Get_thread_executing) 901 #if defined( ASM ) || defined( _RTEMS_PERCPU_DEFINE_OFFSETS ) 903 #define PER_CPU_INTERRUPT_STACK_LOW \ 904 CPU_PER_CPU_CONTROL_SIZE 905 #define PER_CPU_INTERRUPT_STACK_HIGH \ 906 PER_CPU_INTERRUPT_STACK_LOW + CPU_SIZEOF_POINTER 908 #define INTERRUPT_STACK_LOW \ 909 (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_LOW) 910 #define INTERRUPT_STACK_HIGH \ 911 (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_HIGH) 916 #define PER_CPU_ISR_NEST_LEVEL \ 917 PER_CPU_INTERRUPT_STACK_HIGH + CPU_SIZEOF_POINTER 918 #define PER_CPU_ISR_DISPATCH_DISABLE \ 919 PER_CPU_ISR_NEST_LEVEL + 4 920 #define PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL \ 921 PER_CPU_ISR_DISPATCH_DISABLE + 4 922 #define PER_CPU_DISPATCH_NEEDED \ 923 PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL + 4 924 #define PER_CPU_OFFSET_EXECUTING \ 925 PER_CPU_DISPATCH_NEEDED + 4 926 #define PER_CPU_OFFSET_HEIR \ 927 PER_CPU_OFFSET_EXECUTING + CPU_SIZEOF_POINTER 928 #if defined(RTEMS_SMP) 929 #define PER_CPU_INTERRUPT_FRAME_AREA \ 930 PER_CPU_OFFSET_HEIR + CPU_SIZEOF_POINTER 933 #define THREAD_DISPATCH_DISABLE_LEVEL \ 934 (SYM(_Per_CPU_Information) + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL) 935 #define ISR_NEST_LEVEL \ 936 (SYM(_Per_CPU_Information) + PER_CPU_ISR_NEST_LEVEL) 937 #define DISPATCH_NEEDED \ 938 (SYM(_Per_CPU_Information) + PER_CPU_DISPATCH_NEEDED) The per CPU controls are initialized to zero.
void * interrupt_stack_high
The interrupt stack high address for this processor.
void _Per_CPU_Perform_jobs(Per_CPU_Control *cpu)
Performs the jobs of the specified processor in FIFO order.
Index for realtime clock per-CPU watchdog header.
int64_t Timestamp_Control
Processor is ready to start multitasking.
bool _Per_CPU_State_wait_for_non_initial_state(uint32_t cpu_index, uint32_t timeout_in_ns)
Waits for a processor to change into a non-initial state.
struct Per_CPU_Job ** tail
Tail of the FIFO list of jobs to be performed by this processor.
void _Per_CPU_Wait_for_job(const Per_CPU_Control *cpu, const Per_CPU_Job *job)
Waits for the job carried out by the specified processor.
Count of per-CPU watchdog headers.
Watchdog_Header Header[PER_CPU_WATCHDOG_COUNT]
Header for watchdogs.
#define _ISR_Local_disable(_level)
Disables interrupts on this processor.
struct _Thread_Control * executing
This is the thread executing on this processor.
struct Per_CPU_Control::@15 Jobs
FIFO list of jobs to be performed by this processor.
ISR_lock_Control Lock
This lock protects some members of this structure.
struct _Thread_Control * idle_if_online_and_unused
The idle thread for this processor in case it is online and currently not used by a scheduler instanc...
uint64_t ticks
Protects all watchdog operations on this processor.
bool boot
Indicates if the processor is the one that performed the initial system initialization.
Interrupt stack frame (ISF).
Helpers for Manipulating Timestamps.
#define _ISR_lock_ISR_enable(_context)
Restores the saved interrupt state of the ISR lock context.
Thread_Scheduler_control Scheduler
Scheduler related control.
const struct Scheduler_Context * context
The scheduler context of the scheduler owning this processor.
struct _Thread_Control * ancestor
The ancestor of the executing thread.
Constants and Structures Associated with Watchdog Timers.
Per_CPU_Control_envelope _Per_CPU_Information [] CPU_STRUCTURE_ALIGNMENT
Set of Per CPU Core Information.
Chain_Control Threads_in_need_for_help
Chain of threads in need for help.
static __inline__ struct _Thread_Control * _Thread_Get_executing(void)
Returns the thread control block of the executing thread.
#define _ISR_Get_level()
Return current interrupt level.
Timestamp_Control cpu_usage_timestamp
The CPU usage timestamp contains the time point of the last heir thread change or last CPU usage upda...
SuperCore SMP Support API.
Information for the Assert Handler.
Per_CPU_Watchdog_index
Per-CPU watchdog header index.
void * arg
The job handler argument.
void _Per_CPU_Initialize(void)
Allocate and Initialize Per CPU Structures.
#define ISR_LOCK_MEMBER(_designator)
Defines an ISR lock member.
char * data
Begin of the per-CPU data area.
Address the Problems Caused by Incompatible Flavor of Assemblers and Toolsets.
CPU Port Implementation API.
void _Per_CPU_Add_job(Per_CPU_Control *cpu, Per_CPU_Job *job)
Adds the job to the tail of the processing list of the specified processor.
#define _ISR_Local_enable(_level)
Enables interrupts on this processor.
Context for per-processor jobs.
struct Per_CPU_Control::@13 Watchdog
Watchdog state for this processor.
void * interrupt_stack_low
The interrupt stack low address for this processor.
const struct _Scheduler_Control * control
The scheduler control of the scheduler owning this processor.
bool online
Indicates if the processor has been successfully started via _CPU_SMP_Start_processor().
Atomic_Ulong done
Indication if the job is done.
ISR_lock_Context Lock_context
Lock context used to acquire all per-CPU locks.
uint32_t isr_dispatch_disable
Indicates if an ISR thread dispatch is disabled.
struct Per_CPU_Job * next
The next job in the corresponding per-processor job list.
volatile bool dispatch_necessary
This is set to true when this processor needs to run the thread dispatcher.
const Per_CPU_Job_context * context
Pointer to the job context to get the handler and argument.
Per_CPU_State state
Indicates the current state of the CPU.
struct _Thread_Control * heir
This is the heir thread for this processor.
struct Per_CPU_Control Per_CPU_Control
Per CPU Core Structure.
struct Per_CPU_Job Per_CPU_Job
A per-processor job.
This is the terminal state.
Normal multitasking state.
Per_CPU_State
State of a processor.
volatile uint32_t thread_dispatch_disable_level
The thread dispatch critical section nesting counter which is used to prevent context switches at ino...
#define _ISR_lock_ISR_disable(_context)
Disables interrupts and saves the previous interrupt state in the ISR lock context.
Index for monotonic clock per-CPU watchdog header.
Atomic_Ulong message
Bit field for SMP messages.
Local ISR lock context for acquire and release pairs.
#define RTEMS_INLINE_ROUTINE
Gives a hint to the compiler in a function declaration to inline this function.
Index for tick clock per-CPU watchdog header.
struct Per_CPU_Job * head
Head of the FIFO list of jobs to be performed by this processor.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Multitasking start of processor is requested.