Example #1
0
rtems_status_code rtems_task_restart(
  rtems_id  id,
  uint32_t  argument
)
{
  register Thread_Control *the_thread;
  Objects_Locations        location;

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

    case OBJECTS_LOCAL:
      if ( _Thread_Restart( the_thread, NULL, argument ) ) {
        _Objects_Put( &the_thread->Object );
        return RTEMS_SUCCESSFUL;
      }
      _Objects_Put( &the_thread->Object );
      return RTEMS_INCORRECT_STATE;

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

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
Example #2
0
rtems_status_code rtems_rate_monotonic_cancel(
  rtems_id id
)
{
  Rate_monotonic_Control *the_period;
  Objects_Locations       location;

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

    case OBJECTS_LOCAL:
      if ( !_Thread_Is_executing( the_period->owner ) ) {
        _Objects_Put( &the_period->Object );
        return RTEMS_NOT_OWNER_OF_RESOURCE;
      }
      (void) _Watchdog_Remove( &the_period->Timer );
      the_period->state = RATE_MONOTONIC_INACTIVE;
      _Scheduler_Release_job( the_period->owner, 0 );
      _Objects_Put( &the_period->Object );
      return RTEMS_SUCCESSFUL;

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

  return RTEMS_INVALID_ID;
}
Example #3
0
rtems_status_code rtems_timer_fire_after(
  rtems_id                           id,
  rtems_interval                     ticks,
  rtems_timer_service_routine_entry  routine,
  void                              *user_data
)
{
  Timer_Control      *the_timer;
  Objects_Locations   location;
  ISR_Level           level;

  if ( ticks == 0 )
    return RTEMS_INVALID_NUMBER;

  if ( !routine )
    return RTEMS_INVALID_ADDRESS;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _Timer_Cancel( the_timer );

      _ISR_Disable( level );

        /*
         *  Check to see if the watchdog has just been inserted by a
         *  higher priority interrupt.  If so, abandon this insert.
         */

        if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) {
          _ISR_Enable( level );
          _Objects_Put( &the_timer->Object );
          return RTEMS_SUCCESSFUL;
        }

        /*
         *  OK.  Now we now the timer was not rescheduled by an interrupt
         *  so we can atomically initialize it as in use.
         */

        the_timer->the_class = TIMER_INTERVAL;
        _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
      _ISR_Enable( level );


      _Watchdog_Insert_ticks( &the_timer->Ticker, ticks );
      _Objects_Put( &the_timer->Object );
      return RTEMS_SUCCESSFUL;

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

  return RTEMS_INVALID_ID;
}
Example #4
0
rtems_status_code rtems_timer_reset(
  rtems_id id
)
{
  Timer_Control     *the_timer;
  Objects_Locations  location;
  rtems_status_code  status = RTEMS_SUCCESSFUL;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( the_timer->the_class == TIMER_INTERVAL ) {
        _Watchdog_Remove( &the_timer->Ticker );
        _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker );
      } else if ( the_timer->the_class == TIMER_INTERVAL_ON_TASK ) {
        Timer_server_Control *timer_server = _Timer_server;

        /*
         *  There is no way for a timer to have this class unless
         *  it was scheduled as a server fire.  That requires that
         *  the Timer Server be initiated.  So this error cannot
         *  occur unless something is internally wrong.
         */
        #if defined(RTEMS_DEBUG)
          if ( !timer_server ) {
            _Objects_Put( &the_timer->Object );
            return RTEMS_INCORRECT_STATE;
          }
        #endif
        _Watchdog_Remove( &the_timer->Ticker );
        (*timer_server->schedule_operation)( timer_server, the_timer );
      } else {
        /*
         *  Must be dormant or time of day timer (e.g. TIMER_DORMANT,
         *  TIMER_TIME_OF_DAY, or TIMER_TIME_OF_DAY_ON_TASK).  We
         *  can only reset active interval timers.
         */
        status = RTEMS_NOT_DEFINED;
      }
      _Objects_Put( &the_timer->Object );
      return status;

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

  return RTEMS_INVALID_ID;
}
Example #5
0
/* Set barriers to be interruptible by signals. */
static void pipe_interruptible(pipe_control_t *pipe)
{
  Objects_Locations  location;
  Barrier_Control   *the_barrier;

  the_barrier = _Barrier_Get(pipe->readBarrier, &location);
  the_barrier->Barrier.Wait_queue.state |= STATES_INTERRUPTIBLE_BY_SIGNAL;
  _Objects_Put( &the_barrier->Object );

  the_barrier = _Barrier_Get(pipe->writeBarrier, &location);
  the_barrier->Barrier.Wait_queue.state |= STATES_INTERRUPTIBLE_BY_SIGNAL;
  _Objects_Put( &the_barrier->Object );
}
Example #6
0
rtems_status_code rtems_partition_delete(
  rtems_id id
)
{
   Partition_Control           *the_partition;
  Objects_Locations           location;

  the_partition = _Partition_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( the_partition->number_of_used_blocks == 0 ) {
        _Objects_Close( &_Partition_Information, &the_partition->Object );
        _Partition_Free( the_partition );
#if defined(RTEMS_MULTIPROCESSING)
        if ( _Attributes_Is_global( the_partition->attribute_set ) ) {

          _Objects_MP_Close(
            &_Partition_Information,
            the_partition->Object.id
          );

          _Partition_MP_Send_process_packet(
            PARTITION_MP_ANNOUNCE_DELETE,
            the_partition->Object.id,
            0,                         /* Not used */
            0                          /* Not used */
          );
        }
#endif

        _Objects_Put( &the_partition->Object );
        return RTEMS_SUCCESSFUL;
      }
      _Objects_Put( &the_partition->Object );
      return RTEMS_RESOURCE_IN_USE;

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

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
Example #7
0
int mq_notify(
  mqd_t                  mqdes,
  const struct sigevent *notification
)
{
  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 );
  switch ( location ) {

    case OBJECTS_LOCAL:
      the_mq = the_mq_fd->Queue;

      if ( notification ) {
        if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) {
          _Objects_Put( &the_mq_fd->Object );
          rtems_set_errno_and_return_minus_one( EBUSY );
        }

        _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );

        the_mq->notification = *notification;

        _CORE_message_queue_Set_notify(
          &the_mq->Message_queue,
          _POSIX_Message_queue_Notify_handler,
          the_mq
        );
      } else {

        _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );

      }

      _Objects_Put( &the_mq_fd->Object );
      return 0;

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

  rtems_set_errno_and_return_minus_one( EBADF );
}
Example #8
0
rtems_status_code rtems_timer_cancel(
  rtems_id id
)
{
  Timer_Control   *the_timer;
  Objects_Locations       location;

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( !_Timer_Is_dormant_class( the_timer->the_class ) )
        (void) _Watchdog_Remove( &the_timer->Ticker );
      _Objects_Put( &the_timer->Object );
      return RTEMS_SUCCESSFUL;

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

  return RTEMS_INVALID_ID;
}
Example #9
0
rtems_status_code rtems_barrier_wait(
  rtems_id        id,
  rtems_interval  timeout
)
{
  Barrier_Control   *the_barrier;
  Objects_Locations  location;
  Thread_Control    *executing;

  the_barrier = _Barrier_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      executing = _Thread_Executing;
      _CORE_barrier_Wait(
        &the_barrier->Barrier,
        executing,
        id,
        true,
        timeout,
        NULL
      );
      _Objects_Put( &the_barrier->Object );
      return _Barrier_Translate_core_barrier_return_code(
                executing->Wait.return_code );

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

  return RTEMS_INVALID_ID;
}
Example #10
0
rtems_status_code rtems_barrier_release(
  rtems_id          id,
  uint32_t         *released
)
{
  Barrier_Control   *the_barrier;
  Objects_Locations  location;

  if ( !released )
    return RTEMS_INVALID_ADDRESS;

  the_barrier = _Barrier_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      *released = _CORE_barrier_Release( &the_barrier->Barrier, id, NULL );
      _Objects_Put( &the_barrier->Object );
      return RTEMS_SUCCESSFUL;

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

  return RTEMS_INVALID_ID;
}
Example #11
0
rtems_status_code rtems_task_set_note(
  rtems_id id,
  uint32_t notepad,
  uint32_t note
)
{
  Thread_Control          *the_thread;
  Objects_Locations        location;
  RTEMS_API_Control       *api;
  Thread_Control          *executing;

  if ( !rtems_configuration_get_notepads_enabled() )
    return RTEMS_NOT_CONFIGURED;

  /*
   *  NOTE:  There is no check for < RTEMS_NOTEPAD_FIRST because that would
   *         be checking an unsigned number for being negative.
   */

  if ( notepad > RTEMS_NOTEPAD_LAST )
    return RTEMS_INVALID_NUMBER;

  /*
   *  Optimize the most likely case to avoid the Thread_Dispatch.
   */

  executing = _Thread_Get_executing();
  if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||
       _Objects_Are_ids_equal( id, executing->Object.id ) ) {
      api = executing->API_Extensions[ THREAD_API_RTEMS ];
      api->Notepads[ notepad ] = note;
      return RTEMS_SUCCESSFUL;
  }

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

    case OBJECTS_LOCAL:
      api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
      api->Notepads[ notepad ] = note;
      _Objects_Put( &the_thread->Object );
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      return _RTEMS_tasks_MP_Send_request_packet(
        RTEMS_TASKS_MP_SET_NOTE_REQUEST,
        id,
        0,          /* Not used */
        notepad,
        note
      );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
