summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
Diffstat (limited to 'c')
-rw-r--r--c/src/exec/score/include/rtems/score/coremsg.h14
-rw-r--r--c/src/exec/score/src/coremsg.c34
2 files changed, 43 insertions, 5 deletions
diff --git a/c/src/exec/score/include/rtems/score/coremsg.h b/c/src/exec/score/include/rtems/score/coremsg.h
index 03277e12b7..9e94828468 100644
--- a/c/src/exec/score/include/rtems/score/coremsg.h
+++ b/c/src/exec/score/include/rtems/score/coremsg.h
@@ -56,6 +56,7 @@ typedef struct {
typedef struct {
Chain_Node Node;
+ int priority;
CORE_message_queue_Buffer Contents;
} CORE_message_queue_Buffer_control;
@@ -72,12 +73,17 @@ typedef enum {
* The following enumerated type details the modes in which a message
* may be submitted to a message queue. The message may be posted
* in a send or urgent fashion.
+ *
+ * NOTE: All other values are message priorities. Numerically smaller
+ * priorities indicate higher priority messages.
+ *
+ * XXX these constants should be changed to be compiler dependent.
*/
-typedef enum {
- CORE_MESSAGE_QUEUE_SEND_REQUEST = 0,
- CORE_MESSAGE_QUEUE_URGENT_REQUEST = 1
-} CORE_message_queue_Submit_types;
+#define CORE_MESSAGE_QUEUE_SEND_REQUEST 0x7fffffff
+#define CORE_MESSAGE_QUEUE_URGENT_REQUEST -(0x7fffffff)
+
+typedef int CORE_message_queue_Submit_types;
/*
* Core Message queue handler return statuses.
diff --git a/c/src/exec/score/src/coremsg.c b/c/src/exec/score/src/coremsg.c
index 2d1eca624b..da06c7acf9 100644
--- a/c/src/exec/score/src/coremsg.c
+++ b/c/src/exec/score/src/coremsg.c
@@ -422,7 +422,8 @@ CORE_message_queue_Status _CORE_message_queue_Submit(
_CORE_message_queue_Copy_buffer( buffer, the_message->Contents.buffer, size );
the_message->Contents.size = size;
-
+ the_message->priority = submit_type;
+
the_message_queue->number_of_pending_messages += 1;
switch ( submit_type ) {
@@ -432,7 +433,38 @@ CORE_message_queue_Status _CORE_message_queue_Submit(
case CORE_MESSAGE_QUEUE_URGENT_REQUEST:
_CORE_message_queue_Prepend( the_message_queue, the_message );
break;
+ default:
+ /* XXX interrupt critical section needs to be addressed */
+ {
+ CORE_message_queue_Buffer_control *this_message;
+ Chain_Node *the_node;
+
+ the_message->priority = submit_type;
+ for ( the_node = the_message_queue->Pending_messages.first ;
+ !_Chain_Is_tail( &the_message_queue->Pending_messages, the_node ) ;
+ the_node = the_node->next ) {
+
+ this_message = (CORE_message_queue_Buffer_control *) the_node;
+
+ if ( this_message->priority >= the_message->priority )
+ continue;
+
+ _Chain_Insert( the_node, &the_message->Node );
+ break;
+ }
+ }
+ break;
}
+ /*
+ * According to POSIX, does this happen before or after the message
+ * is actually enqueued. It is logical to think afterwards, because
+ * the message is actually in the queue at this point.
+ */
+
+ if ( the_message_queue->number_of_pending_messages == 1 &&
+ the_message_queue->notify_handler )
+ (*the_message_queue->notify_handler)( the_message_queue->notify_argument );
+
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
}