rtems_status_code rtems_task_delete(
  rtems_id id
)
{
  register Thread_Control *the_thread;
  Objects_Locations        location;
  Objects_Information     *the_information;

  _RTEMS_Lock_allocator();

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

    case OBJECTS_LOCAL:
      the_information = _Objects_Get_information_id( the_thread->Object.id );

      #if defined(RTEMS_DEBUG)
	if ( !the_information ) {
	  _Thread_Enable_dispatch();
	  return RTEMS_INVALID_ID;
	  /* This should never happen if _Thread_Get() works right */
	}
      #endif

      #if defined(RTEMS_MULTIPROCESSING)
        if ( the_thread->is_global ) {
          _Objects_MP_Close( &_RTEMS_tasks_Information, 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_information, the_thread );

      _RTEMS_tasks_Free( the_thread );

      _RTEMS_Unlock_allocator();
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

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

    case OBJECTS_ERROR:
      break;
  }

  _RTEMS_Unlock_allocator();
  return RTEMS_INVALID_ID;
}
Exemplo n.º 2
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
int sem_unlink(
  const char *name
)
{
  int  status;
  register POSIX_Semaphore_Control *the_semaphore;
  sem_t                        the_semaphore_id;

  _Thread_Disable_dispatch();

  status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
  if ( status != 0 ) {
    _Thread_Enable_dispatch();
    rtems_set_errno_and_return_minus_one( status );
  }

  /*
   *  Don't support unlinking a remote semaphore.
   */

#if defined(RTEMS_MULTIPROCESSING)
  if ( !_Objects_Is_local_id((Objects_Id)the_semaphore_id) ) {
    _Thread_Enable_dispatch();
    rtems_set_errno_and_return_minus_one( ENOSYS );
  }
#endif

  the_semaphore = (POSIX_Semaphore_Control *) _Objects_Get_local_object(
    &_POSIX_Semaphore_Information,
    _Objects_Get_index( the_semaphore_id )
  );

#if defined(RTEMS_MULTIPROCESSING)
  if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
    _Objects_MP_Close( &_POSIX_Semaphore_Information, the_semaphore_id );
  }
#endif

  the_semaphore->linked = FALSE;
  _POSIX_Semaphore_Namespace_remove( the_semaphore );
  _POSIX_Semaphore_Delete( the_semaphore );

  _Thread_Enable_dispatch();
  return 0;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