Example #12
0
int pthread_getattr_np(
  pthread_t       id,
  pthread_attr_t *attr
)
{
  Objects_Locations        location;
  POSIX_API_Control       *api;
  Thread_Control          *the_thread;

  if ( !attr )
    return EINVAL;

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

    case OBJECTS_LOCAL:
      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
      _POSIX_Threads_Copy_attributes( attr, &api->Attributes);
      _Objects_Put( &the_thread->Object );
      return 0;

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

  return ESRCH;
}
int _Scheduler_CBS_Get_execution_time (
  Scheduler_CBS_Server_id   server_id,
  time_t                   *exec_time,
  time_t                   *abs_time
)
{
  Objects_Locations location;
  Thread_Control *the_thread;

  if ( server_id >= _Scheduler_CBS_Maximum_servers )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  if ( !_Scheduler_CBS_Server_list[server_id] )
    return SCHEDULER_CBS_ERROR_NOSERVER;
  if ( _Scheduler_CBS_Server_list[server_id]->task_id == -1 ) {
    *exec_time = 0;
    return SCHEDULER_CBS_OK;
  }

  the_thread = _Thread_Get(
                 _Scheduler_CBS_Server_list[server_id]->task_id,
                 &location
               );
  /* The routine _Thread_Get may disable dispatch and not enable again. */
  if ( the_thread ) {
    *exec_time = _Scheduler_CBS_Server_list[server_id]->parameters.budget -
      the_thread->cpu_time_budget;
    _Objects_Put( &the_thread->Object );
  }
  else {
    *exec_time = _Scheduler_CBS_Server_list[server_id]->parameters.budget;
  }
  return SCHEDULER_CBS_OK;
}
Example #14
0
int sem_post(
  sem_t  *sem
)
{
  POSIX_Semaphore_Control          *the_semaphore;
  Objects_Locations                 location;

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

    case OBJECTS_LOCAL:
      _CORE_semaphore_Surrender(
        &the_semaphore->Semaphore,
        the_semaphore->Object.id,
#if defined(RTEMS_MULTIPROCESSING)
        NULL         /* POSIX Semaphores are local only */
#else
        NULL
#endif
      );
      _Objects_Put( &the_semaphore->Object );
      return 0;

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

  rtems_set_errno_and_return_minus_one( EINVAL );
}
Example #15
0
int pthread_rwlock_unlock(
  pthread_rwlock_t  *rwlock
)
{
  POSIX_RWLock_Control  *the_rwlock;
  Objects_Locations      location;
  CORE_RWLock_Status     status;

  if ( !rwlock )
    return EINVAL;

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

    case OBJECTS_LOCAL:
      status = _CORE_RWLock_Release( &the_rwlock->RWLock, _Thread_Executing );
      _Objects_Put( &the_rwlock->Object );
      return _POSIX_RWLock_Translate_core_RWLock_return_code( status );

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

  return EINVAL;
}
Example #16
0
int sem_close(
    sem_t *sem
)
{
    POSIX_Semaphore_Control          *the_semaphore;
    Objects_Locations                 location;

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

    case OBJECTS_LOCAL:
        the_semaphore->open_count -= 1;
        _POSIX_Semaphore_Delete( the_semaphore );
        _Objects_Put( &the_semaphore->Object );
        _Objects_Allocator_unlock();
        return 0;

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

    _Objects_Allocator_unlock();

    rtems_set_errno_and_return_minus_one( EINVAL );
}
Example #17
0
/*
 *  17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
 */
