void _SMP_Request_other_cores_to_perform_first_context_switch(void) { int cpu; _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_UP; for (cpu=1 ; cpu < _SMP_Processor_count ; cpu++ ) { _SMP_Send_message( cpu, RTEMS_BSP_SMP_FIRST_TASK ); } }
static void test_send_message_while_processing_a_message( test_context *ctx ) { uint32_t cpu_count = rtems_get_processor_count(); uint32_t cpu_index_self = rtems_get_current_processor(); uint32_t cpu_index; SMP_barrier_State *bs = &ctx->main_barrier_state; _SMP_Set_test_message_handler(barrier_handler); for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { if (cpu_index != cpu_index_self) { _SMP_Send_message(cpu_index, SMP_MESSAGE_TEST); /* (A) */ barrier(ctx, bs); rtems_test_assert(ctx->counters[cpu_index].value == 1); _SMP_Send_message(cpu_index, SMP_MESSAGE_TEST); /* (B) */ barrier(ctx, bs); rtems_test_assert(ctx->counters[cpu_index].value == 1); /* (C) */ barrier(ctx, bs); /* (A) */ barrier(ctx, bs); rtems_test_assert(ctx->counters[cpu_index].value == 2); /* (B) */ barrier(ctx, bs); /* (C) */ barrier(ctx, bs); ctx->counters[cpu_index].value = 0; } } }
void _SMP_Send_message_multicast( const Processor_mask *targets, unsigned long message ) { uint32_t cpu_count = _SMP_Get_processor_count(); uint32_t cpu_index; for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) { if ( _Processor_mask_Is_set( targets, cpu_index ) ) { _SMP_Send_message( cpu_index, message ); } } }
void _SMP_Send_message_broadcast( unsigned long message ) { uint32_t cpu_count = _SMP_Get_processor_count(); uint32_t cpu_index_self = _SMP_Get_current_processor(); uint32_t cpu_index; _Assert( _Debug_Is_thread_dispatching_allowed() ); for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) { if ( cpu_index != cpu_index_self && _Processor_mask_Is_set( &_SMP_Online_processors, cpu_index ) ) { _SMP_Send_message( cpu_index, message ); } } }
void _SMP_Request_other_cores_to_dispatch(void) { int i; int cpu; cpu = bsp_smp_processor_id(); if ( !_System_state_Is_up (_System_state_Current) ) return; for (i=1 ; i < _SMP_Processor_count ; i++ ) { if ( cpu == i ) continue; if ( _Per_CPU_Information[i].state != RTEMS_BSP_SMP_CPU_UP ) continue; if ( !_Per_CPU_Information[i].dispatch_necessary ) continue; _SMP_Send_message( i, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY ); } }
static void test_send_message_flood( test_context *ctx ) { uint32_t cpu_count = rtems_get_processor_count(); uint32_t cpu_index_self = rtems_get_current_processor(); uint32_t cpu_index; _SMP_Set_test_message_handler(counter_handler); for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { uint32_t i; /* Wait 1us so that all outstanding messages have been processed */ rtems_counter_delay_nanoseconds(1000000); for (i = 0; i < cpu_count; ++i) { if (i != cpu_index) { ctx->copy_counters[i] = ctx->counters[i].value; } } for (i = 0; i < 100000; ++i) { _SMP_Send_message(cpu_index, SMP_MESSAGE_TEST); } for (i = 0; i < cpu_count; ++i) { if (i != cpu_index) { rtems_test_assert(ctx->copy_counters[i] == ctx->counters[i].value); } } } for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { printf( "inter-processor interrupts for processor %" PRIu32 "%s: %" PRIu32 "\n", cpu_index, cpu_index == cpu_index_self ? " (main)" : "", ctx->counters[cpu_index].value ); } }