Ejemplo n.º 1
0
/*!
 * \brief Allocates a message from a system message pool.
 * 
 * The size of the message is determined by the message size that a task 
 * specified when it called _msgpool_create_system().
 * \n The message is a resource of the task until the task either frees it 
 * (_msg_free()) or puts it on a message queue (_msgq_send family of functions.)
 * 
 * \param[in] message_size Maximum size (in single-addressable units) of the 
 * message.
 * 
 * \return Pointer to a message of at least message_size single-addressable 
 * units (success).
 * \return NULL (Failure: message component is not created.)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li Task error codes from _mem_alloc_system() (If MQX needs to grow the pool.)
 * 
 * \see _mem_alloc
 * \see _mem_alloc_from
 * \see _mem_alloc_system
 * \see _mem_alloc_system_from
 * \see _mem_alloc_system_zero
 * \see _mem_alloc_system_zero_from
 * \see _mem_alloc_zero
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align
 * \see _mem_alloc_align_from
 * \see _mem_alloc_at        
 * \see _msg_alloc
 * \see _msg_free
 * \see _msgpool_create_system
 * \see _msgq_send
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT 
 */ 
pointer _msg_alloc_system
(
    _msg_size message_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;
    uint_16                              grow_number;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_msg_alloc_system, message_size );

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX2( KLOG_msg_alloc_system, NULL );
        return(NULL);
    }/* Endif */
#endif

    message_ptr = NULL;
    _INT_DISABLE();
    msgpool_ptr = msg_component_ptr->SMALLEST_MSGPOOL_PTR;
    while (msgpool_ptr != NULL)
    {
        if (msgpool_ptr->MESSAGE_SIZE >= message_size)
        {
            imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
            if ( (imsg_ptr == NULL) &&
                            (msgpool_ptr->GROW_NUMBER) &&
                            (msgpool_ptr->MAX < msgpool_ptr->GROW_LIMIT) )
            {
                /* Attempt to add elements to the pool */
                grow_number = msgpool_ptr->GROW_NUMBER;
                if ( ((uint_16)(msgpool_ptr->MAX + grow_number) > msgpool_ptr->GROW_LIMIT))
                {
                    grow_number = msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX;
                } /* Endif */
                _msgpool_add_internal(msgpool_ptr, grow_number);
                imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
            } /* Endif */
            if ( imsg_ptr != NULL )
            {
                msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr->NEXT;
                --msgpool_ptr->SIZE;
                _INT_ENABLE();
                imsg_ptr->FREE = FALSE;
                imsg_ptr->QUEUED = FALSE;
                if (kernel_data->IN_ISR)
                {
                    imsg_ptr->TD_PTR = NULL;
                }
                else
                {
                    imsg_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
                } /* Endif */
                message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;
                message_ptr->TARGET_QID = MSGQ_NULL_QUEUE_ID;
                message_ptr->SOURCE_QID = MSGQ_NULL_QUEUE_ID;
                message_ptr->SIZE = message_size;
                message_ptr->CONTROL = MSG_HDR_ENDIAN | MSG_DATA_ENDIAN;

                _KLOGX2(KLOG_msg_alloc_system, message_ptr);
                return (pointer)message_ptr;
            } /* Endif */
        } /* Endif */
        msgpool_ptr = msgpool_ptr->NEXT_MSGPOOL_PTR;
    } /* Endwhile */

    _int_enable();
    _KLOGX2(KLOG_msg_alloc_system, message_ptr);
    return (pointer)message_ptr;

} /* Endbody */
Ejemplo n.º 2
0
/*!
 * \brief Allocates a message from the private message pool.
 * 
 * The size of the message is determined by the message size that a task 
 * specified when it called _msgpool_create(). The message is a resource of the 
 * task until the task either frees it (_msg_free()) or puts it on a message 
 * queue (_msgq_send() family of functions.)
 * 
 * \param[in] pool A pool ID from _msgpool_create().
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)
 *  
 * \warning On failure, calls _task_set_error() to set one the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGPOOL_INVALID_POOL_ID (Pool_id is not valid.)
 * \li MSGPOOL_OUT_OF_MESSAGES (All the messages in the pool are allocated.)
 * \li Task error codes from _mem_alloc_system() (If MQX needs to grow the pool.)
 * 
 * \see _msg_alloc_system
 * \see _msg_free
 * \see _msgpool_create
 * \see _msgpool_destroy
 * \see _task_set_error
 * \see _mem_alloc
 * \see _mem_alloc_from
 * \see _mem_alloc_system
 * \see _mem_alloc_system_from
 * \see _mem_alloc_system_zero
 * \see _mem_alloc_system_zero_from
 * \see _mem_alloc_zero
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align
 * \see _mem_alloc_align_from
 * \see _mem_alloc_at
 * \see MESSAGE_HEADER_STRUCT     
 */ 