int pthread_key_delete(
  pthread_key_t  key
)
{
  POSIX_Keys_Control *the_key;
  Objects_Locations   location;

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

    case OBJECTS_LOCAL:
      _POSIX_Keys_Free_memory( the_key );

      /*
       *  NOTE:  The destructor is not called and it is the responsibility
       *         of the application to free the memory.
       */
      _POSIX_Keys_Free( the_key );
      _Objects_Put(&the_key->Object);
      _Objects_Allocator_unlock();
      return 0;

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

  _Objects_Allocator_unlock();

  return EINVAL;
}
Example #18
0
rtems_status_code rtems_task_resume(
  rtems_id id
)
{
  Thread_Control          *the_thread;
  Objects_Locations        location;
  States_Control           previous_state;

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

    case OBJECTS_LOCAL:
      previous_state = _Thread_Clear_state( the_thread, STATES_SUSPENDED );
      _Objects_Put( &the_thread->Object );

      return _States_Is_suspended( previous_state ) ?
        RTEMS_SUCCESSFUL : RTEMS_INCORRECT_STATE;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      return _RTEMS_tasks_MP_Send_request_packet(
          RTEMS_TASKS_MP_RESUME_REQUEST,
          id,
          0,          /* Not used */
          0,          /* Not used */
          0           /* Not used */
        );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
Example #19
0
int pthread_getaffinity_np(
  const pthread_t       id,
  size_t                cpusetsize,
  cpu_set_t            *cpuset
)
{
  Objects_Locations        location;
  Thread_Control          *the_thread;
  bool                     ok;

  if ( !cpuset )
    return EFAULT;

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

    case OBJECTS_LOCAL:
      ok = _Scheduler_Get_affinity(
        the_thread,
        cpusetsize,
        cpuset
      );
      _Objects_Put( &the_thread->Object );
      return ok ? 0 : EINVAL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }
  return ESRCH;
}
Example #20
0
rtems_status_code rtems_port_delete(
  rtems_id id
)
{
  register Dual_ported_memory_Control *the_port;
  Objects_Locations                    location;

  the_port = _Dual_ported_memory_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object );
      _Dual_ported_memory_Free( the_port );
      _Objects_Put( &the_port->Object );
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:        /* this error cannot be returned */
#endif
    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
