From 00815403be55800c8e6c9ecf8464def7179bbc21 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 9 Aug 2001 20:46:12 +0000 Subject: 2001-08-09 Joel Sherrill * include/rtems/score/coremsg.h, inline/rtems/score/coremsg.inl, 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/score/ChangeLog | 8 ++++ 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 +++++++++++++++---------- 4 files changed, 50 insertions(+), 29 deletions(-) (limited to 'c/src/exec') diff --git a/c/src/exec/score/ChangeLog b/c/src/exec/score/ChangeLog index cb702fbbe1..b60f40a988 100644 --- a/c/src/exec/score/ChangeLog +++ b/c/src/exec/score/ChangeLog @@ -1,4 +1,12 @@ +2001-08-09 Joel Sherrill + + * include/rtems/score/coremsg.h, inline/rtems/score/coremsg.inl, + 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 . + 2000-05-25 Sergei Organov * macros/rtems/score/coresem.inl, inline/rtems/score/coresem.inl: 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