pointer _msg_alloc
(
    _pool_id pool
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
#if MQX_CHECK_ERRORS
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
#endif
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;
    uint_16                              grow_number;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msg_alloc, pool);

#if MQX_CHECK_ERRORS
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msg_alloc, NULL, MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
#endif

    message_ptr = NULL;
    msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool;

#if MQX_CHECK_VALIDITY || MQX_CHECK_ERRORS
    if (
#if MQX_CHECK_VALIDITY
                    (msgpool_ptr->VALID != MSG_VALID)
#if MQX_CHECK_ERRORS
                    ||
#endif
#endif
#if MQX_CHECK_ERRORS
                    (msgpool_ptr->MSGPOOL_TYPE != MSG_POOL)
#endif
    )
    {
        _task_set_error(MSGPOOL_INVALID_POOL_ID);
        _KLOGX3(KLOG_msg_alloc, message_ptr, MSGPOOL_INVALID_POOL_ID);
        return (message_ptr);
    } /* Endif */
#endif

    if ( (msgpool_ptr->SIZE == 0) && (msgpool_ptr->GROW_NUMBER) &&
                    ( (msgpool_ptr->MAX < msgpool_ptr->GROW_LIMIT) ||
                                    (msgpool_ptr->GROW_LIMIT == 0) ) )
    {
        /* Attempt to add elements to the pool */
        grow_number = msgpool_ptr->GROW_NUMBER;
        if (grow_number > (uint_16)(msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX))
        {
            grow_number = msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX;
        } /* Endif */
        _msgpool_add_internal(msgpool_ptr, grow_number);
    } /* Endif */

    _INT_DISABLE();
    imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
    if (imsg_ptr == NULL)
    {
        _int_enable();
        _task_set_error(MSGPOOL_OUT_OF_MESSAGES);
        _KLOGX3(KLOG_msg_alloc, message_ptr, MSGPOOL_OUT_OF_MESSAGES);
        return((pointer)message_ptr);
    } /* Endif */

    msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr->NEXT;
    --msgpool_ptr->SIZE;
    _INT_ENABLE();
    imsg_ptr->FREE = FALSE;
    imsg_ptr->QUEUED = FALSE;
    if (kernel_data->IN_ISR)
    {
        imsg_ptr->TD_PTR = NULL;
    }
    else
    {
        imsg_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
    } /* Endif */
    message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;
    message_ptr->TARGET_QID = MSGQ_NULL_QUEUE_ID;
    message_ptr->SOURCE_QID = MSGQ_NULL_QUEUE_ID;
    message_ptr->SIZE = msgpool_ptr->MESSAGE_SIZE;
    message_ptr->CONTROL = MSG_HDR_ENDIAN | MSG_DATA_ENDIAN;
    _KLOGX3(KLOG_msg_alloc, message_ptr, MQX_OK);
    return (pointer)message_ptr;

} /* Endbody */
Ejemplo n.º 3
0
_pool_id   _msgpool_create_internal
   (
      /*  [IN]  size of the messages being created  */
      uint_16  message_size,

      /*  [IN]  no. of messages in this pool  */
      uint_16  num_messages,

      /*  [IN]  no. of messages to grow pool by if empty */
      uint_16  grow_number,

      /*  [IN]  maximum number of messages allowed in pool */
      uint_16  grow_limit,

      /*  [IN]  whether this is a system pool or a regular pool */
      _mqx_uint  pool_type
   )
{ /* Body */
            KERNEL_DATA_STRUCT_PTR kernel_data;
            MSG_COMPONENT_STRUCT_PTR  msg_component_ptr;
   register MSGPOOL_STRUCT_PTR     msgpool_ptr;
   register MSGPOOL_STRUCT_PTR     temp_msgpool_ptr;
   register MSGPOOL_STRUCT_PTR     prev_msgpool_ptr;
   register _mqx_uint               i;
            _mqx_uint               result;

   _GET_KERNEL_DATA(kernel_data);
   msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);

#if MQX_CHECK_ERRORS
   if (message_size < sizeof(MESSAGE_HEADER_STRUCT)) {
      _task_set_error(MSGPOOL_MESSAGE_SIZE_TOO_SMALL);
      return ((_pool_id) 0);
   } /* Endif */