Arquivo: taskmp.c Projeto: ray-x/rtems
void _RTEMS_tasks_MP_Process_packet (
  rtems_packet_prefix  *the_packet_prefix
)
{
  RTEMS_tasks_MP_Packet *the_packet;
  Thread_Control   *the_thread;
  bool           ignored;

  the_packet = (RTEMS_tasks_MP_Packet *) the_packet_prefix;

  switch ( the_packet->operation ) {

    case RTEMS_TASKS_MP_ANNOUNCE_CREATE:

      ignored = _Objects_MP_Allocate_and_open(
                  &_RTEMS_tasks_Information.Objects,
                  the_packet->name,
                  the_packet->Prefix.id,
                  true
                );

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case RTEMS_TASKS_MP_ANNOUNCE_DELETE:

      _Objects_MP_Close(
        &_RTEMS_tasks_Information.Objects,
        the_packet->Prefix.id
      );

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case RTEMS_TASKS_MP_SUSPEND_REQUEST:

      the_packet->Prefix.return_code = rtems_task_suspend(
        the_packet->Prefix.id
      );

      _RTEMS_tasks_MP_Send_response_packet(
        RTEMS_TASKS_MP_SUSPEND_RESPONSE,
        _Thread_Executing
      );
      break;

    case RTEMS_TASKS_MP_SUSPEND_RESPONSE:
    case RTEMS_TASKS_MP_RESUME_RESPONSE:
    case RTEMS_TASKS_MP_SET_NOTE_RESPONSE:

      the_thread = _MPCI_Process_response( the_packet_prefix );

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case RTEMS_TASKS_MP_RESUME_REQUEST:

      the_packet->Prefix.return_code = rtems_task_resume(
        the_packet->Prefix.id
      );

      _RTEMS_tasks_MP_Send_response_packet(
        RTEMS_TASKS_MP_RESUME_RESPONSE,
        _Thread_Executing
      );
      break;

    case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST:

      the_packet->Prefix.return_code = rtems_task_set_priority(
        the_packet->Prefix.id,
        the_packet->the_priority,
        &the_packet->the_priority
      );

      _RTEMS_tasks_MP_Send_response_packet(
        RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE,
        _Thread_Executing
      );
      break;

    case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE:

      the_thread = _MPCI_Process_response( the_packet_prefix );

      *(rtems_task_priority *)the_thread->Wait.return_argument =
                                               the_packet->the_priority;

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case RTEMS_TASKS_MP_GET_NOTE_REQUEST:

      the_packet->Prefix.return_code = rtems_task_get_note(
        the_packet->Prefix.id,
        the_packet->notepad,
        &the_packet->note
      );

      _RTEMS_tasks_MP_Send_response_packet(
        RTEMS_TASKS_MP_GET_NOTE_RESPONSE,
        _Thread_Executing
      );
      break;

    case RTEMS_TASKS_MP_GET_NOTE_RESPONSE:

      the_thread = _MPCI_Process_response( the_packet_prefix );

      *(uint32_t   *)the_thread->Wait.return_argument = the_packet->note;

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case RTEMS_TASKS_MP_SET_NOTE_REQUEST:

      the_packet->Prefix.return_code = rtems_task_set_note(
        the_packet->Prefix.id,
        the_packet->notepad,
        the_packet->note
      );

      _RTEMS_tasks_MP_Send_response_packet(
        RTEMS_TASKS_MP_SET_NOTE_RESPONSE,
        _Thread_Executing
      );
      break;
  }
}
Exemplo n.º 8
0
void _Message_queue_MP_Process_packet (
  rtems_packet_prefix   *the_packet_prefix
)
{
  Message_queue_MP_Packet *the_packet;
  Thread_Control          *the_thread;
  bool                     ignored;

  the_packet = (Message_queue_MP_Packet *) the_packet_prefix;

  switch ( the_packet->operation ) {

    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:

      ignored = _Objects_MP_Allocate_and_open(
                  &_Message_queue_Information,
                  the_packet->name,
                  the_packet->Prefix.id,
                  true
                );

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:

      _Objects_MP_Close( &_Message_queue_Information, the_packet->Prefix.id );

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:

      the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );

      if (! _Thread_Is_null( the_thread ) )
         _Thread_queue_Extract( the_thread );

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:

      the_packet->Prefix.return_code = rtems_message_queue_receive(
        the_packet->Prefix.id,
        the_packet->Buffer.buffer,
        &the_packet->size,
        the_packet->option_set,
        the_packet->Prefix.timeout
      );

      if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING )
        _Message_queue_MP_Send_response_packet(
          MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
          the_packet->Prefix.id,
          _Thread_Executing
        );
      break;

    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:

      the_thread = _MPCI_Process_response( the_packet_prefix );

      if (the_packet->Prefix.return_code == RTEMS_SUCCESSFUL) {
        *(size_t *) the_thread->Wait.return_argument =
           the_packet->size;

        _CORE_message_queue_Copy_buffer(
          the_packet->Buffer.buffer,
          the_thread->Wait.return_argument_second.mutable_object,
          the_packet->size
        );
      }

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case MESSAGE_QUEUE_MP_SEND_REQUEST:

      the_packet->Prefix.return_code = rtems_message_queue_send(
        the_packet->Prefix.id,
        the_packet->Buffer.buffer,
        the_packet->Buffer.size
      );

      _Message_queue_MP_Send_response_packet(
        MESSAGE_QUEUE_MP_SEND_RESPONSE,
        the_packet->Prefix.id,
        _Thread_Executing
      );
      break;

    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:

      the_thread = _MPCI_Process_response( the_packet_prefix );

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case MESSAGE_QUEUE_MP_URGENT_REQUEST:

      the_packet->Prefix.return_code = rtems_message_queue_urgent(
        the_packet->Prefix.id,
        the_packet->Buffer.buffer,
        the_packet->Buffer.size
      );

      _Message_queue_MP_Send_response_packet(
        MESSAGE_QUEUE_MP_URGENT_RESPONSE,
        the_packet->Prefix.id,
        _Thread_Executing
      );
      break;

    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:

      the_packet->Prefix.return_code = rtems_message_queue_broadcast(
        the_packet->Prefix.id,
        the_packet->Buffer.buffer,
        the_packet->Buffer.size,
        &the_packet->count
      );

      _Message_queue_MP_Send_response_packet(
        MESSAGE_QUEUE_MP_BROADCAST_RESPONSE,
        the_packet->Prefix.id,
        _Thread_Executing
      );
      break;

    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:

      the_thread = _MPCI_Process_response( the_packet_prefix );

      *(uint32_t *) the_thread->Wait.return_argument = the_packet->count;

      _MPCI_Return_packet( the_packet_prefix );
      break;

    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:

      the_packet->Prefix.return_code = rtems_message_queue_flush(
        the_packet->Prefix.id,
        &the_packet->count
      );

      _Message_queue_MP_Send_response_packet(
        MESSAGE_QUEUE_MP_FLUSH_RESPONSE,
        the_packet->Prefix.id,
        _Thread_Executing
      );
      break;

    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:

      the_packet->Prefix.return_code = rtems_message_queue_get_number_pending(
        the_packet->Prefix.id,
        &the_packet->count
      );

      _Message_queue_MP_Send_response_packet(
        MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE,
        the_packet->Prefix.id,
        _Thread_Executing
      );
      break;

  }
}
Exemplo n.º 9
0
void _Partition_MP_Process_packet (
    rtems_packet_prefix  *the_packet_prefix
)
{
    Partition_MP_Packet *the_packet;
    Thread_Control      *the_thread;

    the_packet = (Partition_MP_Packet *) the_packet_prefix;

    switch ( the_packet->operation ) {

    case PARTITION_MP_ANNOUNCE_CREATE:

        _Objects_MP_Allocate_and_open(
            &_Partition_Information,
            the_packet->name,
            the_packet->Prefix.id,
            true
        );

        _MPCI_Return_packet( the_packet_prefix );
        break;

    case PARTITION_MP_ANNOUNCE_DELETE:

        _Objects_MP_Close( &_Partition_Information, the_packet->Prefix.id );

        _MPCI_Return_packet( the_packet_prefix );
        break;

    case PARTITION_MP_EXTRACT_PROXY:

        the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );

        if ( ! _Thread_Is_null( the_thread ) )
            _Thread_queue_Extract( the_thread );

        _MPCI_Return_packet( the_packet_prefix );
        break;

    case PARTITION_MP_GET_BUFFER_REQUEST:

        the_packet->Prefix.return_code = rtems_partition_get_buffer(
                                             the_packet->Prefix.id,
                                             &the_packet->buffer
                                         );

        _Partition_MP_Send_response_packet(
            PARTITION_MP_GET_BUFFER_RESPONSE,
            the_packet->Prefix.id,
            _Thread_Executing
        );
        break;

    case PARTITION_MP_GET_BUFFER_RESPONSE:

        the_thread = _MPCI_Process_response( the_packet_prefix );

        *(void **)the_thread->Wait.return_argument = the_packet->buffer;

        _MPCI_Return_packet( the_packet_prefix );
        break;

    case PARTITION_MP_RETURN_BUFFER_REQUEST:

        the_packet->Prefix.return_code = rtems_partition_return_buffer(
                                             the_packet->Prefix.id,
                                             the_packet->buffer
                                         );

        _Partition_MP_Send_response_packet(
            PARTITION_MP_RETURN_BUFFER_RESPONSE,
            the_packet->Prefix.id,
            _Thread_Executing
        );
        break;

    case PARTITION_MP_RETURN_BUFFER_RESPONSE:

        the_thread = _MPCI_Process_response( the_packet_prefix );

        _MPCI_Return_packet( the_packet_prefix );
        break;

    }
}
Exemplo n.º 10
0
int _POSIX_Message_queue_Create_support(
  const char                    *name,
  int                            pshared,
  unsigned int                   oflag,
  struct mq_attr                *attr_ptr,
  POSIX_Message_queue_Control  **message_queue
)
{
  POSIX_Message_queue_Control   *the_mq;
  CORE_message_queue_Attributes *the_mq_attr;
  struct mq_attr                 attr;

  _Thread_Disable_dispatch();
 
  /*
   *  There is no real basis for the default values.  They will work
   *  but were not compared against any existing implementation for
   *  compatibility.  See README.mqueue for an example program we
   *  think will print out the defaults.  Report anything you find with it.
   */

  if ( attr_ptr == NULL ) {
    attr.mq_maxmsg  = 10;
    attr.mq_msgsize = 16;
  } else {
    if ( attr_ptr->mq_maxmsg < 0 ){
      _Thread_Enable_dispatch();
      set_errno_and_return_minus_one( EINVAL );
    }

    if ( attr_ptr->mq_msgsize < 0 ){
      _Thread_Enable_dispatch();
      set_errno_and_return_minus_one( EINVAL );
    }

    attr = *attr_ptr;
  }

#if 0 && defined(RTEMS_MULTIPROCESSING)
  if ( pshared == PTHREAD_PROCESS_SHARED &&
       !( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
                            the_mq->Object.id, FALSE ) ) ) {
    _POSIX_Message_queue_Free( the_mq );
    _Thread_Enable_dispatch();
    set_errno_and_return_minus_one( ENFILE );
  }
