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); }
static void test_static_and_dynamic_initialization(void) { #if (__SIZEOF_INT__ == 2) #define UINT_CONSTANT 0xc0feU #else #define UINT_CONSTANT 0xc01dc0feU #endif static Atomic_Uint static_uint = ATOMIC_INITIALIZER_UINT(UINT_CONSTANT); static Atomic_Ulong static_ulong = ATOMIC_INITIALIZER_ULONG(0xdeadbeefUL); static Atomic_Uintptr static_uintptr = ATOMIC_INITIALIZER_UINTPTR((uintptr_t) &static_uintptr); static Atomic_Flag static_flag = ATOMIC_INITIALIZER_FLAG; Atomic_Uint stack_uint; Atomic_Ulong stack_ulong; Atomic_Uintptr stack_uintptr; Atomic_Flag stack_flag; puts("=== static and dynamic initialization test case ==="); _Atomic_Init_uint(&stack_uint, UINT_CONSTANT); _Atomic_Init_ulong(&stack_ulong, 0xdeadbeefUL); _Atomic_Init_uintptr(&stack_uintptr, (uintptr_t) &static_uintptr); _Atomic_Flag_clear(&stack_flag, ATOMIC_ORDER_RELAXED); rtems_test_assert( memcmp(&stack_uint, &static_uint, sizeof(stack_uint)) == 0 ); rtems_test_assert( memcmp(&stack_ulong, &static_ulong, sizeof(stack_ulong)) == 0 ); rtems_test_assert( memcmp(&stack_uintptr, &static_uintptr, sizeof(stack_uintptr)) == 0 ); rtems_test_assert( memcmp(&stack_flag, &static_flag, sizeof(stack_flag)) == 0 ); rtems_test_assert( _Atomic_Load_uint(&stack_uint, ATOMIC_ORDER_RELAXED) == 0xc01dc0feU ); rtems_test_assert( _Atomic_Load_ulong(&stack_ulong, ATOMIC_ORDER_RELAXED) == 0xdeadbeefUL ); rtems_test_assert( _Atomic_Load_uintptr(&stack_uintptr, ATOMIC_ORDER_RELAXED) == (uintptr_t) &static_uintptr ); rtems_test_assert( !_Atomic_Flag_test_and_set(&stack_flag, ATOMIC_ORDER_RELAXED) ); }
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 _SMP_Multicasts_try_process( void ) { unsigned long message; Per_CPU_Control *cpu_self; ISR_Level isr_level; _ISR_Local_disable( isr_level ); cpu_self = _Per_CPU_Get(); message = _Atomic_Load_ulong( &cpu_self->message, ATOMIC_ORDER_RELAXED ); if ( message & SMP_MESSAGE_MULTICAST_ACTION ) { if ( _Atomic_Compare_exchange_ulong( &cpu_self->message, &message, message & ~SMP_MESSAGE_MULTICAST_ACTION, ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED ) ) { _SMP_Multicast_actions_process(); } } _ISR_Local_enable( isr_level ); }
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); }