From 3bb9542cd66a2b4cd5c4f0186420385eaf03f2d9 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 9 Aug 2001 21:08:50 +0000 Subject: 2001-08-09 Joel Sherrill * 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 . --- c/src/exec/itron/src/snd_mbx.c | 7 ++- c/src/exec/itron/src/tsnd_mbf.c | 5 +- c/src/exec/posix/src/mqueuesendsupp.c | 7 +-- c/src/exec/rtems/src/msgqsubmit.c | 10 ++-- c/src/exec/score/include/rtems/score/coremsg.h | 2 +- c/src/exec/score/inline/rtems/score/coremsg.inl | 8 ++-- c/src/exec/score/src/coremsgsubmit.c | 61 +++++++++++++++---------- 7 files changed, 57 insertions(+), 43 deletions(-) diff --git a/c/src/exec/itron/src/snd_mbx.c b/c/src/exec/itron/src/snd_mbx.c index e02714465e..db1f0ee5ae 100644 --- a/c/src/exec/itron/src/snd_mbx.c +++ b/c/src/exec/itron/src/snd_mbx.c @@ -29,6 +29,7 @@ ER snd_msg( Objects_Locations location; unsigned32 message_priority; void *message_contents; + CORE_message_queue_Status msg_status; if ( !pk_msg ) return E_PAR; @@ -46,7 +47,7 @@ ER snd_msg( message_priority = CORE_MESSAGE_QUEUE_SEND_REQUEST; message_contents = pk_msg; - _CORE_message_queue_Submit( + msg_status = _CORE_message_queue_Submit( &the_mailbox->message_queue, &message_contents, sizeof(T_MSG *), @@ -60,8 +61,6 @@ ER snd_msg( } _ITRON_return_errorno( - _ITRON_Mailbox_Translate_core_message_queue_return_code( - _Thread_Executing->Wait.return_code - ) + _ITRON_Mailbox_Translate_core_message_queue_return_code( msg_status ) ); } diff --git a/c/src/exec/itron/src/tsnd_mbf.c b/c/src/exec/itron/src/tsnd_mbf.c index 0ed3b4f90e..5a4e4cb1b2 100644 --- a/c/src/exec/itron/src/tsnd_mbf.c +++ b/c/src/exec/itron/src/tsnd_mbf.c @@ -33,6 +33,7 @@ ER tsnd_mbf( Objects_Locations location; Watchdog_Interval interval; boolean wait; + CORE_message_queue_Status msg_status; if (msgsz <= 0 || !msg) return E_PAR; @@ -57,7 +58,7 @@ ER tsnd_mbf( case OBJECTS_LOCAL: /* XXX Submit needs to take into account blocking */ - _CORE_message_queue_Submit( + msg_status = _CORE_message_queue_Submit( &the_message_buffer->message_queue, msg, msgsz, @@ -69,7 +70,7 @@ ER tsnd_mbf( ); _Thread_Enable_dispatch(); return _ITRON_Message_buffer_Translate_core_message_buffer_return_code( - _Thread_Executing->Wait.return_code + msg_status ); } diff --git a/c/src/exec/posix/src/mqueuesendsupp.c b/c/src/exec/posix/src/mqueuesendsupp.c index f456758c83..9615244583 100644 --- a/c/src/exec/posix/src/mqueuesendsupp.c +++ b/c/src/exec/posix/src/mqueuesendsupp.c @@ -44,6 +44,7 @@ int _POSIX_Message_queue_Send_support( { register POSIX_Message_queue_Control *the_mq; Objects_Locations location; + CORE_message_queue_Status msg_status; /* * Validate the priority. @@ -70,7 +71,7 @@ int _POSIX_Message_queue_Send_support( set_errno_and_return_minus_one( EBADF ); } - _CORE_message_queue_Submit( + msg_status = _CORE_message_queue_Submit( &the_mq->Message_queue, (void *) msg_ptr, msg_len, @@ -86,12 +87,12 @@ int _POSIX_Message_queue_Send_support( ); _Thread_Enable_dispatch(); - if ( !_Thread_Executing->Wait.return_code ) + if ( !msg_status ) return 0; set_errno_and_return_minus_one( _POSIX_Message_queue_Translate_core_message_queue_return_code( - _Thread_Executing->Wait.return_code + msg_status ) ); } diff --git a/c/src/exec/rtems/src/msgqsubmit.c b/c/src/exec/rtems/src/msgqsubmit.c index 16f1c50266..5cca0ae5dd 100644 --- a/c/src/exec/rtems/src/msgqsubmit.c +++ b/c/src/exec/rtems/src/msgqsubmit.c @@ -61,6 +61,7 @@ rtems_status_code _Message_queue_Submit( { register Message_queue_Control *the_message_queue; Objects_Locations location; + CORE_message_queue_Status msg_status; the_message_queue = _Message_queue_Get( id, &location ); switch ( location ) @@ -97,7 +98,7 @@ rtems_status_code _Message_queue_Submit( case OBJECTS_LOCAL: switch ( submit_type ) { case MESSAGE_QUEUE_SEND_REQUEST: - _CORE_message_queue_Send( + msg_status = _CORE_message_queue_Send( &the_message_queue->message_queue, buffer, size, @@ -112,7 +113,7 @@ rtems_status_code _Message_queue_Submit( ); break; case MESSAGE_QUEUE_URGENT_REQUEST: - _CORE_message_queue_Urgent( + msg_status = _CORE_message_queue_Urgent( &the_message_queue->message_queue, buffer, size, @@ -131,9 +132,8 @@ rtems_status_code _Message_queue_Submit( } _Thread_Enable_dispatch(); - return _Message_queue_Translate_core_message_queue_return_code( - _Thread_Executing->Wait.return_code - ); + return + _Message_queue_Translate_core_message_queue_return_code( msg_status ); } return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ diff --git a/c/src/exec/score/include/rtems/score/coremsg.h b/c/src/exec/score/include/rtems/score/coremsg.h index 818b1e8c18..0036db0f81 100644 --- a/c/src/exec/score/include/rtems/score/coremsg.h +++ b/c/src/exec/score/include/rtems/score/coremsg.h @@ -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, void *buffer, unsigned32 size, diff --git a/c/src/exec/score/inline/rtems/score/coremsg.inl b/c/src/exec/score/inline/rtems/score/coremsg.inl index 7356ce9537..2f6fe5e877 100644 --- a/c/src/exec/score/inline/rtems/score/coremsg.inl +++ b/c/src/exec/score/inline/rtems/score/coremsg.inl @@ -27,7 +27,7 @@ * 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, void *buffer, unsigned32 size, @@ -37,7 +37,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send( Watchdog_Interval timeout ) { - _CORE_message_queue_Submit( + return _CORE_message_queue_Submit( the_message_queue, buffer, 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. */ -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, void *buffer, unsigned32 size, @@ -72,7 +72,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Urgent( Watchdog_Interval timeout ) { - _CORE_message_queue_Submit( + return _CORE_message_queue_Submit( the_message_queue, buffer, size, diff --git a/c/src/exec/score/src/coremsgsubmit.c b/c/src/exec/score/src/coremsgsubmit.c index 6829351c18..94398db4c0 100644 --- a/c/src/exec/score/src/coremsgsubmit.c +++ b/c/src/exec/score/src/coremsgsubmit.c @@ -53,7 +53,7 @@ * error code - if unsuccessful */ -void _CORE_message_queue_Submit( +CORE_message_queue_Status _CORE_message_queue_Submit( CORE_message_queue_Control *the_message_queue, void *buffer, unsigned32 size, @@ -67,14 +67,9 @@ void _CORE_message_queue_Submit( ISR_Level level; CORE_message_queue_Buffer_control *the_message; 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 ) { - _Thread_Executing->Wait.return_code = - CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE; - return; + return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE; } /* @@ -96,7 +91,7 @@ void _CORE_message_queue_Submit( if ( !_Objects_Is_local_id( the_thread->Object.id ) ) (*api_message_queue_mp_support) ( the_thread, id ); #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. */ + if ( !the_message ) { - _Thread_Executing->Wait.return_code = - CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED; - return; + return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED; } _CORE_message_queue_Copy_buffer( @@ -133,7 +127,7 @@ void _CORE_message_queue_Submit( the_message, submit_type ); - return; + return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL; } /* @@ -143,20 +137,39 @@ void _CORE_message_queue_Submit( */ if ( !wait ) { - _Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_TOO_MANY; - return; + return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY; + } + + /* + * Do NOT block on a send if the caller is in an ISR. It is + * deadly to block in an ISR. + */ + + if ( _ISR_Is_in_progress() ) { + return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED; } - executing = _Thread_Executing; + /* + * 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 ); - _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 ); + } - _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout ); + return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL; } -- cgit v1.2.3