ER del_mbx(
  ID mbxid
)
{
  register ITRON_Mailbox_Control *the_mailbox;
  Objects_Locations               location;

  the_mailbox= _ITRON_Mailbox_Get( mbxid, &location );
  switch ( location ) {
    case OBJECTS_ERROR:
    case OBJECTS_REMOTE:
      return _ITRON_Mailbox_Clarify_get_id_error( mbxid );

    case OBJECTS_LOCAL:
      _Objects_Close( &_ITRON_Mailbox_Information, &the_mailbox->Object );

      _CORE_message_queue_Close(
        &the_mailbox->message_queue,
        NULL,                      /* Multiprocessing not supported */
        CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED
      );

      _ITRON_Mailbox_Free(the_mailbox);
      break;
  }

  _ITRON_return_errorno( E_OK );
}
rtems_status_code rtems_rate_monotonic_delete(
  rtems_id id
)
{
  Rate_monotonic_Control *the_period;
  Objects_Locations       location;

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

    case OBJECTS_LOCAL:
      _Objects_Close( &_Rate_monotonic_Information, &the_period->Object );
      (void) _Watchdog_Remove( &the_period->Timer );
      the_period->state = RATE_MONOTONIC_INACTIVE;
      _Rate_monotonic_Free( 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;
}
示例#3
0
static void _Thread_Make_zombie( Thread_Control *the_thread )
{
#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
  if ( _Thread_Owns_resources( the_thread ) ) {
    _Internal_error( INTERNAL_ERROR_RESOURCE_IN_USE );
  }
#endif

  _Objects_Close(
    _Objects_Get_information_id( the_thread->Object.id ),
    &the_thread->Object
  );

  _Thread_Set_state( the_thread, STATES_ZOMBIE );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Thread_Timer_remove( the_thread );

  /*
   * Add the thread to the thread zombie chain before we wake up joining
   * threads, so that they are able to clean up the thread immediately.  This
   * matters for SMP configurations.
   */
  _Thread_Add_to_zombie_chain( the_thread );

  _Thread_Wake_up_joining_threads( the_thread );
}
int pthread_cond_destroy(
  pthread_cond_t           *cond
)
{
  POSIX_Condition_variables_Control *the_cond;
  Objects_Locations                  location;

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

    case OBJECTS_LOCAL:

      if ( _Thread_queue_First( &the_cond->Wait_queue ) ) {
        _Thread_Enable_dispatch();
        return EBUSY;
      }

      _Objects_Close(
        &_POSIX_Condition_variables_Information,
        &the_cond->Object
      );

      _POSIX_Condition_variables_Free( the_cond );
      _Thread_Enable_dispatch();
      return 0;

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

  return EINVAL;
}
示例#5
0
rtems_status_code rtems_timer_delete(
  rtems_id id
)
{
  Timer_Control     *the_timer;
  Objects_Locations  location;

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

    case OBJECTS_LOCAL:
      _Objects_Close( &_Timer_Information, &the_timer->Object );
      (void) _Watchdog_Remove( &the_timer->Ticker );
      _Timer_Free( the_timer );
      _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;
}
epos_status_code epos_barrier_delete(
  epos_id   id
)
{
  Barrier_Control   *the_barrier;
  Objects_Locations  location;

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

    case OBJECTS_LOCAL:
      _CORE_barrier_Flush(
        &the_barrier->Barrier,
        NULL,
        CORE_BARRIER_WAS_DELETED
      );

      _Objects_Close( &_Barrier_Information, &the_barrier->Object );

      _Barrier_Free( the_barrier );

      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

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

  return RTEMS_INVALID_ID;
}
示例#7
0
static void _Thread_Make_zombie( Thread_Control *the_thread )
{
  ISR_lock_Context lock_context;
  Thread_Zombie_control *zombies = &_Thread_Zombies;

  if ( _Thread_Owns_resources( the_thread ) ) {
    _Terminate(
      INTERNAL_ERROR_CORE,
      false,
      INTERNAL_ERROR_RESOURCE_IN_USE
    );
  }

  _Objects_Close(
    _Objects_Get_information_id( the_thread->Object.id ),
    &the_thread->Object
  );

  _Thread_Set_state( the_thread, STATES_ZOMBIE );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Watchdog_Remove_ticks( &the_thread->Timer );

  _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );
  _Chain_Append_unprotected( &zombies->Chain, &the_thread->Object.Node );
  _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );
}
示例#8
0
int pthread_spin_destroy(
  pthread_spinlock_t *spinlock
)
{
  POSIX_Spinlock_Control *the_spinlock = NULL;
  Objects_Locations      location;

  if ( !spinlock )
    return EINVAL;

  the_spinlock = _POSIX_Spinlock_Get( spinlock, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( _CORE_spinlock_Is_busy( &the_spinlock->Spinlock ) ) {
        _Thread_Enable_dispatch();
        return EBUSY;
      }

      _Objects_Close( &_POSIX_Spinlock_Information, &the_spinlock->Object );

      _POSIX_Spinlock_Free( the_spinlock );

      _Thread_Enable_dispatch();
      return 0;

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

  return EINVAL;
}
示例#9
0
void _Thread_Close( Thread_Control *the_thread, Thread_Control *executing )
{
  _Assert( _Thread_Is_life_protected( executing->Life.state ) );

  _Objects_Close(
    _Objects_Get_information_id( the_thread->Object.id ),
    &the_thread->Object
  );

  if ( _States_Is_dormant( the_thread->current_state ) ) {
    _Thread_Make_zombie( the_thread );
  } else {
    if (
      the_thread != executing
        && !_Thread_Is_life_terminating( executing->Life.state )
    ) {
      /*
       * Wait for termination of victim thread.  If the executing thread is
       * also terminated, then do not wait.  This avoids potential cyclic
       * dependencies and thus dead lock.
       */
       the_thread->Life.terminator = executing;
       _Thread_Set_state( executing, STATES_WAITING_FOR_TERMINATION );
    }

    _Thread_Request_life_change(
      the_thread,
      executing,
      executing->current_priority,
      THREAD_LIFE_TERMINATING
    );
  }
}
示例#10
0
文件: shmunlink.c 项目: gedare/rtems
int shm_unlink( const char *name )
{
  Objects_Get_by_name_error obj_err;
  int err = 0;
  POSIX_Shm_Control *shm;

  shm = _POSIX_Shm_Get_by_name( name, 0, &obj_err );
  switch ( obj_err ) {
    case OBJECTS_GET_BY_NAME_INVALID_NAME:
      err = ENOENT;
      break;

    case OBJECTS_GET_BY_NAME_NAME_TOO_LONG:
      err = ENAMETOOLONG;
      break;

    case OBJECTS_GET_BY_NAME_NO_OBJECT:
    default:
      _Objects_Close( &_POSIX_Shm_Information, &shm->Object );
      if ( shm->reference_count == 0 ) {
        /* Only remove the shm object if no references exist to it. Otherwise,
         * the shm object will be freed later in _POSIX_Shm_Attempt_delete */
        _POSIX_Shm_Free( shm );
      }
      break;
  }
  if ( err != 0 )
    rtems_set_errno_and_return_minus_one( err );
  return 0;
}
示例#11
0
void _POSIX_Message_queue_Delete(
  POSIX_Message_queue_Control *the_mq
)
{
  if ( !the_mq->linked && !the_mq->open_count ) {
      Objects_Control *the_object = &the_mq->Object;

      #if defined(RTEMS_DEBUG)
        /*
         *  the name memory will have been freed by unlink.
         */
	if ( the_object->name.name_p ) {
          printk(
            "POSIX MQ name (%p) not freed by unlink\n",
	    (void *)the_object->name.name_p
          );
	  _Workspace_Free( (void *)the_object->name.name_p );
        }
      #endif

      _Objects_Close( &_POSIX_Message_queue_Information, the_object );

      _CORE_message_queue_Close(
        &the_mq->Message_queue,
        NULL,        /* no MP support */
        CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED
      );

    _POSIX_Message_queue_Free( the_mq );

  }
}
示例#12
0
rtems_status_code rtems_port_delete(
  rtems_id id
)
{
  Dual_ported_memory_Control          *the_port;
  Objects_Locations                    location;

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

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

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

  _Objects_Allocator_unlock();

  return RTEMS_INVALID_ID;
}
示例#13
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
      _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;
}
rtems_status_code rtems_partition_delete(
  rtems_id id
)
{
  register 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

        _Thread_Enable_dispatch();
        return RTEMS_SUCCESSFUL;
      }
      _Thread_Enable_dispatch();
      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;
}
示例#15
0
void _POSIX_Semaphore_Delete(
  POSIX_Semaphore_Control *the_semaphore
)
{
  if ( !the_semaphore->linked && !the_semaphore->open_count ) {
      _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );

      _CORE_semaphore_Flush(
        &the_semaphore->Semaphore,
        NULL,
        -1
      );

    _POSIX_Semaphore_Free( the_semaphore );
  }
}
示例#16
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;
}
示例#17
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;
}
示例#18
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 );
}
示例#19
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;
  ISR_lock_Context     lock_context;

  _Objects_Allocator_lock();

  ptimer = _POSIX_Timer_Get( timerid, &lock_context );
  if ( ptimer != NULL ) {
    Per_CPU_Control *cpu;

    _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object );
    cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
    ptimer->state = POSIX_TIMER_STATE_FREE;
    _Watchdog_Remove(
      &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
      &ptimer->Timer
    );
    _POSIX_Timer_Release( cpu, &lock_context );
    _POSIX_Timer_Free( ptimer );
    _Objects_Allocator_unlock();
    return 0;
  }

  _Objects_Allocator_unlock();

  rtems_set_errno_and_return_minus_one( EINVAL );
}
示例#20
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;
}
示例#21
0
int pthread_mutex_destroy(
  pthread_mutex_t           *mutex
)
{
  register POSIX_Mutex_Control *the_mutex;
  Objects_Locations             location;

  the_mutex = _POSIX_Mutex_Get( mutex, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
       /*
        * XXX: There is an error for the mutex being locked
        *  or being in use by a condition variable.
        */

      if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
        _Thread_Enable_dispatch();
        return EBUSY;
      }

      _Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );

      _CORE_mutex_Flush( &the_mutex->Mutex, NULL, EINVAL );

      _POSIX_Mutex_Free( the_mutex );
      _Thread_Enable_dispatch();
      return 0;

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

  return EINVAL;
}
示例#22
0
rtems_status_code rtems_region_delete(
  rtems_id id
)
{
  Objects_Locations   location;
  rtems_status_code   return_status;
  Region_Control     *the_region;

  _RTEMS_Lock_allocator();

    the_region = _Region_Get( id, &location );
    switch ( location ) {

      case OBJECTS_LOCAL:
        _Region_Debug_Walk( the_region, 5 );
        if ( the_region->number_of_used_blocks != 0 )
          return_status = RTEMS_RESOURCE_IN_USE;
        else {
          _Objects_Close( &_Region_Information, &the_region->Object );
          _Region_Free( the_region );
          return_status = RTEMS_SUCCESSFUL;
        }
        break;

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

      case OBJECTS_ERROR:
      default:
        return_status = RTEMS_INVALID_ID;
        break;
    }

  _RTEMS_Unlock_allocator();
  return return_status;
}
示例#23
0
rtems_status_code rtems_extension_delete(
  rtems_id id
)
{
  rtems_status_code  status;
  Extension_Control *the_extension;

  _Objects_Allocator_lock();

  the_extension = _Extension_Get( id );

  if ( the_extension != NULL ) {
    _Objects_Close( &_Extension_Information, &the_extension->Object );
    _User_extensions_Remove_set( &the_extension->Extension );
    _Extension_Free( the_extension );
    status = RTEMS_SUCCESSFUL;
  } else {
    status = RTEMS_INVALID_ID;
  }

  _Objects_Allocator_unlock();
  return status;
}
示例#24
0
int pthread_rwlock_destroy(
  pthread_rwlock_t *rwlock
)
{
  POSIX_RWLock_Control *the_rwlock;
  ISR_lock_Context      lock_context;

  _Objects_Allocator_lock();
  the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );

  if ( the_rwlock == NULL ) {
    _Objects_Allocator_unlock();
    return EINVAL;
  }

  _CORE_RWLock_Acquire_critical( &the_rwlock->RWLock, &lock_context );

  /*
   *  If there is at least one thread waiting, then do not delete it.
   */

  if ( !_Thread_queue_Is_empty( &the_rwlock->RWLock.Wait_queue.Queue ) ) {
    _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context );
    _Objects_Allocator_unlock();
    return EBUSY;
  }

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

  _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object );
  _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context );
  _POSIX_RWLock_Free( the_rwlock );
  _Objects_Allocator_unlock();
  return 0;
}
示例#25
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;
}
示例#26
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 */
}
示例#27
0
rtems_status_code rtems_semaphore_delete(
  rtems_id   id
)
{
  Semaphore_Control    *the_semaphore;
  Thread_queue_Context  queue_context;
  Status_Control        status;

  _Objects_Allocator_lock();
  the_semaphore = _Semaphore_Get( id, &queue_context );

  if ( the_semaphore == NULL ) {
    _Objects_Allocator_unlock();

#if defined(RTEMS_MULTIPROCESSING)
    if ( _Semaphore_MP_Is_remote( id ) ) {
      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
    }
#endif

    return RTEMS_INVALID_ID;
  }

  _Thread_queue_Acquire_critical(
    &the_semaphore->Core_control.Wait_queue,
    &queue_context.Lock_context
  );

  switch ( the_semaphore->variant ) {
    case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
      if (
        _CORE_mutex_Is_locked(
          &the_semaphore->Core_control.Mutex.Recursive.Mutex
        )
      ) {
        status = STATUS_RESOURCE_IN_USE;
      } else {
        status = STATUS_SUCCESSFUL;
      }

      break;
#if defined(RTEMS_SMP)
    case SEMAPHORE_VARIANT_MRSP:
      status = _MRSP_Can_destroy( &the_semaphore->Core_control.MRSP );
      break;
#endif
    default:
      _Assert(
        the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
          || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
      );
      status = STATUS_SUCCESSFUL;
      break;
  }

  if ( status != STATUS_SUCCESSFUL ) {
    _Thread_queue_Release(
      &the_semaphore->Core_control.Wait_queue,
      &queue_context.Lock_context
    );
    _Objects_Allocator_unlock();
    return _Status_Get( status );
  }

  _Objects_Close( &_Semaphore_Information, &the_semaphore->Object );

  switch ( the_semaphore->variant ) {
#if defined(RTEMS_SMP)
    case SEMAPHORE_VARIANT_MRSP:
      _MRSP_Destroy( &the_semaphore->Core_control.MRSP, &queue_context );
      break;
#endif
    default:
      _Assert(
        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY
          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING
          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
          || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
      );
      _Thread_queue_Flush_critical(
        &the_semaphore->Core_control.Wait_queue.Queue,
        _Semaphore_Get_operations( the_semaphore ),
        _Thread_queue_Flush_status_object_was_deleted,
        &queue_context
      );
      _Thread_queue_Destroy( &the_semaphore->Core_control.Wait_queue );
      break;
  }

#if defined(RTEMS_MULTIPROCESSING)
  if ( the_semaphore->is_global ) {

    _Objects_MP_Close( &_Semaphore_Information, id );

    _Semaphore_MP_Send_process_packet(
      SEMAPHORE_MP_ANNOUNCE_DELETE,
      id,
      0,                         /* Not used */
      0                          /* Not used */
    );
  }
#endif

  _Semaphore_Free( the_semaphore );
  _Objects_Allocator_unlock();
  return RTEMS_SUCCESSFUL;
}
示例#28
0
rtems_status_code rtems_semaphore_delete(
  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) ) {
        if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) &&
             !_Attributes_Is_simple_binary_semaphore(
                 the_semaphore->attribute_set ) ) {
          _Thread_Enable_dispatch();
          return RTEMS_RESOURCE_IN_USE;
        }
        _CORE_mutex_Flush(
          &the_semaphore->Core_control.mutex,
          SEMAPHORE_MP_OBJECT_WAS_DELETED,
          CORE_MUTEX_WAS_DELETED
        );
      } else {
        _CORE_semaphore_Flush(
          &the_semaphore->Core_control.semaphore,
          SEMAPHORE_MP_OBJECT_WAS_DELETED,
          CORE_SEMAPHORE_WAS_DELETED
        );
     }

      _Objects_Close( &_Semaphore_Information, &the_semaphore->Object );

      _Semaphore_Free( the_semaphore );

