/* * ITRON 3.0 Mailbox 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 /* * _ITRON_Mailbox_Translate_core_message_queue_return_code * * This routine translates a core message queue object status * into the appropriate ITRON status code. */ ER _ITRON_Mailbox_Translate_core_message_queue_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_Mailbox_Manager_initialization * * This routine initializes all mailboxes manager related data structures. * * Input parameters: * maximum_mailboxes - maximum configured mailboxes * * Output parameters: NONE */ void _ITRON_Mailbox_Manager_initialization( unsigned32 maximum_mailboxes ) { _Objects_Initialize_information( &_ITRON_Mailbox_Information, /* object information table */ OBJECTS_ITRON_MAILBOXES, /* object class */ FALSE, /* TRUE if this is a global */ /* object class */ maximum_mailboxes, /* maximum objects of this class */ sizeof( ITRON_Mailbox_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_mbx - Create Mailbox * * Creates a Mailbox according to the following spec: * * ------Parameters------------------------- * ID mbxid MailboxID * T_CMBX *pk_cmbx Packet to Create Mailbox * ----------------------------------------- * -*pk_cmbx members*- * VP exinf ExtendedInformation * ATR mbxatr MailboxAttributes * (the use of the following information * is implementation dependent) * INT bufcnt BufferMessageCount * (CPU and/or implementation-dependent information * may also be included) * * ----Return Parameters-------------------- * ER ercd ErrorCode * ----------------------------------------- * * * ----C Language Interface----------------- * ER ercd = cre_mbx ( ID mbxid, T_CMBX *pk_cmbx ) ; * ----------------------------------------- * */ ER cre_mbx( ID mbxid, T_CMBX *pk_cmbx ) { register ITRON_Mailbox_Control *the_mailbox; CORE_message_queue_Attributes the_mailbox_attributes; if ( !pk_cmbx ) return E_PAR; if ((pk_cmbx->mbxatr & (TA_TPRI | TA_MPRI)) != 0 ) return E_RSATR; _Thread_Disable_dispatch(); /* protects object pointer */ the_mailbox = _ITRON_Mailbox_Allocate( mbxid ); if ( !the_mailbox ) { _Thread_Enable_dispatch(); return _ITRON_Mailbox_Clarify_allocation_id_error( mbxid ); } the_mailbox->count = pk_cmbx->bufcnt; if (pk_cmbx->mbxatr & TA_MPRI) the_mailbox->do_message_priority = TRUE; else the_mailbox->do_message_priority = FALSE; if (pk_cmbx->mbxatr & TA_TPRI) the_mailbox_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY; else the_mailbox_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO; if ( !_CORE_message_queue_Initialize( &the_mailbox->message_queue, OBJECTS_ITRON_MAILBOXES, &the_mailbox_attributes, the_mailbox->count, sizeof(T_MSG *), NULL ) ) { /* Multiprocessing not supported */ _ITRON_Mailbox_Free(the_mailbox); _ITRON_return_errorno( E_OBJ ); } _ITRON_Objects_Open( &_ITRON_Mailbox_Information, &the_mailbox->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 _ITRON_return_errorno( E_OK ); } /* * del_mbx - Delete Mailbox * * * ------Parameters-------------- * ID mbxid The Mailbox's ID * ------------------------------ * * -----Return Parameters------- * ER ercd Itron Error Code * ----------------------------- * * -----C Language Interface---- * ER ercd = del_mbx(ID mbxid); * ----------------------------- * */ 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 ); } /* * snd_msg - Send Message to Mailbox */ ER snd_msg( ID mbxid, T_MSG *pk_msg ) { register ITRON_Mailbox_Control *the_mailbox; Objects_Locations location; CORE_message_queue_Status status = E_OK; unsigned32 message_priority; void *message_contents; if ( !pk_msg ) return E_PAR; the_mailbox = _ITRON_Mailbox_Get( mbxid, &location ); switch ( location ) { case OBJECTS_REMOTE: case OBJECTS_ERROR: return _ITRON_Mailbox_Clarify_get_id_error( mbxid ); case OBJECTS_LOCAL: if ( the_mailbox->do_message_priority ) message_priority = pk_msg->msgpri; else message_priority = CORE_MESSAGE_QUEUE_SEND_REQUEST; message_contents = pk_msg; status = _CORE_message_queue_Submit( &the_mailbox->message_queue, &message_contents, sizeof(T_MSG *), the_mailbox->Object.id, NULL, /* multiprocessing not supported */ message_priority ); break; } _ITRON_return_errorno( _ITRON_Mailbox_Translate_core_message_queue_return_code(status) ); } /* * rcv_msg - Receive Message from Mailbox */ ER rcv_msg( T_MSG **ppk_msg, ID mbxid ) { return trcv_msg( ppk_msg, mbxid, TMO_FEVR ); } /* * prcv_msg - Poll and Receive Message from Mailbox */ ER prcv_msg( T_MSG **ppk_msg, ID mbxid ) { return trcv_msg( ppk_msg, mbxid, TMO_POL ); } /* * trcv_msg - Receive Message from Mailbox with Timeout */ ER trcv_msg( T_MSG **ppk_msg, ID mbxid, TMO tmout ) { register ITRON_Mailbox_Control *the_mailbox; Watchdog_Interval interval; boolean wait; Objects_Locations location; unsigned32 size; if (!ppk_msg) return E_PAR; 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; the_mailbox = _ITRON_Mailbox_Get( mbxid, &location ); switch ( location ) { case OBJECTS_REMOTE: case OBJECTS_ERROR: return _ITRON_Mailbox_Clarify_get_id_error( mbxid ); case OBJECTS_LOCAL: _CORE_message_queue_Seize( &the_mailbox->message_queue, the_mailbox->Object.id, ppk_msg, &size, wait, interval ); break; } _ITRON_return_errorno( _ITRON_Mailbox_Translate_core_message_queue_return_code( _Thread_Executing->Wait.return_code ) ); } /* * ref_mbx - Reference Mailbox Status */ ER ref_mbx( T_RMBX *pk_rmbx, ID mbxid ) { register ITRON_Mailbox_Control *the_mailbox; Objects_Locations location; Chain_Control *pending; if ( !pk_rmbx ) return E_PAR; the_mailbox = _ITRON_Mailbox_Get( mbxid, &location ); switch ( location ) { case OBJECTS_REMOTE: case OBJECTS_ERROR: return _ITRON_Mailbox_Clarify_get_id_error( mbxid ); case OBJECTS_LOCAL: pending = &the_mailbox->message_queue.Pending_messages; if ( _Chain_Is_empty( pending ) ) pk_rmbx->pk_msg = NULL; else pk_rmbx->pk_msg = (T_MSG *) pending->first; /* * Fill in whether or not there is a waiting task */ if ( !_Thread_queue_First( &the_mailbox->message_queue.Wait_queue ) ) pk_rmbx->wtsk = FALSE; else pk_rmbx->wtsk = TRUE; break; } _ITRON_return_errorno( E_OK ); }