Esempio n. 1
0
void *_Freechain_Get(
  Freechain_Control   *freechain,
  Freechain_Allocator  allocator,
  size_t               number_nodes_to_extend,
  size_t               node_size
)
{
  _Assert( node_size >= sizeof( Chain_Node ) );

  if ( _Chain_Is_empty( &freechain->Free ) && number_nodes_to_extend > 0 ) {
    void *starting_address;

    starting_address = ( *allocator )( number_nodes_to_extend * node_size );
    number_nodes_to_extend *= ( starting_address != NULL );

    _Chain_Initialize(
      &freechain->Free,
      starting_address,
      number_nodes_to_extend,
      node_size
    );
  }

  return _Chain_Get_unprotected( &freechain->Free );
}
boolean _POSIX_signals_Clear_signals(
  POSIX_API_Control  *api,
  int                 signo,
  siginfo_t          *info,
  boolean             is_global,
  boolean             check_blocked
)
{
  sigset_t                    mask;
  sigset_t                    signals_blocked;
  ISR_Level                   level;
  boolean                     do_callout;
  POSIX_signals_Siginfo_node *psiginfo;

  mask = signo_to_mask( signo );

  do_callout = FALSE;

  /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK
   * insures that no signals are blocked and all are checked.
   */

  if ( check_blocked )
    signals_blocked = ~api->signals_blocked;
  else
    signals_blocked = SIGNAL_ALL_MASK;

  /* XXX this is not right for siginfo type signals yet */
  /* XXX since they can't be cleared the same way */

  _ISR_Disable( level );
    if ( is_global ) {
       if ( mask & (_POSIX_signals_Pending & signals_blocked) ) {
         if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) {
           psiginfo = (POSIX_signals_Siginfo_node *)
             _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] );
           if ( _Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) )
             _POSIX_signals_Clear_process_signals( mask );
           if ( psiginfo ) {
             *info = psiginfo->Info;
             _Chain_Append_unprotected(
               &_POSIX_signals_Inactive_siginfo,
               &psiginfo->Node
             );
           } else
             do_callout = FALSE;
         } else
           _POSIX_signals_Clear_process_signals( mask );
         do_callout = TRUE;
       }
    } else {
      if ( mask & (api->signals_pending & signals_blocked) ) {
        api->signals_pending &= ~mask;
        do_callout = TRUE;
      }
    }
  _ISR_Enable( level );
  return do_callout;
}
Esempio n. 3
0
static Thread_Action *_Thread_Get_post_switch_action(
  Thread_Control *executing
)
{
  Chain_Control *chain = &executing->Post_switch_actions.Chain;

  return (Thread_Action *) _Chain_Get_unprotected( chain );
}
Esempio n. 4
0
rtems_chain_node *rtems_chain_get( rtems_chain_control *chain )
{
    rtems_chain_node *node;
    ISR_Level level;

    _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    node = _Chain_Get_unprotected( &chain->Chain );
    _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );

    return node;
}
Esempio n. 5
0
rtems_chain_node *rtems_chain_get( rtems_chain_control *chain )
{
  rtems_chain_node *node;
  rtems_interrupt_lock_context lock_context;

  chain_acquire( &lock_context );
  node = _Chain_Get_unprotected( chain );
  chain_release( &lock_context );

  return node;
}
void _Thread_Kill_zombies( void )
{
  ISR_lock_Context lock_context;
  Thread_Zombie_control *zombies = &_Thread_Zombies;
  Thread_Control *the_thread;

  _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );

  the_thread = (Thread_Control *) _Chain_Get_unprotected( &zombies->Chain );
  while ( the_thread != NULL ) {
    _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );

    _Thread_Wait_for_execution_stop( the_thread );
    _Thread_Free( the_thread );

    _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );

    the_thread = (Thread_Control *) _Chain_Get_unprotected( &zombies->Chain );
  }

  _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );
}
Esempio n. 7
0
bool _POSIX_signals_Clear_signals(
  POSIX_API_Control  *api,
  int                 signo,
  siginfo_t          *info,
  bool                is_global,
  bool                check_blocked
)
{
  sigset_t                    mask;
  sigset_t                    signals_blocked;
  ISR_Level                   level;
  bool                        do_callout;
  POSIX_signals_Siginfo_node *psiginfo;

  mask = signo_to_mask( signo );

  do_callout = false;

  /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK
   * insures that no signals are blocked and all are checked.
   */

  if ( check_blocked )
    signals_blocked = ~api->signals_blocked;
  else
    signals_blocked = SIGNAL_ALL_MASK;

  /* XXX is this right for siginfo type signals? */
  /* XXX are we sure they can be cleared the same way? */

  _ISR_Disable( level );
    if ( is_global ) {
       if ( mask & (_POSIX_signals_Pending & signals_blocked) ) {
         if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) {
           psiginfo = (POSIX_signals_Siginfo_node *)
             _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] );
           _POSIX_signals_Clear_process_signals( signo );
           /*
            *  It may be impossible to get here with an empty chain
            *  BUT until that is proven we need to be defensive and
            *  protect against it.
            */
           if ( psiginfo ) {
             *info = psiginfo->Info;
             _Chain_Append_unprotected(
               &_POSIX_signals_Inactive_siginfo,
               &psiginfo->Node
             );
           } else
             do_callout = false;
         }
         _POSIX_signals_Clear_process_signals( signo );
         do_callout = true;
       }
    } else {
      if ( mask & (api->signals_pending & signals_blocked) ) {
        api->signals_pending &= ~mask;
        do_callout = true;
      }
    }
  _ISR_Enable( level );
  return do_callout;
}
Esempio n. 8
0
/**
 *  @brief Timer server body.
 *
 *  This is the server for task based timers.  This task executes whenever a
 *  task-based timer should fire.  It services both "after" and "when" timers.
 *  It is not created automatically but must be created explicitly by the
 *  application before task-based timers may be initiated.  The parameter
 *  @a arg points to the corresponding timer server control block.
 */