#endif

   /*
   ** Try to find an available slot in the array of msgpools for a new pool
   ** if MAX_MSGPOOLS_EVER has not yet reached MAX_MSGPOOLS then
   ** simply use MAX_MSGPOOLS_EVER as an index value and then increment it
   ** but if MAX_MSGPOOLS_EVER has reached MAX_MSGPOOLS then
   ** go back and search through the previously assigned headers to see
   ** if one has been deallocated and is available for use
   */
   if (msg_component_ptr == NULL) {
      result = _msg_create_component();
      msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (msg_component_ptr == NULL) {
         _task_set_error(result);
         return ((_pool_id)0);
      } /* Endif */
#endif
   } /* Endif */

   _int_disable();
   if (msg_component_ptr->MAX_MSGPOOLS_EVER >= msg_component_ptr->MAX_MSGPOOLS) {
      msgpool_ptr = &msg_component_ptr->MSGPOOLS_PTR[0];
      for ( i=0; i < msg_component_ptr->MAX_MSGPOOLS; i++ ) {
         if (msgpool_ptr->VALID != MSG_VALID) {
            break;
         } /* Endif */
         msgpool_ptr++;
      } /* Endfor */
      if (i == msg_component_ptr->MAX_MSGPOOLS) {
         _int_enable();
         _task_set_error(MSGPOOL_OUT_OF_POOLS);
         return ((_pool_id)0);
      } /* Endif */
   } else {
      msgpool_ptr = &msg_component_ptr->MSGPOOLS_PTR[
         msg_component_ptr->MAX_MSGPOOLS_EVER++];
   } /* Endif */

   msgpool_ptr->VALID        = MSG_VALID;
   msgpool_ptr->MESSAGE_SIZE = message_size;
   msgpool_ptr->GROW_NUMBER  = 0;
   _int_enable();

   msgpool_ptr->MSGPOOL_BLOCK_PTR = NULL;
   msgpool_ptr->MSG_FREE_LIST_PTR = NULL;
   msgpool_ptr->NEXT_MSGPOOL_PTR  = NULL;
   msgpool_ptr->SIZE              = 0;
   msgpool_ptr->MAX               = 0;
   if ( grow_number == 0 ) {
      msgpool_ptr->GROW_LIMIT = num_messages;
   } else if (grow_limit == 0) {
      msgpool_ptr->GROW_LIMIT = 0xFFFF;
   } else {
      msgpool_ptr->GROW_LIMIT = grow_limit;
   } /* Endif */
   msgpool_ptr->MSGPOOL_TYPE  = pool_type;

   if (num_messages) {
      _msgpool_add_internal(msgpool_ptr, num_messages);

      /* no messages could be created, so abort pool creation */
      if (msgpool_ptr->SIZE == 0) {
         msgpool_ptr->VALID = 0;
         _task_set_error(MQX_OUT_OF_MEMORY);
         return ((_pool_id)0);
      } /* Endif */
   } /* Endif */

   msgpool_ptr->GROW_NUMBER       = grow_number;

   if ( pool_type == SYSTEM_MSG_POOL ) {
      /* We must insert the pool into the link list of system message pools,
      ** by order of size, smallest first.
      */

      _int_disable();
      prev_msgpool_ptr = msg_component_ptr->SMALLEST_MSGPOOL_PTR;
      if (prev_msgpool_ptr == NULL) {
         /* first entry in list */
         msg_component_ptr->SMALLEST_MSGPOOL_PTR = msgpool_ptr;
         msg_component_ptr->LARGEST_MSGPOOL_PTR  = msgpool_ptr;
      } else if (prev_msgpool_ptr->MESSAGE_SIZE >= msgpool_ptr->MESSAGE_SIZE){
         /* The new pool is smaller than that at head of list */
         msgpool_ptr->NEXT_MSGPOOL_PTR        = prev_msgpool_ptr;
         msg_component_ptr->SMALLEST_MSGPOOL_PTR = msgpool_ptr;
      } else {
         temp_msgpool_ptr = prev_msgpool_ptr->NEXT_MSGPOOL_PTR;
         while (temp_msgpool_ptr != NULL) {
            /* check the relative message sizes */
            if (temp_msgpool_ptr->MESSAGE_SIZE < msgpool_ptr->MESSAGE_SIZE){
               /* continue to walk down linked list */
               prev_msgpool_ptr = temp_msgpool_ptr;
               temp_msgpool_ptr = prev_msgpool_ptr->NEXT_MSGPOOL_PTR;
            } else {
               /* this entry belongs between prev_ptr and temp_msgpool_ptr */
               prev_msgpool_ptr->NEXT_MSGPOOL_PTR = msgpool_ptr;
               msgpool_ptr->NEXT_MSGPOOL_PTR      = temp_msgpool_ptr;
               break;
            } /* Endif */
         } /* Endwhile */
         if (temp_msgpool_ptr == NULL) {
            /* searched the list and this entry belongs at the bottom */
            prev_msgpool_ptr->NEXT_MSGPOOL_PTR  = msgpool_ptr;
            msg_component_ptr->LARGEST_MSGPOOL_PTR = msgpool_ptr;
         }/* Endif */
      } /* Endif */
      _int_enable();

   } /* Endif */

   return ((_pool_id)msgpool_ptr);

} /* Endbody */