#endif
 
  the_mq = _POSIX_Message_queue_Allocate();
  if ( !the_mq ) {
    _Thread_Enable_dispatch();
    set_errno_and_return_minus_one( ENFILE );
  }
 
  the_mq->process_shared  = pshared;
  the_mq->oflag = oflag;
  the_mq->named = TRUE;
  the_mq->open_count = 1;
  the_mq->linked = TRUE;

 
  /* XXX
   *
   *  Note that thread blocking discipline should be based on the
   *  current scheduling policy.
   */

  the_mq_attr = &the_mq->Message_queue.Attributes;
  the_mq_attr->discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;

  if ( ! _CORE_message_queue_Initialize(
           &the_mq->Message_queue,
           OBJECTS_POSIX_MESSAGE_QUEUES,
           the_mq_attr,
           attr.mq_maxmsg,
           attr.mq_msgsize,
#if 0 && defined(RTEMS_MULTIPROCESSING)
           _POSIX_Message_queue_MP_Send_extract_proxy
#else
           NULL
#endif
      ) ) {

#if 0 && defined(RTEMS_MULTIPROCESSING)
    if ( pshared == PTHREAD_PROCESS_SHARED )
      _Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
#endif
 
    _POSIX_Message_queue_Free( the_mq );
    _Thread_Enable_dispatch();
    set_errno_and_return_minus_one( ENOSPC );
  }

  _Objects_Open(
    &_POSIX_Message_queue_Information,
    &the_mq->Object,
    (char *) name
  );
 
  *message_queue = the_mq;
 
