void pthread_exit(
  void  *value_ptr
)
{
  Objects_Information     *the_information;

  the_information = _Objects_Get_information( _Thread_Executing->Object.id );

  /* This should never happen if _Thread_Get() works right */
  assert( the_information );

  _Thread_Disable_dispatch();

  _Thread_Executing->Wait.return_argument = value_ptr;

  _Thread_Close( the_information, _Thread_Executing );

  _POSIX_Threads_Free( _Thread_Executing );

  _Thread_Enable_dispatch();
}
rtems_status_code rtems_clock_set(
  rtems_time_of_day *time_buffer
)
{
  struct timespec  newtime;

  if ( !time_buffer )
    return RTEMS_INVALID_ADDRESS;

  if ( _TOD_Validate( time_buffer ) ) {
    newtime.tv_sec = _TOD_To_seconds( time_buffer );
    newtime.tv_nsec = time_buffer->ticks * 
                 (_TOD_Microseconds_per_tick * TOD_NANOSECONDS_PER_MICROSECOND);

    _Thread_Disable_dispatch();
      _TOD_Set( &newtime );
    _Thread_Enable_dispatch();
    return RTEMS_SUCCESSFUL;
  }
  return RTEMS_INVALID_CLOCK;
}
  bool _Debug_Is_owner_of_allocator( void )
  {
    API_Mutex_Control *mutex = _RTEMS_Allocator_Mutex;
    bool owner;

    /*
     * We have to synchronize with the _CORE_mutex_Surrender() operation,
     * otherwise we may observe an outdated mutex holder.
     */
    _Thread_Disable_dispatch();

    if ( mutex != NULL ) {
      owner = mutex->Mutex.holder == _Thread_Executing;
    } else {
      owner = false;
    }

    _Thread_Enable_dispatch();

    return owner;
  }
示例#4
0
文件: init.c 项目: AlexShiLucky/rtems
static void test_change_priority(void)
{
  rtems_status_code sc;
  rtems_id task_id;
  Thread_Control *executing;
  Scheduler_SMP_Node *node;
  size_t i;
  size_t j;
  size_t k;

  task_id = start_task(3);

  _Thread_Disable_dispatch();

  executing = _Thread_Executing;
  node = _Scheduler_SMP_Thread_get_node( executing );

  for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
    for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
      for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
        test_case_change_priority(
          executing,
          node,
          states[i],
          priorities[j],
          prepend_it[k],
          states[j]
        );
      }
    }
  }

  _Thread_Change_priority(executing, 1, true);
  rtems_test_assert(node->state == SCHEDULER_SMP_NODE_SCHEDULED);

  _Thread_Enable_dispatch();

  sc = rtems_task_delete(task_id);
  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
