mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
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:
@@ -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
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user