#if defined(RTEMS_MULTIPROCESSING)
      if ( _Attributes_Is_global( the_semaphore->attribute_set ) ) {

        _Objects_MP_Close( &_Semaphore_Information, the_semaphore->Object.id );

        _Semaphore_MP_Send_process_packet(
          SEMAPHORE_MP_ANNOUNCE_DELETE,
          the_semaphore->Object.id,
          0,                         /* Not used */
          0                          /* Not used */
        );
      }
#endif
      _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;
}
示例#29
0
void _Thread_Close(
  Objects_Information  *information,
  Thread_Control       *the_thread
)
{
  /*
   *  Now we are in a dispatching critical section again and we
   *  can take the thread OUT of the published set.  It is invalid
   *  to use this thread's Id after this call.  This will prevent
   *  any other task from attempting to initiate a call on this task.
   */
  _Objects_Invalidate_Id( information, &the_thread->Object );

  /*
   *  We assume the Allocator Mutex is locked when we get here.
   *  This provides sufficient protection to let the user extensions
   *  run but as soon as we get back, we will make the thread
   *  disappear and set a transient state on it.  So we temporarily
   *  unnest dispatching.
   */
  _Thread_Unnest_dispatch();

  _User_extensions_Thread_delete( the_thread );

  _Thread_Disable_dispatch();

  /*
   *  Now we are in a dispatching critical section again and we
   *  can take the thread OUT of the published set.  It is invalid
   *  to use this thread's Id OR name after this call.
   */
  _Objects_Close( information, &the_thread->Object );

  /*
   *  By setting the dormant state, the thread will not be considered
   *  for scheduling when we remove any blocking states.
   */
  _Thread_Set_state( the_thread, STATES_DORMANT );

  if ( !_Thread_queue_Extract_with_proxy( the_thread ) ) {
    if ( _Watchdog_Is_active( &the_thread->Timer ) )
      (void) _Watchdog_Remove( &the_thread->Timer );
  }

  /*
   * Free the per-thread scheduling information.
   */
  _Scheduler_Free( the_thread );

  /*
   *  The thread might have been FP.  So deal with that.
   */
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
  if ( _Thread_Is_allocated_fp( the_thread ) )
    _Thread_Deallocate_fp();
#endif
  the_thread->fp_context = NULL;

  _Workspace_Free( the_thread->Start.fp_context );
#endif

  /*
   *  Free the rest of the memory associated with this task
   *  and set the associated pointers to NULL for safety.
   */
  _Thread_Stack_Free( the_thread );
  the_thread->Start.stack = NULL;

  _Workspace_Free( the_thread->extensions );
  the_thread->extensions = NULL;

  _Workspace_Free( the_thread->Start.tls_area );
}