#if 0 && defined(RTEMS_MULTIPROCESSING)
  if ( pshared == PTHREAD_PROCESS_SHARED )
    _POSIX_Message_queue_MP_Send_process_packet(
      POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
      the_mq->Object.id,
      (char *) name,
      0                          /* Not used */
    );
#endif
 
  _Thread_Enable_dispatch();
  return 0;
}
Exemplo n.º 11
0
epos_status_code epos_message_queue_create(
  epos_name       name,
  uint32_t         count,
  size_t           max_message_size,
  epos_attribute  attribute_set,
  epos_id        *id
)
{
  register Message_queue_Control *the_message_queue;
  CORE_message_queue_Attributes   the_msgq_attributes;
#if defined(RTEMS_MULTIPROCESSING)
  bool                            is_global;
#endif

  if ( !epos_is_name_valid( name ) )
    return RTEMS_INVALID_NAME;

  if ( !id )
    return RTEMS_INVALID_ADDRESS;

#if defined(RTEMS_MULTIPROCESSING)
  if ( (is_global = _Attributes_Is_global( attribute_set ) ) &&
       !_System_state_Is_multiprocessing )
    return RTEMS_MP_NOT_CONFIGURED;
#endif

  if ( count == 0 )
      return RTEMS_INVALID_NUMBER;

  if ( max_message_size == 0 )
      return RTEMS_INVALID_SIZE;

#if defined(RTEMS_MULTIPROCESSING)
#if 1
  /*
   * I am not 100% sure this should be an error.
   * It seems reasonable to create a que with a large max size,
   * and then just send smaller msgs from remote (or all) nodes.
   */

  if ( is_global && (_MPCI_table->maximum_packet_size < max_message_size) )
    return RTEMS_INVALID_SIZE;
#endif
#endif


  _Thread_Disable_dispatch();              /* protects object pointer */

  the_message_queue = _Message_queue_Allocate();

  if ( !the_message_queue ) {
    _Thread_Enable_dispatch();
    return RTEMS_TOO_MANY;
  }

#if defined(RTEMS_MULTIPROCESSING)
  if ( is_global &&
    !( _Objects_MP_Allocate_and_open( &_Message_queue_Information,
                              name, the_message_queue->Object.id, false ) ) ) {
    _Message_queue_Free( the_message_queue );
    _Thread_Enable_dispatch();
    return RTEMS_TOO_MANY;
  }
#endif

  the_message_queue->attribute_set = attribute_set;

  if (_Attributes_Is_priority( attribute_set ) )
    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
  else
    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;

  if ( ! _CORE_message_queue_Initialize(
           &the_message_queue->message_queue,
           &the_msgq_attributes,
           count,
           max_message_size
         ) ) {
#if defined(RTEMS_MULTIPROCESSING)
    if ( is_global )
        _Objects_MP_Close(
          &_Message_queue_Information, the_message_queue->Object.id);
#endif

    _Message_queue_Free( the_message_queue );
    _Thread_Enable_dispatch();
    return RTEMS_UNSATISFIED;
  }

  _Objects_Open(
    &_Message_queue_Information,
    &the_message_queue->Object,
    (Objects_Name) name
  );

  *id = the_message_queue->Object.id;

#if defined(RTEMS_MULTIPROCESSING)
  if ( is_global )
    _Message_queue_MP_Send_process_packet(
      MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
      the_message_queue->Object.id,
      name,
      0
    );
#endif

  _Thread_Enable_dispatch();
  return RTEMS_SUCCESSFUL;
}
Exemplo n.º 12
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;
}