Beispiel #1
0
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 );
}
Beispiel #2
0
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));
}
Beispiel #3
0
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);
}
Beispiel #4
0
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 */
  };
}
Beispiel #5
0
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;
}
Beispiel #6
0
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);
}
Beispiel #7
0
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);
}