static rtems_task _Timer_server_Body(
  rtems_task_argument arg
)
{
  Timer_server_Control *ts = (Timer_server_Control *) arg;
  Chain_Control insert_chain;
  Chain_Control fire_chain;

  _Chain_Initialize_empty( &insert_chain );
  _Chain_Initialize_empty( &fire_chain );

  while ( true ) {
    _Timer_server_Get_watchdogs_that_fire_now( ts, &insert_chain, &fire_chain );

    if ( !_Chain_Is_empty( &fire_chain ) ) {
      /*
       *  Fire the watchdogs.
       */
      while ( true ) {
        Watchdog_Control *watchdog;
        ISR_Level level;

        /*
         *  It is essential that interrupts are disable here since an interrupt
         *  service routine may remove a watchdog from the chain.
         */
        _ISR_Disable( level );
        watchdog = (Watchdog_Control *) _Chain_Get_unprotected( &fire_chain );
        if ( watchdog != NULL ) {
          watchdog->state = WATCHDOG_INACTIVE;
          _ISR_Enable( level );
        } else {
          _ISR_Enable( level );

          break;
        }

        /*
         *  The timer server may block here and wait for resources or time.
         *  The system watchdogs are inactive and will remain inactive since
         *  the active flag of the timer server is true.
         */
        (*watchdog->routine)( watchdog->id, watchdog->user_data );
      }
    } else {
      ts->active = false;

      /*
       *  Block until there is something to do.
       */
      _Thread_Disable_dispatch();
        _Thread_Set_state( ts->thread, STATES_DELAYING );
        _Timer_server_Reset_interval_system_watchdog( ts );
        _Timer_server_Reset_tod_system_watchdog( ts );
      _Thread_Enable_dispatch();

      ts->active = true;

      /*
       *  Maybe an interrupt did reset the system timers, so we have to stop
       *  them here.  Since we are active now, there will be no more resets
       *  until we are inactive again.
       */
      _Timer_server_Stop_interval_system_watchdog( ts );
      _Timer_server_Stop_tod_system_watchdog( ts );
    }
  }
}
Esempio n. 9
0
Thread_Control *_Thread_MP_Allocate_proxy (
  States_Control  the_state
)
{
  Thread_Proxy_control *the_proxy;
  ISR_lock_Context      lock_context;

  _Thread_MP_Proxies_acquire( &lock_context );

  the_proxy = (Thread_Proxy_control *)
    _Chain_Get_unprotected( &_Thread_MP_Inactive_proxies );
  if ( the_proxy != NULL ) {
    Thread_Control   *executing;
    MP_packet_Prefix *receive_packet;
    Objects_Id        source_tid;

    executing = _Thread_Executing;
    receive_packet = _MPCI_Receive_server_tcb->receive_packet;
    source_tid = receive_packet->source_tid;

    executing->Wait.return_code = THREAD_STATUS_PROXY_BLOCKING;

    the_proxy->receive_packet = receive_packet;
    the_proxy->Object.id = source_tid;
    the_proxy->current_priority = receive_packet->source_priority;
    the_proxy->current_state = _States_Set( STATES_DORMANT, the_state );

    the_proxy->Wait.count                   = executing->Wait.count;
    the_proxy->Wait.return_argument         = executing->Wait.return_argument;
    the_proxy->Wait.return_argument_second  = executing->Wait.return_argument_second;
    the_proxy->Wait.option                  = executing->Wait.option;
    the_proxy->Wait.return_code             = executing->Wait.return_code;
    the_proxy->Wait.timeout_code            = executing->Wait.timeout_code;

    the_proxy->thread_queue_callout = _Thread_queue_MP_callout_do_nothing;

    _RBTree_Insert_inline(
      &_Thread_MP_Active_proxies,
      &the_proxy->Active,
      &source_tid,
      _Thread_MP_Proxy_less
    );

    _Thread_MP_Proxies_release( &lock_context );

    return (Thread_Control *) the_proxy;
  }

  _Thread_MP_Proxies_release( &lock_context );

  _Terminate(
    INTERNAL_ERROR_CORE,
    true,
    INTERNAL_ERROR_OUT_OF_PROXIES
  );

  /*
   *  NOTE: The following return ensures that the compiler will
   *        think that all paths return a value.
   */

  return NULL;
}