_mqx_uint _msgq_get_count ( /* [IN] the id of the queue which is being checked for waiting msgs */ _queue_id queue_id ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register MSGQ_STRUCT_PTR msgq_ptr; INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; register _mqx_uint pending; register uint_16 queue; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_msgq_get_count, queue_id); 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); _KLOGX3(KLOG_msgq_get_count, MQX_COMPONENT_DOES_NOT_EXIST, 0); return(0); } /* Endif */ #endif if (queue_id == MSGQ_ANY_QUEUE) { _KLOGX3(KLOG_msgq_get_count, MQX_OK, kernel_data->ACTIVE_PTR->MESSAGES_AVAILABLE); return(kernel_data->ACTIVE_PTR->MESSAGES_AVAILABLE ); } /* Endif */ pending = 0; queue = QUEUE_FROM_QID(queue_id); if ( (PROC_NUMBER_FROM_QID(queue_id) == kernel_data->INIT.PROCESSOR_NUMBER) && VALID_QUEUE(queue) ) { msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; if ( msgq_ptr->QUEUE == (queue) ) { pending = msgq_ptr->NO_OF_ENTRIES; /* Check for short-cutted message ie not on q but could have been */ if (msgq_ptr->TD_PTR != NULL) { imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR)msgq_ptr->TD_PTR->MESSAGE; if ((imsg_ptr != NULL) && (QUEUE_FROM_QID(imsg_ptr->MESSAGE.TARGET_QID) == queue)) { ++pending; } /* Endif */ } /* Endif */ } else { _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); } /* Endif */ } else { _task_set_error(MSGQ_INVALID_QUEUE_ID); } /* Endif */ _KLOGX2(KLOG_msgq_get_count, pending); return(pending); } /* Endbody */
_mqx_uint _msgq_get_notification_function ( /* [IN] the queue upon which to install the function */ _queue_id qid, /* [OUT] the function to be called when an entry is put on the queue */ void (_CODE_PTR_ _PTR_ notification_function)(pointer), /* [OUT] information to pass to the notification function */ pointer _PTR_ notification_data ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; MSGQ_STRUCT_PTR msgq_ptr; _mqx_uint result = MQX_OK; _queue_number queue; #if MQX_CHECK_ERRORS _processor_number pnum; #endif _GET_KERNEL_DATA(kernel_data); msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data); #if MQX_CHECK_ERRORS if (msg_component_ptr == NULL){ return(MQX_COMPONENT_DOES_NOT_EXIST); } /* Endif */ #endif queue = QUEUE_FROM_QID(qid); #if MQX_CHECK_ERRORS pnum = PROC_NUMBER_FROM_QID(qid); if (( pnum != kernel_data->INIT.PROCESSOR_NUMBER) || ( ! VALID_QUEUE(queue))) { result = MSGQ_INVALID_QUEUE_ID; } /* Endif */ #endif if (result == MQX_OK) { msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; if ( msgq_ptr->QUEUE != (queue) ) { result = MSGQ_QUEUE_IS_NOT_OPEN; } else { *notification_function = msgq_ptr->NOTIFICATION_FUNCTION; *notification_data = msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER; } /* Endif */ } /* Endif */ return result; } /* Endbody */
_task_id _msgq_get_owner ( /* [IN] queue from which need to match the task id */ _queue_id queue_id ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register MSGQ_STRUCT_PTR msgq_ptr; _queue_number queue; _task_id task_id; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_msgq_get_owner, queue_id); 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); _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MQX_COMPONENT_DOES_NOT_EXIST); return(MQX_NULL_TASK_ID); } /* Endif */ #endif queue = QUEUE_FROM_QID(queue_id); #if MQX_CHECK_ERRORS if ((PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER) || (! VALID_QUEUE(queue)) ) { _task_set_error(MQX_INVALID_PROCESSOR_NUMBER); _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER); return (MQX_NULL_TASK_ID); } /* Endif */ #endif msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; if (msgq_ptr->QUEUE != (queue)) { _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MSGQ_QUEUE_IS_NOT_OPEN); return (MQX_NULL_TASK_ID); } /* Endif */ task_id = msgq_ptr->TD_PTR->TASK_ID; _KLOGX3(KLOG_msgq_get_owner, task_id, MQX_OK); return (task_id); } /* Endbody */
/*! * \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 */
/*! * \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 */
/*! * \brief This function is called when a task is being destroyed. * * Closes all open message queues and then free all messages owned by this task. * * \param[in] td_ptr The task descriptor of the task that is being destroyed. */ void _msg_cleanup ( TD_STRUCT_PTR td_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; MSGQ_STRUCT_PTR msgq_ptr; MSGQ_STRUCT_PTR qprev_ptr; MSGPOOL_STRUCT_PTR msgpool_ptr; MSGPOOL_BLOCK_STRUCT_PTR msgpool_block_ptr; INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; INTERNAL_MESSAGE_STRUCT_PTR tmp_imsg_ptr; _mqx_uint i,j,raw_message_size; _GET_KERNEL_DATA(kernel_data); msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data); #if MQX_CHECK_ERRORS if (msg_component_ptr == NULL) { return; } /* Endif */ #endif /* Delete the message queues owned by the task, and free the messages * on the queues */ msgq_ptr = (MSGQ_STRUCT_PTR)td_ptr->MSG_QUEUE_HEAD; while (msgq_ptr != NULL) { if (msgq_ptr->TD_PTR != NULL) { msgq_ptr->TD_PTR->MESSAGES_AVAILABLE -= msgq_ptr->NO_OF_ENTRIES; } /* Endif */ imsg_ptr = msgq_ptr->FIRST_MSG_PTR; while ( imsg_ptr != NULL ) { tmp_imsg_ptr = imsg_ptr->NEXT; imsg_ptr->QUEUED = FALSE; _msg_free((pointer)&imsg_ptr->MESSAGE); imsg_ptr = tmp_imsg_ptr; } /* Endwhile */ qprev_ptr = msgq_ptr; msgq_ptr = msgq_ptr->NEXT_MSGQ_PTR; qprev_ptr->FIRST_MSG_PTR = NULL; qprev_ptr->NEXT_MSGQ_PTR = NULL; qprev_ptr->QUEUE = 0; } /* Endwhile */ td_ptr->MSG_QUEUE_HEAD = NULL; td_ptr->MSG_QUEUE_TAIL = NULL; /* Search through all of the message pools, looking for any messages * owned by this task. If found free them. */ msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR; i = msg_component_ptr->MAX_MSGPOOLS + 1; while (--i) { if (msgpool_ptr->VALID == MSG_VALID) { /* Search through all of the message pool blocks for this pool */ msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR; while (msgpool_block_ptr != NULL) { raw_message_size = msgpool_block_ptr->RAW_MESSAGE_SIZE; imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR) ((uchar _PTR_)msgpool_block_ptr + sizeof(MSGPOOL_BLOCK_STRUCT)); /* if the message is not free, not queued and the * owner is the task being destroyed, then Free the message */ j = msgpool_block_ptr->NUM_MESSAGES + 1; while (--j) { if ( (imsg_ptr->TD_PTR == td_ptr) && (imsg_ptr->FREE == FALSE) && (imsg_ptr->QUEUED == FALSE) ) { _msg_free(&imsg_ptr->MESSAGE); } /* Endif */ imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR) ((uchar _PTR_)imsg_ptr + raw_message_size); } /* Endwhile */ msgpool_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR; } /* Endwhile */ } /* Endif */ msgpool_ptr++; } /* Endwhile */ } /* Endbody */
/*! * \brief Gets the number of free messages in the message pool. * * The function fails if either: * \li Message component is not created. * \li Pool_id is for a private message pool, but does not represent a valid one. * * \param[in] pool One of the following: * \li Private message pool for which to get the number of free messages. * \li MSGPOOL_NULL_POOL_ID (for system message pools). * * \return The number of free messages in the private message pool (success). * \return The number of free messages in all system message pools (success). * \return 0 (Success: No free messages.) * \return 0 (Failure: see Description.) * * \warning If pool_id does not represent a valid private message pool, calls * _task_set_error() to set the task error code to MSGPOOL_INVALID_POOL_ID * * \see _msgpool_create * \see _msgpool_destroy * \see _msg_free * \see _msg_alloc_system * \see _task_set_error * \see _msg_create_component */ _mqx_uint _msg_available ( _pool_id pool ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register MSGPOOL_STRUCT_PTR msgpool_ptr; _mqx_uint i; _mqx_uint count; _GET_KERNEL_DATA(kernel_data); msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data); #if MQX_CHECK_ERRORS if (msg_component_ptr == NULL) { return(0); } /* Endif */ #endif msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR; #if MQX_CHECK_ERRORS if (msgpool_ptr == NULL) { return(0); }/* Endif */ #endif if (pool == MSGPOOL_NULL_POOL_ID) { count = 0; _INT_DISABLE(); i = msg_component_ptr->MAX_MSGPOOLS_EVER + 1; while ( --i ) { if ( #if MQX_CHECK_VALIDITY (msgpool_ptr->VALID == MSG_VALID) && #endif (msgpool_ptr->MSGPOOL_TYPE == SYSTEM_MSG_POOL)) { count += msgpool_ptr->SIZE; } /* Endif */ ++msgpool_ptr; } /* Endwhile */ _INT_ENABLE(); return count; } else { msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool; if ( #if MQX_CHECK_VALIDITY (msgpool_ptr->VALID != MSG_VALID) || #endif (msgpool_ptr->MSGPOOL_TYPE != MSG_POOL) ) { _task_set_error(MSGPOOL_INVALID_POOL_ID); return (0); } /* Endif */ return (_mqx_uint)msgpool_ptr->SIZE; } /* Endif */ } /* Endbody */
_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 */
MESSAGE_HEADER_STRUCT_PTR _msgq_receive_internal ( /* [IN] id of the queue from which a message is to be received */ _queue_id queue_id, /* [IN] indication of the number of ticks which can expire before ** this request times out */ MQX_TICK_STRUCT_PTR timeout_tick_ptr, /* [IN] relative or absolute time specified in tick_ptr */ _mqx_uint mode, /* [OUT] where the error code is to be stored */ _mqx_uint_ptr error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register TD_STRUCT_PTR td_ptr; MESSAGE_HEADER_STRUCT_PTR message_ptr; register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; register MSGQ_STRUCT_PTR msgq_ptr; _queue_number queue; *error_ptr = MQX_OK; _GET_KERNEL_DATA(kernel_data); #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _task_set_error(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); *error_ptr = MQX_CANNOT_CALL_FUNCTION_FROM_ISR; return(NULL); }/* Endif */ #endif 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); *error_ptr = MQX_COMPONENT_DOES_NOT_EXIST; return(NULL); } /* Endif */ #endif message_ptr = NULL; td_ptr = kernel_data->ACTIVE_PTR; if (queue_id == MSGQ_ANY_QUEUE){ /* if queue_id is 0 than a receive from any queue is performed */ /* Does the task own a queue */ if (td_ptr->MSG_QUEUE_HEAD == NULL){ /* Does NOT */ _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); *error_ptr = MSGQ_QUEUE_IS_NOT_OPEN; return NULL; } /* Endif */ _INT_DISABLE(); if (td_ptr->MESSAGES_AVAILABLE == 0){ td_ptr->STATE = RCV_ANY_BLOCKED; td_ptr->INFO = queue_id; td_ptr->MESSAGE = NULL; if (mode == MSG_TIMEOUT_NONE) { _task_block(); } else if (mode == MSG_TIMEOUT_RELATIVE) { _time_delay_for(timeout_tick_ptr); } else { _time_delay_until(timeout_tick_ptr); } /* Endif */ /* ** SHORT CUT... ** The message send routine does not queue up a message in this case. ** the message is deposited directly into the task descriptor */ message_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE; if (message_ptr == NULL){ /* A timeout has occurred */ #if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE); #endif } /* Endif */ td_ptr->MESSAGE = NULL; } else { /* Check all queues for an available entry .. There must be at least ** one entry available */ msgq_ptr = (MSGQ_STRUCT_PTR)td_ptr->MSG_QUEUE_HEAD; while (msgq_ptr != NULL){ if (msgq_ptr->NO_OF_ENTRIES){ /* dequeue the top entry */ DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr); break; } /* Endif */ msgq_ptr = msgq_ptr->NEXT_MSGQ_PTR; } /* Endwhile */ } /* Endif */ } else { /* RECEIVE from a specific qid */ queue = QUEUE_FROM_QID(queue_id); #if MQX_CHECK_ERRORS if ( (PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER) || (! VALID_QUEUE(queue)) ) { _task_set_error(MSGQ_INVALID_QUEUE_ID); *error_ptr = MSGQ_INVALID_QUEUE_ID; return (pointer)message_ptr; } /* Endif */ #endif msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; #if MQX_CHECK_ERRORS if ( msgq_ptr->QUEUE != queue ) { _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); *error_ptr = MSGQ_QUEUE_IS_NOT_OPEN; return message_ptr; } /* Endif */ if ( (msgq_ptr->TD_PTR != NULL) && (msgq_ptr->TD_PTR != td_ptr) ) { _task_set_error(MSGQ_NOT_QUEUE_OWNER); *error_ptr = MSGQ_NOT_QUEUE_OWNER; return message_ptr; } /* Endif */ #endif /* ** check the specified queue for an entry ** if not entry, then block until an entry is received or ** timeout occurs */ _INT_DISABLE(); if (msgq_ptr->NO_OF_ENTRIES == 0) { if (msgq_ptr->TD_PTR == NULL) { /* A system message queue, indicate none available */ message_ptr = NULL; } else { td_ptr->STATE = RCV_SPECIFIC_BLOCKED; td_ptr->INFO = queue; td_ptr->MESSAGE = NULL; if (mode == MSG_TIMEOUT_NONE) { _task_block(); } else if (mode == MSG_TIMEOUT_RELATIVE) { _time_delay_for(timeout_tick_ptr); } else { _time_delay_until(timeout_tick_ptr); } /* Endif */ message_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE; if ( message_ptr == NULL ) { #if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE); #endif } else if ((message_ptr->TARGET_QID != queue_id) && (msgq_ptr->NO_OF_ENTRIES > 0)) { /* The original msg was swapped out in msgq_sendi() for a higher priority msg with a different target_qid. Enqueue this msg, and then dequeue the msg we need. */ register MSGQ_STRUCT_PTR tmp_msgq_ptr; register _queue_number tmp_queue; /* Get the msg's queue */ tmp_queue = QUEUE_FROM_QID(message_ptr->TARGET_QID); tmp_msgq_ptr = &msg_component_ptr->MSGQS_PTR[tmp_queue]; if ((tmp_msgq_ptr->MAX_ENTRIES == 0) || (tmp_msgq_ptr->NO_OF_ENTRIES < tmp_msgq_ptr->MAX_ENTRIES)) { /* the msg's queue has room */ imsg_ptr = GET_INTERNAL_MESSAGE_PTR(message_ptr); #if MQX_CHECK_ERRORS if (imsg_ptr->VALID != MSG_VALID){ /* An invalid message was input by the application. */ _task_set_error(MSGQ_INVALID_MESSAGE); message_ptr = NULL; } else #endif { /* enqueue the msg */ _msgq_insert_message_internal(tmp_msgq_ptr, imsg_ptr, TRUE); if (tmp_msgq_ptr->TD_PTR) { ++(tmp_msgq_ptr->TD_PTR->MESSAGES_AVAILABLE); } /* Endif */ /* now dequeue our queue's top entry */ DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr); } } else { /* Queue full, error - this should not happen since msgq_sendi() checks for room on the queue for all msgs, including short-cut msgs. */ _task_set_error(MSGQ_QUEUE_FULL); message_ptr = NULL; } } /* Endif */ td_ptr->MESSAGE = NULL; } /* Endif */ } else { /* dequeue the top entry */ DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr); } /* Endif */ } /* Endif */ _INT_ENABLE(); return message_ptr; } /* Endbody */
boolean _msgq_send_internal ( /* [IN] pointer to the message being sent by application */ MESSAGE_HEADER_STRUCT_PTR msg_ptr, /* [IN] is the calling task to be blocked after the call */ boolean blocking, /* [IN] the queue to put the message onto */ _queue_id target_qid ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; register MSGQ_STRUCT_PTR msgq_ptr; register TD_STRUCT_PTR td_ptr; MESSAGE_HEADER_STRUCT_PTR tmp_msg_ptr; register _mqx_uint state; register _queue_number queue; register _processor_number pnum; /* Start CR 2191 */ boolean swapped_msg; /* End CR 2191 */ _GET_KERNEL_DATA(kernel_data); 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); return(FALSE); } /* Endif */ if (msg_ptr == NULL) { _task_set_error(MSGQ_INVALID_MESSAGE); return(FALSE); } /* Endif */ #endif imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr); #if MQX_CHECK_ERRORS if (imsg_ptr->VALID != MSG_VALID){ /* An invalid message was input by the application. */ _task_set_error(MSGQ_INVALID_MESSAGE); return FALSE; } /* Endif */ #endif #if MQX_CHECK_ERRORS if (imsg_ptr->FREE || imsg_ptr->QUEUED){ /* Trying to send a free message, or one on a message queue. */ _task_set_error(MSGQ_INVALID_MESSAGE); return FALSE; } /* Endif */ #endif pnum = PROC_NUMBER_FROM_QID(target_qid); /* If processor number is zero then the message is for this processor */ if (pnum == 0) { /* Fix up the target QID in the message header */ msg_ptr->TARGET_QID = BUILD_QID(kernel_data->INIT.PROCESSOR_NUMBER, msg_ptr->TARGET_QID); } else if (pnum != kernel_data->INIT.PROCESSOR_NUMBER) { #if MQX_IS_MULTI_PROCESSOR IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR ipc_msg_comp_ptr; ipc_msg_comp_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING]; if (ipc_msg_comp_ptr && ipc_msg_comp_ptr->MSG_ROUTER) { return( (*ipc_msg_comp_ptr->MSG_ROUTER)(pnum, msg_ptr, blocking)); } else { #endif _msg_free(msg_ptr); _task_set_error(MSGQ_INVALID_QUEUE_ID); return FALSE; #if MQX_IS_MULTI_PROCESSOR }/* Endif */ #endif } /* Endif */ queue = QUEUE_FROM_QID(target_qid); #if MQX_CHECK_ERRORS if ( ! VALID_QUEUE(queue)) { _msg_free(msg_ptr); _task_set_error(MSGQ_INVALID_QUEUE_ID); return FALSE; } /* Endif */ #endif msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; if (msgq_ptr->QUEUE != queue) { msgq_ptr = NULL; } /* Endif */ #if MQX_CHECK_ERRORS if (msgq_ptr == NULL) { _msg_free(msg_ptr); _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); return FALSE; } /* Endif */ #endif _INT_DISABLE(); if ((msgq_ptr->MAX_ENTRIES == 0) || (msgq_ptr->NO_OF_ENTRIES < msgq_ptr->MAX_ENTRIES)) { /* End CR 2265 */ /* There is room on the queue, so add the msg. We need to check for room here even if the msg ends up being short-cutted to the receiver (via td_ptr->MESSAGE) in case msg_receive needs to enqueue the msg. */ if (msgq_ptr->TYPE == MSG_QUEUE) { /* THIS MESSAGE QUEUE IS ATTACHED TO A TASK */ /* check for pending receive ** if a receive is pending then satisfy the request ** and add the receiving task onto the ready-to-run queue */ td_ptr = msgq_ptr->TD_PTR; state = td_ptr->STATE & STATE_MASK; if ( (state == RCV_ANY_BLOCKED) || ((state == RCV_SPECIFIC_BLOCKED) && (td_ptr->INFO == queue))) { /* The task is blocked, waiting for a message */ td_ptr->MESSAGE = &imsg_ptr->MESSAGE; imsg_ptr->TD_PTR = td_ptr; _TIME_DEQUEUE(td_ptr,kernel_data); _TASK_READY(td_ptr,kernel_data); /* Now run the notification function */ if (msgq_ptr->NOTIFICATION_FUNCTION != NULL) { (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER); } /* Endif */ if (blocking) { if ( ! kernel_data->IN_ISR) { td_ptr = kernel_data->ACTIVE_PTR; td_ptr->STATE = SEND_BLOCKED; _task_block(); } /* Endif */ } else { /* ** if the highest priority ready task is not the ** same priority as the sending task, then a higher ** priority task was made ready and it has to be allowed ** to run. */ _CHECK_RUN_SCHEDULER(); /* Let a higher priority task run */ } /* Endif */ } else { /* The task is ready to run and pre-empted OR blocked and ** on a different queue. */ /* Start CR 2191 */ swapped_msg = FALSE; /* End CR 2191 */ if ((msg_ptr->CONTROL & MSG_PRIORITY_MASK) && (td_ptr->MESSAGE != NULL)) { /* Check the message in the TD */ tmp_msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE; if ( (msg_ptr->CONTROL & MSG_HDR_URGENT) || /* Urgent messages first */ ( (! (tmp_msg_ptr->CONTROL & MSG_HDR_URGENT)) && /* Start CR 621 */ ( (_mqx_uint)(tmp_msg_ptr->CONTROL & MSG_HDR_PRIORITY_MASK) < (_mqx_uint)(msg_ptr->CONTROL & MSG_HDR_PRIORITY_MASK)) /* End CR 621 */ ) ) /* Higher priority messages first */ { /* Put new message into TD */ td_ptr->MESSAGE = msg_ptr; /* Start CR 2193 */ /* Set the new message's ownership to the receiving queue's TD */ imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr); imsg_ptr->TD_PTR = td_ptr; /* Old message which we pulled from TD, need to add to queue, below */ /* End CR 2193 */ msg_ptr = tmp_msg_ptr; imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr); /* Don't know the sender's TD for the swapped out msg, so set it to NULL; */ imsg_ptr->TD_PTR = NULL; /* Start CR 2191 */ /* Indicate that a swap occurred */ swapped_msg = TRUE; /* Set the queue to the swapped msg's queue. */ if (target_qid != msg_ptr->TARGET_QID) { queue = QUEUE_FROM_QID(msg_ptr->TARGET_QID); msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; /* This msg's queue was not full when it was short-cut, so we should not get here. Check anyway. */ if ((msgq_ptr->MAX_ENTRIES != 0) && (msgq_ptr->NO_OF_ENTRIES >= msgq_ptr->MAX_ENTRIES)) { /* Queue full, error */ _INT_ENABLE(); _msg_free(msg_ptr); _task_set_error(MSGQ_QUEUE_FULL); return FALSE; } /* Endif */ } /* Endif */ } /* Endif */ } /* Endif */ /* add the message */ _msgq_insert_message_internal(msgq_ptr, imsg_ptr, swapped_msg); if (msgq_ptr->TD_PTR){ ++(msgq_ptr->TD_PTR->MESSAGES_AVAILABLE); } /* Endif */ /* Now run the notification function */ if (msgq_ptr->NOTIFICATION_FUNCTION != NULL) { (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER); } /* Endif */ if (blocking && ! kernel_data->IN_ISR ) { td_ptr = kernel_data->ACTIVE_PTR; td_ptr->STATE = SEND_BLOCKED; _task_block(); } /* Endif */ } /* Endif */ } else { /* THIS IS A SYSTEM QUEUE NOT ATTACHED TO A TASK */ /* add the message to the queue */ _msgq_insert_message_internal(msgq_ptr, imsg_ptr, FALSE); /* Run the notification function. */ if ( msgq_ptr->NOTIFICATION_FUNCTION != NULL ) { (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER); } /* Endif */ } /* Endif */ } else { /* Queue full, error */ _INT_ENABLE(); _task_set_error(MSGQ_QUEUE_FULL); _msg_free(&imsg_ptr->MESSAGE); return FALSE; } /* Endif */ _INT_ENABLE(); return TRUE; /* Message sent MQX_OK */ } /* Endbody */
/*! * \brief Tests all the message poolsin the system for consistency and validity. * * The function checks the validity of each message in each private and system * message pool. It reports the first error that it finds. * * \param[out] pool_error_ptr (Initialized only if an error is found.) If the * message in a message pool has an error; one of the following: * \li A pointer to a pool ID if the message is from a private message pool. * \li A pointer to a system message pool if the message is from a system * message pool. * \param[out] msg_error_ptr Pointer to the message that has an error * (initialized only if an error is found). * * \return MQX_OK (all messages in all message pools passed) * \return MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.) * \return MSGQ_INVALID_MESSAGE (At least one message in at least one message * pool failed.) * * \warning Disables and enables interrupts. * * \see _msgpool_create * \see _msgpool_create_system */ _mqx_uint _msgpool_test ( void **pool_error_ptr, void **msg_error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; MSGPOOL_STRUCT_PTR msgpool_ptr; MSGPOOL_BLOCK_STRUCT_PTR msgpool_block_ptr; INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; _mqx_uint i,j,raw_message_size; _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_msgpool_test, pool_error_ptr, msg_error_ptr); msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data); #if MQX_CHECK_ERRORS if (msg_component_ptr == NULL) { _KLOGX2(KLOG_msgpool_test, MQX_COMPONENT_DOES_NOT_EXIST); return(MQX_COMPONENT_DOES_NOT_EXIST); } /* Endif */ #endif /* Check all the message pools */ msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR; i = msg_component_ptr->MAX_MSGPOOLS + 1; while (--i) { _int_disable(); if (msgpool_ptr->VALID == MSG_VALID) { /* The pool has been created */ /* Search through all of the message pool blocks for this pool */ msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR; while (msgpool_block_ptr != NULL) { raw_message_size = msgpool_block_ptr->RAW_MESSAGE_SIZE; imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR) msgpool_block_ptr->FIRST_IMSG_PTR; j = msgpool_block_ptr->NUM_MESSAGES + 1; while (--j) { if ((imsg_ptr->VALID != MSG_VALID) || (imsg_ptr->MSGPOOL_PTR != msgpool_ptr)) { _int_enable(); *pool_error_ptr = msgpool_ptr; *msg_error_ptr = imsg_ptr; _KLOGX4(KLOG_msgpool_test, MSGQ_INVALID_MESSAGE, msgpool_ptr, imsg_ptr); return(MSGQ_INVALID_MESSAGE); } /* Endif */ imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR) ((unsigned char *)imsg_ptr + raw_message_size); } /* Endwhile */ msgpool_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR; } /* Endwhile */ } /* Endif */ _int_enable(); msgpool_ptr++; } /* Endwhile */ _KLOGX2(KLOG_msgpool_test, MQX_OK); return(MQX_OK); } /* Endbody */
/*! * \brief Destroys the private message pool. * * Any task can destroy the private message pool as long as all its messages have * been freed. * * \param[in] pool_id Pool to destroy. * * \return MQX_OK * \return MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.) * \return MSGPOOL_INVALID_POOL_ID (Pool_id does not represent a message pool * that was created by _msgpool_create().) * \return MSGPOOL_ALL_MESSAGES_NOT_FREE (All messages in the message pool have * not been freed.) * * \warning Calls _mem_free(), which on error sets the task error code. * * \see _msgpool_create * \see _msg_free * \see _msg_alloc * \see _mem_free */ _mqx_uint _msgpool_destroy ( _pool_id pool_id ) { /* Body */ #if MQX_KERNEL_LOGGING || MQX_CHECK_ERRORS KERNEL_DATA_STRUCT_PTR kernel_data; #endif #if MQX_CHECK_ERRORS MSG_COMPONENT_STRUCT_PTR msg_component_ptr; #endif MSGPOOL_STRUCT_PTR msgpool_ptr; MSGPOOL_BLOCK_STRUCT_PTR msgpool_block_ptr; MSGPOOL_BLOCK_STRUCT_PTR next_block_ptr; #if MQX_KERNEL_LOGGING || MQX_CHECK_ERRORS _GET_KERNEL_DATA(kernel_data); #endif _KLOGE2(KLOG_msgpool_destroy, pool_id); #if MQX_CHECK_ERRORS msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data); if (msg_component_ptr == NULL) { _KLOGX2(KLOG_msgpool_destroy, MQX_COMPONENT_DOES_NOT_EXIST); return MQX_COMPONENT_DOES_NOT_EXIST; } /* Endif */ #endif msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool_id; #if MQX_CHECK_VALIDITY if ( msgpool_ptr->VALID != MSG_VALID ) { _KLOGX2(KLOG_msgpool_destroy, MSGPOOL_INVALID_POOL_ID); return MSGPOOL_INVALID_POOL_ID; } /* Endif */ #endif _int_disable(); if (msgpool_ptr->SIZE == msgpool_ptr->MAX) { /* All messages currently returned, lets delete them */ msgpool_ptr->SIZE = 0; msgpool_ptr->GROW_NUMBER = 0; _int_enable(); msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR; while (msgpool_block_ptr != NULL) { next_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR; _mem_free((void *)msgpool_block_ptr); msgpool_block_ptr = next_block_ptr; } /* Endwhile */ msgpool_ptr->MSGPOOL_BLOCK_PTR = NULL; msgpool_ptr->VALID = 0; msgpool_ptr->MSGPOOL_TYPE = 0; _KLOGX2(KLOG_msgpool_destroy, MQX_OK); return MQX_OK; } else { _int_enable(); _KLOGX2(KLOG_msgpool_destroy, MSGPOOL_ALL_MESSAGES_NOT_FREE); return MSGPOOL_ALL_MESSAGES_NOT_FREE; } /* Endif */ } /* Endbody */
_queue_id _msgq_open_internal ( /* [IN] the queue being opened */ _queue_number queue, /* [IN] the maximum number of entries allowed in this queue */ uint_16 max_queue_size, /* [IN] the type of queue, NORMAL or SYSTEM */ _mqx_uint queue_type, /* [IN] the function to be called when an entry is put on the queue */ void (_CODE_PTR_ notification_function)(pointer), /* [IN] information to pass to the notification function */ pointer notification_data ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register MSGQ_STRUCT_PTR temp_msgq_ptr; register MSGQ_STRUCT_PTR msgq_ptr; register _queue_id qid; register _mqx_uint i; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data); qid = (_queue_id)0; 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(qid); } /* Endif */ #endif } /* Endif */ _int_disable(); if (queue == MSGQ_FREE_QUEUE) { /* Lets find a free queue entry */ msgq_ptr = &msg_component_ptr->MSGQS_PTR[MSGQ_FIRST_USER_QUEUE]; for (i = MSGQ_FIRST_USER_QUEUE; i <= msg_component_ptr->MAX_MSGQS; ++i) { if (msgq_ptr->QUEUE != (_queue_number)i) { queue = (_queue_number)i; break; /* Found one! */ } /* Endif */ ++msgq_ptr; } /* Endfor */ if (queue == MSGQ_FREE_QUEUE) { /* Did not get one */ _int_enable(); _task_set_error(MSGQ_QUEUE_IN_USE); return(qid); }/* Endif */ } else { if (queue >= msg_component_ptr->MAX_MSGQS) { _int_enable(); _task_set_error(MSGQ_INVALID_QUEUE_NUMBER); return(qid); } } #if MQX_CHECK_ERRORS if ( !VALID_QUEUE(queue)) { _int_enable(); _task_set_error(MSGQ_INVALID_QUEUE_ID); return(qid); } /* Endif */ #endif msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; #if MQX_CHECK_ERRORS if (msgq_ptr->QUEUE == queue) { _int_enable(); _task_set_error(MSGQ_QUEUE_IN_USE); return(qid); } /* Endif */ #endif msgq_ptr->QUEUE = queue; msgq_ptr->FIRST_MSG_PTR = NULL; msgq_ptr->LAST_MSG_PTR = NULL; msgq_ptr->NEXT_MSGQ_PTR = NULL; msgq_ptr->NO_OF_ENTRIES = 0; msgq_ptr->TYPE = (uint_16)queue_type; msgq_ptr->MAX_ENTRIES = max_queue_size; msgq_ptr->NOTIFICATION_FUNCTION = notification_function; msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER = notification_data; if ( queue_type == MSG_QUEUE ) { td_ptr = kernel_data->ACTIVE_PTR; msgq_ptr->TD_PTR = td_ptr; if ( td_ptr->MSG_QUEUE_HEAD == NULL ) { td_ptr->MSG_QUEUE_HEAD = (pointer)msgq_ptr; td_ptr->MSG_QUEUE_TAIL = (pointer)msgq_ptr; td_ptr->MESSAGES_AVAILABLE = 0; } else { temp_msgq_ptr = (MSGQ_STRUCT_PTR)(td_ptr->MSG_QUEUE_TAIL); temp_msgq_ptr->NEXT_MSGQ_PTR = msgq_ptr; td_ptr->MSG_QUEUE_TAIL = (pointer)msgq_ptr; } /* Endif */ } else { msgq_ptr->TD_PTR = NULL; } /* Endif */ _INT_ENABLE(); qid = BUILD_QID(kernel_data->INIT.PROCESSOR_NUMBER, queue); return (qid); } /* Endbody */