示例#5
0
rtems_status_code rtems_message_queue_flush(
  rtems_id  id,
  uint32_t *count
)
{
  register Message_queue_Control *the_message_queue;
  Objects_Locations               location;

  if ( !count )
    return RTEMS_INVALID_ADDRESS;

  the_message_queue = _Message_queue_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      *count = _CORE_message_queue_Flush( &the_message_queue->message_queue );
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      _Thread_Executing->Wait.return_argument = count;

      return
        _Message_queue_MP_Send_request_packet(
          MESSAGE_QUEUE_MP_FLUSH_REQUEST,
          id,
          0,                               /* buffer not used */
          0,                               /* size */
          0,                               /* option_set not used */
          MPCI_DEFAULT_TIMEOUT
        );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
int _POSIX_Semaphore_Wait_support(
  sem_t             *sem,
  bool               blocking,
  Watchdog_Interval  timeout
)
{
  POSIX_Semaphore_Control *the_semaphore;
  Objects_Locations        location;

  the_semaphore = _POSIX_Semaphore_Get( sem, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _CORE_semaphore_Seize(
        &the_semaphore->Semaphore,
        the_semaphore->Object.id,
        blocking,
        timeout
      );
      _Thread_Enable_dispatch();

      if ( !_Thread_Executing->Wait.return_code )
        return 0;

      rtems_set_errno_and_return_minus_one(
        _POSIX_Semaphore_Translate_core_semaphore_return_code(
          _Thread_Executing->Wait.return_code
        )
      );

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  rtems_set_errno_and_return_minus_one( EINVAL );
}
示例#7
0
文件: init.c 项目: chch1028/rtems
static void test_scheduler_move_heir(void)
{
  bool per_cpu_state_ok;

  _Thread_Disable_dispatch();

  suspend(2);
  suspend(3);
  suspend(0);
  resume(2);
  suspend(1);
  resume(3);
  resume(0);

  per_cpu_state_ok = is_per_cpu_state_ok();

  resume(1);

  _Thread_Enable_dispatch();

  rtems_test_assert(per_cpu_state_ok);
}
示例#8
0
rtems_status_code rtems_semaphore_flush(
  rtems_id        id
)
{
  register Semaphore_Control *the_semaphore;
  Objects_Locations           location;

  the_semaphore = _Semaphore_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) {
        _CORE_mutex_Flush(
          &the_semaphore->Core_control.mutex,
          SEND_OBJECT_WAS_DELETED,
          CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT
        );
      } else {
        _CORE_semaphore_Flush(
          &the_semaphore->Core_control.semaphore,
          SEND_OBJECT_WAS_DELETED,
          CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT
        );
      }
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      _Thread_Dispatch();
      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
示例#9
0
static void deferred_release(void)
{
  rtems_filesystem_global_location_t *current = NULL;

  do {
    int count = 0;

    _Thread_Disable_dispatch();
    current = deferred_released_global_locations;
    if (current != NULL) {
      deferred_released_global_locations = current->deferred_released_next;
      count = current->deferred_released_count;
      current->deferred_released_next = NULL;
      current->deferred_released_count = 0;
    }
    _Thread_Enable_dispatch();

    if (current != NULL) {
      release_with_count(current, count);
    }
  } while (current != NULL);
}
示例#10
0
int mq_close(
  mqd_t  mqdes
)
{
  POSIX_Message_queue_Control    *the_mq;
  POSIX_Message_queue_Control_fd *the_mq_fd;
  Objects_Locations               location;

  the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
  if ( location == OBJECTS_LOCAL ) {
      /* OBJECTS_LOCAL:
       *
       *  First update the actual message queue to reflect this descriptor
       *  being disassociated.  This may result in the queue being really
       *  deleted.
       */

      the_mq = the_mq_fd->Queue;
      the_mq->open_count -= 1;
      _POSIX_Message_queue_Delete( the_mq );

      /*
       *  Now close this file descriptor.
       */

      _Objects_Close(
        &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object );
      _POSIX_Message_queue_Free_fd( the_mq_fd );

      _Thread_Enable_dispatch();
      return 0;
   }

   /*
    *  OBJECTS_REMOTE:
    *  OBJECTS_ERROR:
    */
   rtems_set_errno_and_return_minus_one( EBADF );
}
示例#11
0
rtems_status_code rtems_event_receive(
  rtems_event_set  event_in,
  rtems_option     option_set,
  rtems_interval   ticks,
  rtems_event_set *event_out
)
{
  rtems_status_code sc;

  if ( event_out != NULL ) {
    Thread_Control    *executing = _Thread_Get_executing();
    RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
    Event_Control     *event = &api->Event;

    if ( !_Event_sets_Is_empty( event_in ) ) {
      _Thread_Disable_dispatch();
      _Event_Seize(
        event_in,
        option_set,
        ticks,
        event_out,
        executing,
        event,
        &_Event_Sync_state,
        STATES_WAITING_FOR_EVENT
      );
      _Thread_Enable_dispatch();

      sc = executing->Wait.return_code;
    } else {
      *event_out = event->pending_events;
      sc = RTEMS_SUCCESSFUL;
    }
  } else {
    sc = RTEMS_INVALID_ADDRESS;
  }

  return sc;
}
示例#12
0
void
epicsEventShow(epicsEventId id, unsigned int level)
{
#if __RTEMS_VIOLATE_KERNEL_VISIBILITY__
    rtems_id sid = (rtems_id)id;
    Semaphore_Control *the_semaphore;
    Semaphore_Control semaphore;
    Objects_Locations location;

    the_semaphore = _Semaphore_Get (sid, &location);
    if (location != OBJECTS_LOCAL)
        return;
    /*
     * Yes, there's a race condition here since an interrupt might
     * change things while the copy is in progress, but the information
     * is only for display, so it's not that critical.
     */
    semaphore = *the_semaphore;
    _Thread_Enable_dispatch();
    printf ("          %8.8x  ", (int)sid);
    if (_Attributes_Is_counting_semaphore (semaphore.attribute_set)) {
            printf ("Count: %d", (int)semaphore.Core_control.semaphore.count);
    }
    else {
        if (_CORE_mutex_Is_locked(&semaphore.Core_control.mutex)) {
            char name[30];
            epicsThreadGetName ((epicsThreadId)semaphore.Core_control.mutex.holder_id, name, sizeof name);
            printf ("Held by:%8.8x (%s)  Nest count:%d",
                                    (unsigned int)semaphore.Core_control.mutex.holder_id,
                                    name,
                                    (int)semaphore.Core_control.mutex.nest_count);
        }
        else {
            printf ("Not Held");
        }
    }
    printf ("\n");
#endif
}
示例#13
0
int mq_getattr(
  mqd_t           mqdes,
  struct mq_attr *mqstat
)
{
  POSIX_Message_queue_Control          *the_mq;
  POSIX_Message_queue_Control_fd       *the_mq_fd;
  Objects_Locations                     location;

  if ( !mqstat )
    rtems_set_errno_and_return_minus_one( EINVAL );

  the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      the_mq = the_mq_fd->Queue;

      /*
       *  Return the old values.
       */
      mqstat->mq_flags   = the_mq_fd->oflag;
      mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
      mqstat->mq_maxmsg  = the_mq->Message_queue.maximum_pending_messages;
      mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;

      _Thread_Enable_dispatch();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  rtems_set_errno_and_return_minus_one( EBADF );
}
int pthread_getschedparam(
  pthread_t           thread,
  int                *policy,
  struct sched_param *param
)
{
  Objects_Locations        location;
  POSIX_API_Control       *api;
  register Thread_Control *the_thread;

  if ( !policy || !param  )
    return EINVAL;

  the_thread = _Thread_Get( thread, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
      if ( policy )
        *policy = api->schedpolicy;
      if ( param ) {
        *param  = api->schedparam;
        param->sched_priority =
          _POSIX_Priority_From_core( the_thread->current_priority );
      }
      _Thread_Enable_dispatch();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  return ESRCH;

}
rtems_status_code rtems_message_queue_get_number_pending(
  Objects_Id  id,
  uint32_t   *count
)
{
  register Message_queue_Control *the_message_queue;
  Objects_Locations               location;

  if ( !count )
    return RTEMS_INVALID_ADDRESS;

  the_message_queue = _Message_queue_Get( id, &location );
  switch ( location ) {
    case OBJECTS_REMOTE:
#if defined(RTEMS_MULTIPROCESSING)
      _Thread_Executing->Wait.return_argument = count;

      return _Message_queue_MP_Send_request_packet(
          MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST,
          id,
          0,                               /* buffer not used */
          0,                               /* size */
          0,                               /* option_set not used */
          MPCI_DEFAULT_TIMEOUT
        );
#endif

    case OBJECTS_ERROR:
      return RTEMS_INVALID_ID;

    case OBJECTS_LOCAL:
      *count = the_message_queue->message_queue.number_of_pending_messages;
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;
  }

  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
}
示例#16
0
void _TOD_Set_with_timestamp(
  const Timestamp_Control *tod
)
{
  Watchdog_Interval seconds_next = _Timestamp_Get_seconds( tod );
  Watchdog_Interval seconds_now;

  _Thread_Disable_dispatch();
  _TOD_Deactivate();

  seconds_now = _TOD_Seconds_since_epoch();

  if ( seconds_next < seconds_now )
    _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD, seconds_now - seconds_next );
  else
    _Watchdog_Adjust_seconds( WATCHDOG_FORWARD, seconds_next - seconds_now );

  _TOD_Now = *tod;
  _TOD_Is_set = true;

  _TOD_Activate();
  _Thread_Enable_dispatch();
}
示例#17
0
文件: mpci.c 项目: 0871087123/rtems
uint32_t   _MPCI_Send_request_packet (
  uint32_t            destination,
  MP_packet_Prefix   *the_packet,
  States_Control      extra_state
)
{
  the_packet->source_tid      = _Thread_Executing->Object.id;
  the_packet->source_priority = _Thread_Executing->current_priority;
  the_packet->to_convert =
     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) / sizeof(uint32_t);

  _Thread_Executing->Wait.id = the_packet->id;

  _Thread_Executing->Wait.queue = &_MPCI_Remote_blocked_threads;

  _Thread_Disable_dispatch();

    (*_MPCI_table->send_packet)( destination, the_packet );

    _Thread_queue_Enter_critical_section( &_MPCI_Remote_blocked_threads );

    /*
     *  See if we need a default timeout
     */

    if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT)
        the_packet->timeout = _MPCI_table->default_timeout;

    _Thread_queue_Enqueue( &_MPCI_Remote_blocked_threads, the_packet->timeout );

    _Thread_Executing->current_state =
      _States_Set( extra_state, _Thread_Executing->current_state );

  _Thread_Enable_dispatch();

  return _Thread_Executing->Wait.return_code;
}
示例#18
0
rtems_status_code rtems_task_wake_when(
  rtems_time_of_day *time_buffer
)
{
  Watchdog_Interval   seconds;

  if ( !_TOD_Is_set() )
    return RTEMS_NOT_DEFINED;

  if ( !time_buffer )
    return RTEMS_INVALID_ADDRESS;

  time_buffer->ticks = 0;

  if ( !_TOD_Validate( time_buffer ) )
    return RTEMS_INVALID_CLOCK;

  seconds = _TOD_To_seconds( time_buffer );

  if ( seconds <= _TOD_Seconds_since_epoch() )
    return RTEMS_INVALID_CLOCK;

  _Thread_Disable_dispatch();
    _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );
    _Watchdog_Initialize(
      &_Thread_Executing->Timer,
      _Thread_Delay_ended,
      _Thread_Executing->Object.id,
      NULL
    );
    _Watchdog_Insert_seconds(
      &_Thread_Executing->Timer,
      seconds - _TOD_Seconds_since_epoch()
    );
  _Thread_Enable_dispatch();
  return RTEMS_SUCCESSFUL;
}
示例#19
0
int pthread_rwlock_wrlock(
  pthread_rwlock_t  *rwlock
)
{
  POSIX_RWLock_Control  *the_rwlock;
  Objects_Locations      location;

  if ( !rwlock )
    return EINVAL;

  the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:

      _CORE_RWLock_Obtain_for_writing(
	&the_rwlock->RWLock,
	*rwlock,
	true,          /* do not timeout -- wait forever */
	0,
	NULL
      );

      _Thread_Enable_dispatch();
      return _POSIX_RWLock_Translate_core_RWLock_return_code(
        (CORE_RWLock_Status) _Thread_Executing->Wait.return_code
      );

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  return EINVAL;
}
示例#20
0
rtems_status_code rtems_rate_monotonic_reset_statistics(
    rtems_id id
)
{
    Objects_Locations              location;
    Rate_monotonic_Control        *the_period;

    the_period = _Rate_monotonic_Get( id, &location );
    switch ( location ) {

    case OBJECTS_LOCAL:
        _Rate_monotonic_Reset_statistics( the_period );
        _Thread_Enable_dispatch();
        return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:            /* should never return this */
#endif
    case OBJECTS_ERROR:
        break;
    }

    return RTEMS_INVALID_ID;
}
示例#21
0
文件: clockset.c 项目: atixing/rtems
rtems_status_code rtems_clock_set(
  const rtems_time_of_day *tod
)
{
  if ( !tod )
    return RTEMS_INVALID_ADDRESS;

  if ( _TOD_Validate( tod ) ) {
    Timestamp_Control tod_as_timestamp;
    uint32_t seconds = _TOD_To_seconds( tod );
    uint32_t nanoseconds = tod->ticks
      * rtems_configuration_get_nanoseconds_per_tick();

    _Timestamp_Set( &tod_as_timestamp, seconds, nanoseconds );

    _Thread_Disable_dispatch();
      _TOD_Set_with_timestamp( &tod_as_timestamp );
    _Thread_Enable_dispatch();

    return RTEMS_SUCCESSFUL;
  }

  return RTEMS_INVALID_CLOCK;
}
示例#22
0
int _Scheduler_CBS_Detach_thread (
  Scheduler_CBS_Server_id server_id,
  rtems_id                task_id
)
{
  Objects_Locations location;
  Thread_Control *the_thread;
  Scheduler_CBS_Per_thread *sched_info;

  the_thread = _Thread_Get(task_id, &location);
  /* The routine _Thread_Get may disable dispatch and not enable again. */
  if ( the_thread ) {
    _Thread_Enable_dispatch();
  }

  if ( server_id >= _Scheduler_CBS_Maximum_servers )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  if ( !the_thread )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  /* Server is not valid. */
  if ( !_Scheduler_CBS_Server_list[server_id] )
    return SCHEDULER_CBS_ERROR_NOSERVER;
  /* Thread and server are not attached. */
  if ( _Scheduler_CBS_Server_list[server_id]->task_id != task_id )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;

  _Scheduler_CBS_Server_list[server_id]->task_id = -1;
  sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info;
  sched_info->cbs_server = NULL;

  the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
  the_thread->budget_callout   = the_thread->Start.budget_callout;
  the_thread->is_preemptible   = the_thread->Start.is_preemptible;

  return SCHEDULER_CBS_OK;
}
示例#23
0
int pthread_key_delete(
  pthread_key_t  key
)
{
  register POSIX_Keys_Control *the_key;
  Objects_Locations            location;
  uint32_t                     the_api;

  the_key = _POSIX_Keys_Get( key, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _Objects_Close( &_POSIX_Keys_Information, &the_key->Object );

      for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ )
        if ( the_key->Values[ the_api ] )
          _Workspace_Free( the_key->Values[ the_api ] );

      /*
       *  NOTE:  The destructor is not called and it is the responsibility
       *         of the application to free the memory.
       */

      _POSIX_Keys_Free( the_key );
      _Thread_Enable_dispatch();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:   /* should never happen */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return EINVAL;
}
示例#24
0
void _TOD_Set(
  const struct timespec *time
)
{
  long seconds;

  _Thread_Disable_dispatch();
  _TOD_Deactivate();

  seconds = _TOD_Seconds_since_epoch();

  if ( time->tv_sec < seconds )
    _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD, seconds - time->tv_sec );
  else
    _Watchdog_Adjust_seconds( WATCHDOG_FORWARD, time->tv_sec - seconds );

  /* POSIX format TOD (timespec) */
  _Timestamp_Set( &_TOD_Now, time->tv_sec, time->tv_nsec );
  _TOD_Is_set = true;

  _TOD_Activate();

  _Thread_Enable_dispatch();
}
rtems_status_code rtems_event_send(
  rtems_id          id,
  rtems_event_set   event_in
)
{
  register Thread_Control *the_thread;
  Objects_Locations        location;
  RTEMS_API_Control       *api;

  the_thread = _Thread_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
      _Event_sets_Post( event_in, &api->pending_events );
      _Event_Surrender( the_thread );
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      return(
        _Event_MP_Send_request_packet(
          EVENT_MP_SEND_REQUEST,
          id,
          event_in
        )
      );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
示例#26
0
rtems_status_code rtems_event_receive(
  rtems_event_set  event_in,
  rtems_option     option_set,
  rtems_interval   ticks,
  rtems_event_set *event_out
)
{
  RTEMS_API_Control       *api;

  if ( !event_out )
    return RTEMS_INVALID_ADDRESS;

  api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];

  if ( _Event_sets_Is_empty( event_in ) ) {
    *event_out = api->pending_events;
    return RTEMS_SUCCESSFUL;
  }

  _Thread_Disable_dispatch();
  _Event_Seize( event_in, option_set, ticks, event_out );
  _Thread_Enable_dispatch();
  return( _Thread_Executing->Wait.return_code );
}
示例#27
0
int timer_delete(
  timer_t timerid
)
{
 /*
  * IDEA: This function must probably stop the timer first and then delete it
  *
  *       It will have to do a call to rtems_timer_cancel and then another
  *       call to rtems_timer_delete.
  *       The call to rtems_timer_delete will be probably unnecessary,
  *       because rtems_timer_delete stops the timer before deleting it.
  */
  POSIX_Timer_Control *ptimer;
  Objects_Locations    location;

  ptimer = _POSIX_Timer_Get( timerid, &location );
  switch ( location ) {
    case OBJECTS_REMOTE:
#if defined(RTEMS_MULTIPROCESSING)
      _Thread_Dispatch();
      rtems_set_errno_and_return_minus_one( EINVAL );
#endif

    case OBJECTS_ERROR:
      rtems_set_errno_and_return_minus_one( EINVAL );

    case OBJECTS_LOCAL:
      _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object );
      ptimer->state = POSIX_TIMER_STATE_FREE;
      (void) _Watchdog_Remove( &ptimer->Timer );
      _POSIX_Timer_Free( ptimer );
      _Thread_Enable_dispatch();
      return 0;
  }
  return -1;   /* unreached - only to remove warnings */
}
ER dly_tsk(
  DLYTIME dlytim
)
{
  Watchdog_Interval ticks;

  ticks = TOD_MILLISECONDS_TO_TICKS(dlytim);

  _Thread_Disable_dispatch();
    if ( ticks == 0 ) {
      _Thread_Yield_processor();
    } else {
      _Thread_Set_state( _Thread_Executing, STATES_DELAYING );
      _Watchdog_Initialize(
        &_Thread_Executing->Timer,
        _Thread_Delay_ended,
        _Thread_Executing->Object.id,
        NULL
      );
      _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );
    }
  _Thread_Enable_dispatch();
  return E_OK;
}
int sigtimedwait(
  const sigset_t         *set,
  siginfo_t              *info,
  const struct timespec  *timeout
)
{
  Thread_Control    *the_thread;
  POSIX_API_Control *api;
  Watchdog_Interval  interval;
  siginfo_t          signal_information;
  siginfo_t         *the_info;
  int                signo;
  ISR_Level          level;

  /*
   *  Error check parameters before disabling interrupts.
   */
  if ( !set )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*  NOTE: This is very specifically a RELATIVE not ABSOLUTE time
   *        in the Open Group specification.
   */

  interval = 0;
  if ( timeout ) {

    if ( !_Timespec_Is_valid( timeout ) )
      rtems_set_errno_and_return_minus_one( EINVAL );

    interval = _Timespec_To_ticks( timeout );

    if ( !interval )
      rtems_set_errno_and_return_minus_one( EINVAL );
  }

  /*
   *  Initialize local variables.
   */

  the_info = ( info ) ? info : &signal_information;

  the_thread = _Thread_Executing;

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  /*
   *  What if they are already pending?
   */

  /* API signals pending? */

  _ISR_Disable( level );
  if ( *set & api->signals_pending ) {
    /* XXX real info later */
    the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
    _POSIX_signals_Clear_signals(
      api,
      the_info->si_signo,
      the_info,
      false,
      false
    );
    _ISR_Enable( level );

    the_info->si_code = SI_USER;
    the_info->si_value.sival_int = 0;
    return the_info->si_signo;
  }

  /* Process pending signals? */

  if ( *set & _POSIX_signals_Pending ) {
    signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
    _POSIX_signals_Clear_signals( api, signo, the_info, true, false );
    _ISR_Enable( level );

    the_info->si_signo = signo;
    the_info->si_code = SI_USER;
    the_info->si_value.sival_int = 0;
    return signo;
  }

  the_info->si_signo = -1;

  _Thread_Disable_dispatch();
    the_thread->Wait.queue           = &_POSIX_signals_Wait_queue;
    the_thread->Wait.return_code     = EINTR;
    the_thread->Wait.option          = *set;
    the_thread->Wait.return_argument = the_info;
    _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
    _ISR_Enable( level );
    _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
  _Thread_Enable_dispatch();

  /*
   * When the thread is set free by a signal, it is need to eliminate
   * the signal.
   */

  _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false );
  errno = _Thread_Executing->Wait.return_code;
  return the_info->si_signo;
}
示例#30
0
void _Thread_Handler( void )
{
  ISR_Level  level;
  Thread_Control *executing;
  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    static char doneConstructors;
    char doneCons;
  #endif

  executing = _Thread_Executing;

  /*
   * Some CPUs need to tinker with the call frame or registers when the
   * thread actually begins to execute for the first time.  This is a
   * hook point where the port gets a shot at doing whatever it requires.
   */
  _Context_Initialization_at_thread_begin();

  /*
   * have to put level into a register for those cpu's that use
   * inline asm here
   */

  level = executing->Start.isr_level;
  _ISR_Set_level(level);

  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    doneCons = doneConstructors;
    doneConstructors = 1;
  #endif

  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
    #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
      if ( (executing->fp_context != NULL) &&
            !_Thread_Is_allocated_fp( executing ) ) {
        if ( _Thread_Allocated_fp != NULL )
          _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
        _Thread_Allocated_fp = executing;
      }
    #endif
  #endif

  /*
   * Take care that 'begin' extensions get to complete before
   * 'switch' extensions can run.  This means must keep dispatch
   * disabled until all 'begin' extensions complete.
   */
  _User_extensions_Thread_begin( executing );

  /*
   *  At this point, the dispatch disable level BETTER be 1.
   */
  _Thread_Enable_dispatch();

  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    /*
     *  _init could be a weak symbol and we SHOULD test it but it isn't
     *  in any configuration I know of and it generates a warning on every
     *  RTEMS target configuration.  --joel (12 May 2007)
     */
    if (!doneCons) /* && (volatile void *)_init) */ {
      INIT_NAME ();
    }
  #endif

  if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
    executing->Wait.return_argument =
      (*(Thread_Entry_numeric) executing->Start.entry_point)(
        executing->Start.numeric_argument
      );
  }
  #if defined(RTEMS_POSIX_API)
    else if ( executing->Start.prototype == THREAD_START_POINTER ) {
      executing->Wait.return_argument =
        (*(Thread_Entry_pointer) executing->Start.entry_point)(
          executing->Start.pointer_argument
        );
    }
  #endif
  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
    else if ( executing->Start.prototype == THREAD_START_BOTH_POINTER_FIRST ) {
      executing->Wait.return_argument =
         (*(Thread_Entry_both_pointer_first) executing->Start.entry_point)(
           executing->Start.pointer_argument,
           executing->Start.numeric_argument
         );
    }
    else if ( executing->Start.prototype == THREAD_START_BOTH_NUMERIC_FIRST ) {
      executing->Wait.return_argument =
       (*(Thread_Entry_both_numeric_first) executing->Start.entry_point)(
         executing->Start.numeric_argument,
         executing->Start.pointer_argument
       );
    }
  #endif

  /*
   *  In the switch above, the return code from the user thread body
   *  was placed in return_argument.  This assumed that if it returned
   *  anything (which is not supporting in all APIs), then it would be
   *  able to fit in a (void *).
   */

  _User_extensions_Thread_exitted( executing );

  _Internal_error_Occurred(
    INTERNAL_ERROR_CORE,
    true,
    INTERNAL_ERROR_THREAD_EXITTED
  );
}