2001-08-09 Joel Sherrill <joel@OARcorp.com>

* c/src/exec/itron/src/snd_mbx.c, c/src/exec/itron/src/tsnd_mbf.c
	c/src/exec/posix/src/mqueuesendsupp.c,
	c/src/exec/rtems/src/msgqsubmit.c,
	c/src/exec/score/include/rtems/score/coremsg.h,
	c/src/exec/score/inline/rtems/score/coremsg.inl,
	c/src/exec/score/src/coremsgsubmit.c: Unblocking message queue
	operations should NOT use _Thread_Executing for return status
	since it is permissible to invoke message send operations from
	an ISR.  This was reported by Suvrat Gupta <suvrat@utstar.com>.
This commit is contained in:
Joel Sherrill
2001-08-09 21:08:50 +00:00
parent b748fff9c5
commit 3bb9542cd6
7 changed files with 57 additions and 43 deletions

View File

@@ -29,6 +29,7 @@ ER snd_msg(
Objects_Locations location; Objects_Locations location;
unsigned32 message_priority; unsigned32 message_priority;
void *message_contents; void *message_contents;
CORE_message_queue_Status msg_status;
if ( !pk_msg ) if ( !pk_msg )
return E_PAR; return E_PAR;
@@ -46,7 +47,7 @@ ER snd_msg(
message_priority = CORE_MESSAGE_QUEUE_SEND_REQUEST; message_priority = CORE_MESSAGE_QUEUE_SEND_REQUEST;
message_contents = pk_msg; message_contents = pk_msg;
_CORE_message_queue_Submit( msg_status = _CORE_message_queue_Submit(
&the_mailbox->message_queue, &the_mailbox->message_queue,
&message_contents, &message_contents,
sizeof(T_MSG *), sizeof(T_MSG *),
@@ -60,8 +61,6 @@ ER snd_msg(
} }
_ITRON_return_errorno( _ITRON_return_errorno(
_ITRON_Mailbox_Translate_core_message_queue_return_code( _ITRON_Mailbox_Translate_core_message_queue_return_code( msg_status )
_Thread_Executing->Wait.return_code
)
); );
} }

View File

@@ -33,6 +33,7 @@ ER tsnd_mbf(
Objects_Locations location; Objects_Locations location;
Watchdog_Interval interval; Watchdog_Interval interval;
boolean wait; boolean wait;
CORE_message_queue_Status msg_status;
if (msgsz <= 0 || !msg) if (msgsz <= 0 || !msg)
return E_PAR; return E_PAR;
@@ -57,7 +58,7 @@ ER tsnd_mbf(
case OBJECTS_LOCAL: case OBJECTS_LOCAL:
/* XXX Submit needs to take into account blocking */ /* XXX Submit needs to take into account blocking */
_CORE_message_queue_Submit( msg_status = _CORE_message_queue_Submit(
&the_message_buffer->message_queue, &the_message_buffer->message_queue,
msg, msg,
msgsz, msgsz,
@@ -69,7 +70,7 @@ ER tsnd_mbf(
); );
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
return _ITRON_Message_buffer_Translate_core_message_buffer_return_code( return _ITRON_Message_buffer_Translate_core_message_buffer_return_code(
_Thread_Executing->Wait.return_code msg_status
); );
} }

View File

@@ -44,6 +44,7 @@ int _POSIX_Message_queue_Send_support(
{ {
register POSIX_Message_queue_Control *the_mq; register POSIX_Message_queue_Control *the_mq;
Objects_Locations location; Objects_Locations location;
CORE_message_queue_Status msg_status;
/* /*
* Validate the priority. * Validate the priority.
@@ -70,7 +71,7 @@ int _POSIX_Message_queue_Send_support(
set_errno_and_return_minus_one( EBADF ); set_errno_and_return_minus_one( EBADF );
} }
_CORE_message_queue_Submit( msg_status = _CORE_message_queue_Submit(
&the_mq->Message_queue, &the_mq->Message_queue,
(void *) msg_ptr, (void *) msg_ptr,
msg_len, msg_len,
@@ -86,12 +87,12 @@ int _POSIX_Message_queue_Send_support(
); );
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
if ( !_Thread_Executing->Wait.return_code ) if ( !msg_status )
return 0; return 0;
set_errno_and_return_minus_one( set_errno_and_return_minus_one(
_POSIX_Message_queue_Translate_core_message_queue_return_code( _POSIX_Message_queue_Translate_core_message_queue_return_code(
_Thread_Executing->Wait.return_code msg_status
) )
); );
} }

View File

@@ -61,6 +61,7 @@ rtems_status_code _Message_queue_Submit(
{ {
register Message_queue_Control *the_message_queue; register Message_queue_Control *the_message_queue;
Objects_Locations location; Objects_Locations location;
CORE_message_queue_Status msg_status;
the_message_queue = _Message_queue_Get( id, &location ); the_message_queue = _Message_queue_Get( id, &location );
switch ( location ) switch ( location )
@@ -97,7 +98,7 @@ rtems_status_code _Message_queue_Submit(
case OBJECTS_LOCAL: case OBJECTS_LOCAL:
switch ( submit_type ) { switch ( submit_type ) {
case MESSAGE_QUEUE_SEND_REQUEST: case MESSAGE_QUEUE_SEND_REQUEST:
_CORE_message_queue_Send( msg_status = _CORE_message_queue_Send(
&the_message_queue->message_queue, &the_message_queue->message_queue,
buffer, buffer,
size, size,
@@ -112,7 +113,7 @@ rtems_status_code _Message_queue_Submit(
); );
break; break;
case MESSAGE_QUEUE_URGENT_REQUEST: case MESSAGE_QUEUE_URGENT_REQUEST:
_CORE_message_queue_Urgent( msg_status = _CORE_message_queue_Urgent(
&the_message_queue->message_queue, &the_message_queue->message_queue,
buffer, buffer,
size, size,
@@ -131,9 +132,8 @@ rtems_status_code _Message_queue_Submit(
} }
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
return _Message_queue_Translate_core_message_queue_return_code( return
_Thread_Executing->Wait.return_code _Message_queue_Translate_core_message_queue_return_code( msg_status );
);
} }
return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */

View File

@@ -239,7 +239,7 @@ CORE_message_queue_Status _CORE_message_queue_Broadcast(
* *
*/ */
void _CORE_message_queue_Submit( CORE_message_queue_Status _CORE_message_queue_Submit(
CORE_message_queue_Control *the_message_queue, CORE_message_queue_Control *the_message_queue,
void *buffer, void *buffer,
unsigned32 size, unsigned32 size,

View File

@@ -27,7 +27,7 @@
* This routine sends a message to the end of the specified message queue. * This routine sends a message to the end of the specified message queue.
*/ */
RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send( RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send(
CORE_message_queue_Control *the_message_queue, CORE_message_queue_Control *the_message_queue,
void *buffer, void *buffer,
unsigned32 size, unsigned32 size,
@@ -37,7 +37,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send(
Watchdog_Interval timeout Watchdog_Interval timeout
) )
{ {
_CORE_message_queue_Submit( return _CORE_message_queue_Submit(
the_message_queue, the_message_queue,
buffer, buffer,
size, size,
@@ -62,7 +62,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send(
* This routine sends a message to the front of the specified message queue. * This routine sends a message to the front of the specified message queue.
*/ */
RTEMS_INLINE_ROUTINE void _CORE_message_queue_Urgent( RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent(
CORE_message_queue_Control *the_message_queue, CORE_message_queue_Control *the_message_queue,
void *buffer, void *buffer,
unsigned32 size, unsigned32 size,
@@ -72,7 +72,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Urgent(
Watchdog_Interval timeout Watchdog_Interval timeout
) )
{ {
_CORE_message_queue_Submit( return _CORE_message_queue_Submit(
the_message_queue, the_message_queue,
buffer, buffer,
size, size,

View File

@@ -53,7 +53,7 @@
* error code - if unsuccessful * error code - if unsuccessful
*/ */
void _CORE_message_queue_Submit( CORE_message_queue_Status _CORE_message_queue_Submit(
CORE_message_queue_Control *the_message_queue, CORE_message_queue_Control *the_message_queue,
void *buffer, void *buffer,
unsigned32 size, unsigned32 size,
@@ -67,14 +67,9 @@ void _CORE_message_queue_Submit(
ISR_Level level; ISR_Level level;
CORE_message_queue_Buffer_control *the_message; CORE_message_queue_Buffer_control *the_message;
Thread_Control *the_thread; Thread_Control *the_thread;
Thread_Control *executing;
_Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
if ( size > the_message_queue->maximum_message_size ) { if ( size > the_message_queue->maximum_message_size ) {
_Thread_Executing->Wait.return_code = return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
return;
} }
/* /*
@@ -96,7 +91,7 @@ void _CORE_message_queue_Submit(
if ( !_Objects_Is_local_id( the_thread->Object.id ) ) if ( !_Objects_Is_local_id( the_thread->Object.id ) )
(*api_message_queue_mp_support) ( the_thread, id ); (*api_message_queue_mp_support) ( the_thread, id );
#endif #endif
return; return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
} }
} }
@@ -114,10 +109,9 @@ void _CORE_message_queue_Submit(
/* /*
* NOTE: If the system is consistent, this error should never occur. * NOTE: If the system is consistent, this error should never occur.
*/ */
if ( !the_message ) { if ( !the_message ) {
_Thread_Executing->Wait.return_code = return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
return;
} }
_CORE_message_queue_Copy_buffer( _CORE_message_queue_Copy_buffer(
@@ -133,7 +127,7 @@ void _CORE_message_queue_Submit(
the_message, the_message,
submit_type submit_type
); );
return; return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
} }
/* /*
@@ -143,20 +137,39 @@ void _CORE_message_queue_Submit(
*/ */
if ( !wait ) { if ( !wait ) {
_Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_TOO_MANY; return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
return;
} }
executing = _Thread_Executing; /*
* Do NOT block on a send if the caller is in an ISR. It is
* deadly to block in an ISR.
*/
_ISR_Disable( level ); if ( _ISR_Is_in_progress() ) {
_Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue ); return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
executing->Wait.queue = &the_message_queue->Wait_queue; }
executing->Wait.id = id;
executing->Wait.return_argument = (void *)buffer;
executing->Wait.return_argument_1 = (void *)size;
executing->Wait.count = submit_type;
_ISR_Enable( level );
_Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout ); /*
* WARNING!! executing should NOT be used prior to this point.
* Thus the unusual choice to open a new scope and declare
* it as a variable. Doing this emphasizes how dangerous it
* would be to use this variable prior to here.
*/
{
Thread_Control *executing = _Thread_Executing;
_ISR_Disable( level );
_Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
executing->Wait.queue = &the_message_queue->Wait_queue;
executing->Wait.id = id;
executing->Wait.return_argument = (void *)buffer;
executing->Wait.return_argument_1 = (void *)size;
executing->Wait.count = submit_type;
_ISR_Enable( level );
_Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
}
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
} }