Example #21
0
/**
 *  11.4.2 Initializing and Destroying a Condition Variable,
 *         P1003.1c/Draft 10, p. 87
 */
int pthread_cond_destroy(
  pthread_cond_t           *cond
)
{
  POSIX_Condition_variables_Control *the_cond;
  Objects_Locations                  location;

  _Objects_Allocator_lock();
  the_cond = _POSIX_Condition_variables_Get( cond, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:

      if (
        _Thread_queue_First(
          &the_cond->Wait_queue,
          POSIX_CONDITION_VARIABLES_TQ_OPERATIONS
        )
      ) {
        _Objects_Put( &the_cond->Object );
        _Objects_Allocator_unlock();
        return EBUSY;
      }

      _Objects_Close(
        &_POSIX_Condition_variables_Information,
        &the_cond->Object
      );
      _Objects_Put( &the_cond->Object );
      _POSIX_Condition_variables_Free( the_cond );
      _Objects_Allocator_unlock();
      return 0;

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

  _Objects_Allocator_unlock();

  return EINVAL;
}
int _Scheduler_CBS_Attach_thread (
  Scheduler_CBS_Server_id server_id,
  rtems_id                task_id
)
{
  Objects_Locations location;
  Thread_Control *the_thread;

  if ( server_id >= _Scheduler_CBS_Maximum_servers )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;

  /* Server is not valid. */
  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
    return SCHEDULER_CBS_ERROR_NOSERVER;

  /* Server is already attached to a thread. */
  if ( _Scheduler_CBS_Server_list[server_id].task_id != -1 )
    return SCHEDULER_CBS_ERROR_FULL;

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

    /* Thread is already attached to a server. */
    if ( node->cbs_server ) {
      _Objects_Put( &the_thread->Object );
      return SCHEDULER_CBS_ERROR_FULL;
    }

    _Scheduler_CBS_Server_list[server_id].task_id = task_id;
    node->cbs_server = &_Scheduler_CBS_Server_list[server_id];

    the_thread->budget_callout   = _Scheduler_CBS_Budget_callout;
    the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
    the_thread->is_preemptible   = true;

    _Objects_Put( &the_thread->Object );
  } else {
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  }

  return SCHEDULER_CBS_OK;
}
Example #23
0
rtems_status_code rtems_message_queue_delete(
  rtems_id id
)
{
  register Message_queue_Control *the_message_queue;
  Objects_Locations               location;

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

    case OBJECTS_LOCAL:
      _Objects_Close( &_Message_queue_Information,
                      &the_message_queue->Object );

      _CORE_message_queue_Close(
        &the_message_queue->message_queue,
        #if defined(RTEMS_MULTIPROCESSING)
          _Message_queue_MP_Send_object_was_deleted,
        #else
          NULL,
        #endif
        CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED
      );

      _Message_queue_Free( the_message_queue );

#if defined(RTEMS_MULTIPROCESSING)
      if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) {
        _Objects_MP_Close(
          &_Message_queue_Information,
          the_message_queue->Object.id
        );

        _Message_queue_MP_Send_process_packet(
          MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
          the_message_queue->Object.id,
          0,                                 /* Not used */
          0
        );
      }
