/* * ITRON Message Buffer Manager * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * * $Id$ */ #include #include #include ER _ITRON_Message_buffer_Translate_core_message_buffer_return_code( CORE_message_queue_Status status ) { switch (status) { case CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL: return E_OK; case CORE_MESSAGE_QUEUE_STATUS_TOO_MANY: return E_TMOUT; case CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE: return E_PAR; case CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT: return E_TMOUT; case CORE_MESSAGE_QUEUE_STATUS_TIMEOUT: return E_TMOUT; default: return E_ID; } } /* * _ITRON_Message_buffer_Manager_initialization * * This routine initializes all message buffer manager related data * structures. * * Input parameters: * maximum_message_buffers - maximum configured message buffers * * Output parameters: NONE */ void _ITRON_Message_buffer_Manager_initialization( unsigned32 maximum_message_buffers ) { _Objects_Initialize_information( &_ITRON_Message_buffer_Information, /* object information table */ OBJECTS_ITRON_MESSAGE_BUFFERS, /* object class */ FALSE, /* TRUE if this is a global object class */ maximum_message_buffers, /* maximum objects of this class */ sizeof( ITRON_Message_buffer_Control ), /* size of this object's control block */ FALSE, /* TRUE if names for this object are strings */ RTEMS_MAXIMUM_NAME_LENGTH, /* maximum length of each object's name */ FALSE /* TRUE if this class is threads */ ); /* * Register the MP Process Packet routine. * * NOTE: No MP Support YET in RTEMS ITRON implementation. */ } /* * cre_mbf - Create MessageBuffer */ ER cre_mbf( ID mbfid, T_CMBF *pk_cmbf ) { CORE_message_queue_Attributes the_message_queue_attributes; ITRON_Message_buffer_Control *the_message_buffer; /* * Bad pointer to the attributes structure */ if ( !pk_cmbf ) return E_PAR; /* * Bits were set that were note defined. */ if (pk_cmbf->mbfatr & ~(TA_TPRI)) return E_RSATR; if (pk_cmbf->bufsz < 0 || pk_cmbf->maxmsz < 0) return E_PAR; if (pk_cmbf->bufsz < pk_cmbf->maxmsz) return E_PAR; _Thread_Disable_dispatch(); /* prevents deletion */ the_message_buffer = _ITRON_Message_buffer_Allocate(mbfid); if ( !the_message_buffer ) { _Thread_Enable_dispatch(); return _ITRON_Message_buffer_Clarify_allocation_id_error(mbfid); } if ( pk_cmbf->mbfatr & TA_TPRI ) the_message_queue_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY; else the_message_queue_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO; _CORE_message_queue_Initialize( &the_message_buffer->message_queue, OBJECTS_ITRON_MESSAGE_BUFFERS, &the_message_queue_attributes, pk_cmbf->bufsz / pk_cmbf->maxmsz, pk_cmbf->maxmsz, NULL /* Multiprocessing not supported */ ); _ITRON_Objects_Open( &_ITRON_Message_buffer_Information, &the_message_buffer->Object ); /* * If multiprocessing were supported, this is where we would announce * the existence of the semaphore to the rest of the system. */ #if defined(RTEMS_MULTIPROCESSING) #endif _Thread_Enable_dispatch(); return E_OK; } /* * del_mbf - Delete MessageBuffer */ ER del_mbf( ID mbfid ) { ITRON_Message_buffer_Control *the_message_buffer; Objects_Locations location; the_message_buffer = _ITRON_Message_buffer_Get(mbfid, &location); switch (location) { case OBJECTS_REMOTE: case OBJECTS_ERROR: /* Multiprocessing not supported */ return _ITRON_Message_buffer_Clarify_get_id_error(mbfid); case OBJECTS_LOCAL: _CORE_message_queue_Flush(&the_message_buffer->message_queue); _ITRON_Objects_Close( &_ITRON_Message_buffer_Information, &the_message_buffer->Object); _ITRON_Message_buffer_Free(the_message_buffer); /* * If multiprocessing were supported, this is where we would announce * the existence of the semaphore to the rest of the system. */ #if defined(RTEMS_MULTIPROCESSING) #endif _Thread_Enable_dispatch(); return E_OK; } return E_OK; } /* * snd_mbf - Send Message to MessageBuffer */ ER snd_mbf( ID mbfid, VP msg, INT msgsz ) { return E_OK; } /* * psnd_mbf - Poll and Send Message to MessageBuffer */ ER psnd_mbf( ID mbfid, VP msg, INT msgsz ) { ITRON_Message_buffer_Control *the_message_buffer; Objects_Locations location; CORE_message_queue_Status status; if (msgsz <= 0 || !msg) return E_PAR; the_message_buffer = _ITRON_Message_buffer_Get(mbfid, &location); switch (location) { case OBJECTS_REMOTE: case OBJECTS_ERROR: /* Multiprocessing not supported */ return _ITRON_Message_buffer_Clarify_get_id_error(mbfid); case OBJECTS_LOCAL: status = _CORE_message_queue_Submit( &the_message_buffer->message_queue, msg, msgsz, the_message_buffer->Object.id, NULL, CORE_MESSAGE_QUEUE_SEND_REQUEST ); _Thread_Enable_dispatch(); return _ITRON_Message_buffer_Translate_core_message_buffer_return_code(status); } /* * If multiprocessing were supported, this is where we would announce * the existence of the semaphore to the rest of the system. */ #if defined(RTEMS_MULTIPROCESSING) #endif return E_OK; } /* * tsnd_mbf - Send Message to MessageBuffer with Timeout */ ER tsnd_mbf( ID mbfid, VP msg, INT msgsz, TMO tmout ) { return E_OK; } /* * rcv_mbf - Receive Message from MessageBuffer */ ER rcv_mbf( VP msg, INT *p_msgsz, ID mbfid ) { return trcv_mbf(msg, p_msgsz, mbfid, TMO_FEVR); } /* * prcv_mbf - Poll and Receive Message from MessageBuffer */ ER prcv_mbf( VP msg, INT *p_msgsz, ID mbfid ) { return trcv_mbf(msg, p_msgsz, mbfid, TMO_POL); } /* * trcv_mbf - Receive Message from MessageBuffer with Timeout */ ER trcv_mbf( VP msg, INT *p_msgsz, ID mbfid, TMO tmout ) { ITRON_Message_buffer_Control *the_message_buffer; Objects_Locations location; CORE_message_queue_Status status; boolean wait; Watchdog_Interval interval; interval = 0; if (tmout == TMO_POL) { wait = FALSE; } else { wait = TRUE; if (tmout != TMO_FEVR) interval = TOD_MILLISECONDS_TO_TICKS(tmout); } if (wait && _ITRON_Is_in_non_task_state() ) return E_CTX; if (!p_msgsz || !msg || tmout <= -2) return E_PAR; the_message_buffer = _ITRON_Message_buffer_Get(mbfid, &location); switch (location) { case OBJECTS_REMOTE: case OBJECTS_ERROR: /* Multiprocessing not supported */ return _ITRON_Message_buffer_Clarify_get_id_error(mbfid); case OBJECTS_LOCAL: _CORE_message_queue_Seize( &the_message_buffer->message_queue, the_message_buffer->Object.id, msg, p_msgsz, wait, interval ); _Thread_Enable_dispatch(); status = (CORE_message_queue_Status)_Thread_Executing->Wait.return_code; return _ITRON_Message_buffer_Translate_core_message_buffer_return_code(status); } /* * If multiprocessing were supported, this is where we would announce * the existence of the semaphore to the rest of the system. */ #if defined(RTEMS_MULTIPROCESSING) #endif return E_OK; } /* * ref_mbf - Reference MessageBuffer Status */ ER ref_mbf( T_RMBF *pk_rmbf, ID mbfid ) { ITRON_Message_buffer_Control *the_message_buffer; Objects_Locations location; CORE_message_queue_Control *the_core_msgq; if ( !pk_rmbf ) return E_PAR; /* XXX check this error code */ the_message_buffer = _ITRON_Message_buffer_Get( mbfid, &location ); switch ( location ) { case OBJECTS_REMOTE: /* Multiprocessing not supported */ case OBJECTS_ERROR: return _ITRON_Message_buffer_Clarify_get_id_error( mbfid ); case OBJECTS_LOCAL: the_core_msgq = &the_message_buffer->message_queue; /* * Fill in the size of message to be sent */ if (the_core_msgq->number_of_pending_messages == 0) { pk_rmbf->msgsz = 0; } else { pk_rmbf->msgsz = ((CORE_message_queue_Buffer_control *) the_core_msgq->Pending_messages.first)->Contents.size; } /* * Fill in the size of free buffer */ pk_rmbf->frbufsz = (the_core_msgq->maximum_pending_messages - the_core_msgq->number_of_pending_messages) * the_core_msgq->maximum_message_size; /* * Fill in whether or not there is a waiting task */ if ( !_Thread_queue_First(&the_core_msgq->Wait_queue ) ) pk_rmbf->wtsk = FALSE; else pk_rmbf->wtsk = TRUE; pk_rmbf->stsk = FALSE; _Thread_Enable_dispatch(); return E_OK; } return E_OK; }