void _SMP_Multicast_actions_process( void ) { SMP_lock_Context lock_context; uint32_t cpu_self_index; SMP_Multicast_action *node; SMP_Multicast_action *next; _SMP_lock_ISR_disable_and_acquire( &_SMP_Multicast.Lock, &lock_context ); cpu_self_index = _SMP_Get_current_processor(); node = (SMP_Multicast_action *) _Chain_First( &_SMP_Multicast.Actions ); while ( !_Chain_Is_tail( &_SMP_Multicast.Actions, &node->Node ) ) { next = (SMP_Multicast_action *) _Chain_Next( &node->Node ); if ( _Processor_mask_Is_set( &node->targets, cpu_self_index ) ) { _Processor_mask_Clear( &node->targets, cpu_self_index ); ( *node->handler )( node->arg ); if ( _Processor_mask_Is_zero( &node->targets ) ) { _Chain_Extract_unprotected( &node->Node ); _Atomic_Store_ulong( &node->done, 1, ATOMIC_ORDER_RELEASE ); } } node = next; } _SMP_lock_Release_and_ISR_enable( &_SMP_Multicast.Lock, &lock_context ); }
static void test_simple_atomic_add_body(test_context *ctx) { unsigned int ia = 8, ib = 4; unsigned int ic; uintptr_t pa = 42, pb = 24; uintptr_t pc; unsigned long a = 2, b = 1; unsigned long c; puts("=== atomic simple add test case ==="); _Atomic_Store_uint(&ctx->uint_atomic, ia, ATOMIC_ORDER_RELAXED); _Atomic_Fetch_add_uint(&ctx->uint_atomic, ib, ATOMIC_ORDER_RELAXED); ic = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(ic == (ia + ib)); _Atomic_Store_uintptr(&ctx->uintptr_atomic, pa, ATOMIC_ORDER_RELAXED); _Atomic_Fetch_add_uintptr(&ctx->uintptr_atomic, pb, ATOMIC_ORDER_RELAXED); pc = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(pc == (pa + pb)); _Atomic_Store_ulong(&ctx->ulong_atomic, a, ATOMIC_ORDER_RELAXED); _Atomic_Fetch_add_ulong(&ctx->ulong_atomic, b, ATOMIC_ORDER_RELAXED); c = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(c == (a + b)); }
static void test_simple_atomic_exchange_body(test_context *ctx) { unsigned int ia = 8, ib = 4; unsigned int ic; uintptr_t pa = 42, pb = 24; uintptr_t pc; unsigned long a = 2, b = 1; unsigned long c; puts("=== atomic simple exchange test case ==="); _Atomic_Store_uint(&ctx->uint_atomic, ia, ATOMIC_ORDER_RELAXED); ic = _Atomic_Exchange_uint(&ctx->uint_atomic, ib, ATOMIC_ORDER_RELAXED); rtems_test_assert(ic == ia); ic = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(ic == ib); _Atomic_Store_uintptr(&ctx->uintptr_atomic, pa, ATOMIC_ORDER_RELAXED); pc = _Atomic_Exchange_uintptr(&ctx->uintptr_atomic, pb, ATOMIC_ORDER_RELAXED); rtems_test_assert(pc == pa); pc = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(pc == pb); _Atomic_Store_ulong(&ctx->ulong_atomic, a, ATOMIC_ORDER_RELAXED); c = _Atomic_Exchange_ulong(&ctx->ulong_atomic, b, ATOMIC_ORDER_RELAXED); rtems_test_assert(c == a); c = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(c == b); }
void _SMP_Multicast_action( const size_t setsize, const cpu_set_t *cpus, SMP_Action_handler handler, void *arg ) { SMP_Multicast_action node; Processor_mask targets; SMP_lock_Context lock_context; uint32_t i; if ( ! _System_state_Is_up( _System_state_Get() ) ) { ( *handler )( arg ); return; } if( cpus == NULL ) { _Processor_mask_Assign( &targets, _SMP_Get_online_processors() ); } else { _Processor_mask_Zero( &targets ); for ( i = 0; i < _SMP_Get_processor_count(); ++i ) { if ( CPU_ISSET_S( i, setsize, cpus ) ) { _Processor_mask_Set( &targets, i ); } } } _Chain_Initialize_node( &node.Node ); node.handler = handler; node.arg = arg; _Processor_mask_Assign( &node.targets, &targets ); _Atomic_Store_ulong( &node.done, 0, ATOMIC_ORDER_RELAXED ); _SMP_lock_ISR_disable_and_acquire( &_SMP_Multicast.Lock, &lock_context ); _Chain_Prepend_unprotected( &_SMP_Multicast.Actions, &node.Node ); _SMP_lock_Release_and_ISR_enable( &_SMP_Multicast.Lock, &lock_context ); _SMP_Send_message_multicast( &targets, SMP_MESSAGE_MULTICAST_ACTION ); _SMP_Multicasts_try_process(); while ( _Atomic_Load_ulong( &node.done, ATOMIC_ORDER_ACQUIRE ) == 0 ) { /* Wait */ }; }
static void start_worker_stop_timer( rtems_test_parallel_context *ctx, rtems_interval duration ) { rtems_status_code sc; _Atomic_Store_ulong(&ctx->stop, 0, ATOMIC_ORDER_RELEASE); sc = rtems_timer_fire_after( ctx->stop_worker_timer_id, duration, stop_worker_timer, ctx ); _Assert(sc == RTEMS_SUCCESSFUL); (void) sc; }
static void stop_worker_timer(rtems_id timer_id, void *arg) { rtems_test_parallel_context *ctx = arg; _Atomic_Store_ulong(&ctx->stop, 1, ATOMIC_ORDER_RELAXED); }
static void test_simple_atomic_compare_exchange_body(test_context *ctx) { unsigned int ei; unsigned int vi; uintptr_t ep; uintptr_t vp; unsigned long el; unsigned long vl; bool success; puts("=== atomic simple compare exchange test case ==="); _Atomic_Store_uint(&ctx->uint_atomic, 1, ATOMIC_ORDER_RELAXED); ei = 2; success = _Atomic_Compare_exchange_uint( &ctx->uint_atomic, &ei, 3, ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED ); rtems_test_assert(!success); rtems_test_assert(ei == 1); success = _Atomic_Compare_exchange_uint( &ctx->uint_atomic, &ei, 3, ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED ); rtems_test_assert(success); vi = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(vi == 3); _Atomic_Store_uintptr(&ctx->uintptr_atomic, 111, ATOMIC_ORDER_RELAXED); ep = 211; success = _Atomic_Compare_exchange_uintptr( &ctx->uintptr_atomic, &ep, 311, ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED ); rtems_test_assert(!success); rtems_test_assert(ep == 111); success = _Atomic_Compare_exchange_uintptr( &ctx->uintptr_atomic, &ep, 311, ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED ); rtems_test_assert(success); vp = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(vp == 311); _Atomic_Store_ulong(&ctx->ulong_atomic, 10, ATOMIC_ORDER_RELAXED); el = 11; success = _Atomic_Compare_exchange_ulong( &ctx->ulong_atomic, &el, 12, ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED ); rtems_test_assert(!success); rtems_test_assert(el == 10); success = _Atomic_Compare_exchange_ulong( &ctx->ulong_atomic, &el, 12, ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED ); rtems_test_assert(success); vl = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED); rtems_test_assert(vl == 12); }