#endif
      _Objects_Put( &the_message_queue->Object );
      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;
}
Example #24
0
/**
 *  This directive allows a thread to delete a rwlock specified by
 *  the rwlock id.  The rwlock is freed back to the inactive
 *  rwlock chain.
 *
 *  @param[in] rwlock is the rwlock id
 *
 *  @return This method returns 0 if there was not an
 *  error. Otherwise, a status code is returned indicating the
 *  source of the error.
 */
int pthread_rwlock_destroy(
  pthread_rwlock_t *rwlock
)
{
  POSIX_RWLock_Control *the_rwlock = NULL;
  Objects_Locations      location;

  if ( !rwlock )
    return EINVAL;

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

    case OBJECTS_LOCAL:
      /*
       *  If there is at least one thread waiting, then do not delete it.
       */
      if ( _Thread_queue_First( &the_rwlock->RWLock.Wait_queue ) != NULL ) {
        _Objects_Put( &the_rwlock->Object );
        return EBUSY;
      }

      /*
       *  POSIX doesn't require behavior when it is locked.
       */

      _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object );

      _POSIX_RWLock_Free( the_rwlock );

      _Objects_Put( &the_rwlock->Object );
      return 0;

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

  return EINVAL;
}
Example #25
0
rtems_status_code rtems_message_queue_urgent(
  rtems_id    id,
  const void *buffer,
  size_t      size
)
{
  Message_queue_Control           *the_message_queue;
  Objects_Locations                location;
  CORE_message_queue_Status        status;

  if ( !buffer )
    return RTEMS_INVALID_ADDRESS;

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

    case OBJECTS_LOCAL:
      status = _CORE_message_queue_Urgent(
        &the_message_queue->message_queue,
        buffer,
        size,
        id,
        MESSAGE_QUEUE_MP_HANDLER,
        false,   /* sender does not block */
        0        /* no timeout */
      );
      _Objects_Put( &the_message_queue->Object );

      /*
       *  Since this API does not allow for blocking sends, we can directly
       *  return the returned status.
       */

      return _Message_queue_Translate_core_message_queue_return_code(status);

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      return _Message_queue_MP_Send_request_packet(
        MESSAGE_QUEUE_MP_URGENT_REQUEST,
        id,
        buffer,
        &size,
        0,                               /* option_set */
        MPCI_DEFAULT_TIMEOUT
      );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
Example #26
0
rtems_status_code rtems_timer_server_fire_when(
  rtems_id                           id,
  rtems_time_of_day                  *wall_time,
  rtems_timer_service_routine_entry  routine,
  void                              *user_data
)
{
  Timer_Control        *the_timer;
  Objects_Locations     location;
  rtems_interval        seconds;
  Timer_server_Control *timer_server = _Timer_server;

  if ( !timer_server )
    return RTEMS_INCORRECT_STATE;

  if ( !_TOD_Is_set() )
    return RTEMS_NOT_DEFINED;

  if ( !routine )
    return RTEMS_INVALID_ADDRESS;

  if ( !_TOD_Validate( wall_time ) )
    return RTEMS_INVALID_CLOCK;

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

  the_timer = _Timer_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      (void) _Watchdog_Remove( &the_timer->Ticker );
      the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK;
      _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
      the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch();

      (*timer_server->schedule_operation)( timer_server, the_timer );

      _Objects_Put( &the_timer->Object );
      return RTEMS_SUCCESSFUL;

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

  return RTEMS_INVALID_ID;
}
Example #27
0
/*
 *  _POSIX_Keys_Run_destructors
 *
 *  17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
 *
 *  NOTE:  This is the routine executed when a thread exits to
 *         run through all the keys and do the destructor action.
 */
void _POSIX_Keys_Run_destructors(
  Thread_Control *thread
)
{
  Chain_Control *chain;
  POSIX_Keys_Key_value_pair *iter, *next;
  void *value;
  void (*destructor) (void *);
  POSIX_Keys_Control *the_key;
  Objects_Locations location;

  _Thread_Disable_dispatch();

  chain = &(
      (POSIX_API_Control *)thread->API_Extensions[ THREAD_API_POSIX ]
  )->Key_Chain;
  iter = (POSIX_Keys_Key_value_pair *) _Chain_First( chain );
  while ( !_Chain_Is_tail( chain, &iter->Key_values_per_thread_node ) ) {
    next = (POSIX_Keys_Key_value_pair *)
      _Chain_Next( &iter->Key_values_per_thread_node );

    /**
     * remove key from rbtree and chain.
     * here Chain_Node *iter can be convert to POSIX_Keys_Key_value_pair *,
     * because Chain_Node is the first member of POSIX_Keys_Key_value_pair
     * structure.
     */
    _RBTree_Extract(
        &_POSIX_Keys_Key_value_lookup_tree,
        &iter->Key_value_lookup_node
    );
    _Chain_Extract_unprotected( &iter->Key_values_per_thread_node );

    /**
     * run key value's destructor if destructor and value are both non-null.
     */
    the_key = _POSIX_Keys_Get( iter->key, &location );
    destructor = the_key->destructor;
    value = iter->value;
    if ( destructor != NULL && value != NULL )
      (*destructor)( value );

    _Objects_Put( &the_key->Object );

    _POSIX_Keys_Key_value_pair_free( iter );

    iter = next;
  }

  _Thread_Enable_dispatch();
}
Example #28
0
/**
 *  This directive allows a thread to delete a barrier specified by
 *  the barrier id.  The barrier is freed back to the inactive
 *  barrier chain.
 *
 *  @param[in] barrier is the barrier id
 * 
 *  @return This method returns 0 if there was not an
 *  error. Otherwise, a status code is returned indicating the
 *  source of the error.
 */
int pthread_barrier_destroy(
  pthread_barrier_t *barrier
)
{
  POSIX_Barrier_Control *the_barrier = NULL;
  Objects_Locations      location;

  if ( !barrier )
    return EINVAL;

  _Objects_Allocator_lock();
  the_barrier = _POSIX_Barrier_Get( barrier, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( the_barrier->Barrier.number_of_waiting_threads != 0 ) {
        _Objects_Put( &the_barrier->Object );
        return EBUSY;
      }

      _Objects_Close( &_POSIX_Barrier_Information, &the_barrier->Object );
      _Objects_Put( &the_barrier->Object );

      _POSIX_Barrier_Free( the_barrier );
      _Objects_Allocator_unlock();
      return 0;

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

  _Objects_Allocator_unlock();

  return EINVAL;
}
Example #29
0
rtems_status_code rtems_task_suspend(
  rtems_id id
)
{
  Thread_Control          *the_thread;
  Objects_Locations        location;

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

    case OBJECTS_LOCAL:
      if ( !_States_Is_suspended( the_thread->current_state ) ) {
        _Thread_Suspend( the_thread );
        _Objects_Put( &the_thread->Object );
        return RTEMS_SUCCESSFUL;
      }
      _Objects_Put( &the_thread->Object );
      return RTEMS_ALREADY_SUSPENDED;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      return _RTEMS_tasks_MP_Send_request_packet(
        RTEMS_TASKS_MP_SUSPEND_REQUEST,
        id,
        0,          /* Not used */
        0,          /* Not used */
        0           /* Not used */
      );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
Example #30
0
rtems_status_code rtems_task_delete(
  rtems_id id
)
{
  Thread_Control    *the_thread;
  Objects_Locations  location;
  bool               previous_life_protection;

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

    case OBJECTS_LOCAL:
      #if defined(RTEMS_MULTIPROCESSING)
        if ( the_thread->is_global ) {
          _Objects_MP_Close(
            &_RTEMS_tasks_Information.Objects,
            the_thread->Object.id
          );
          _RTEMS_tasks_MP_Send_process_packet(
            RTEMS_TASKS_MP_ANNOUNCE_DELETE,
            the_thread->Object.id,
            0                                /* Not used */
          );
        }
      #endif

      _Thread_Close( the_thread, _Thread_Executing );

      _Objects_Put( &the_thread->Object );
      _Thread_Set_life_protection( previous_life_protection );
      return RTEMS_SUCCESSFUL;

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

    case OBJECTS_ERROR:
      break;
  }

  _Thread_Set_life_protection( previous_life_protection );

  return RTEMS_INVALID_ID;
}