summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-04-29 11:05:36 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-02 07:46:15 +0200
commit7e66865e17d7a82add541056de13717793da002a (patch)
tree924312da2c1abe33c48b6ec84102cde59c28074c
parentscore: _CORE_message_queue_Insert_message() (diff)
downloadrtems-7e66865e17d7a82add541056de13717793da002a.tar.bz2
score: Move message notification
Move message notification to end of critical section and delegate the message queue release to the notification handler. It may do more complex notification actions out of the critical section. Update #2555.
-rw-r--r--cpukit/posix/src/mqueuenotify.c23
-rw-r--r--cpukit/score/include/rtems/score/coremsg.h14
-rw-r--r--cpukit/score/include/rtems/score/coremsgimpl.h10
-rw-r--r--cpukit/score/src/coremsg.c2
-rw-r--r--cpukit/score/src/coremsginsert.c17
-rw-r--r--cpukit/score/src/coremsgsubmit.c21
6 files changed, 50 insertions, 37 deletions
diff --git a/cpukit/posix/src/mqueuenotify.c b/cpukit/posix/src/mqueuenotify.c
index 810097691f..d31a8e662d 100644
--- a/cpukit/posix/src/mqueuenotify.c
+++ b/cpukit/posix/src/mqueuenotify.c
@@ -39,16 +39,24 @@
*/
static void _POSIX_Message_queue_Notify_handler(
- void *user_data
+ CORE_message_queue_Control *the_message_queue,
+ ISR_lock_Context *lock_context
)
{
POSIX_Message_queue_Control *the_mq;
+ int signo;
- the_mq = user_data;
+ the_mq = RTEMS_CONTAINER_OF(
+ the_message_queue,
+ POSIX_Message_queue_Control,
+ Message_queue
+ );
- kill( getpid(), the_mq->notification.sigev_signo );
+ signo = the_mq->notification.sigev_signo;
+ _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL );
+ _CORE_message_queue_Release( &the_mq->Message_queue, lock_context );
- _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
+ kill( getpid(), signo );
}
int mq_notify(
@@ -72,18 +80,17 @@ int mq_notify(
rtems_set_errno_and_return_minus_one( EBUSY );
}
- _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
+ _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL );
the_mq->notification = *notification;
_CORE_message_queue_Set_notify(
&the_mq->Message_queue,
- _POSIX_Message_queue_Notify_handler,
- the_mq
+ _POSIX_Message_queue_Notify_handler
);
} else {
- _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
+ _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL );
}
diff --git a/cpukit/score/include/rtems/score/coremsg.h b/cpukit/score/include/rtems/score/coremsg.h
index 27443462fe..af42e7d63d 100644
--- a/cpukit/score/include/rtems/score/coremsg.h
+++ b/cpukit/score/include/rtems/score/coremsg.h
@@ -20,6 +20,7 @@
#define _RTEMS_SCORE_COREMSG_H
#include <rtems/score/chain.h>
+#include <rtems/score/isrlock.h>
#include <rtems/score/threadq.h>
#include <rtems/score/watchdog.h>
@@ -63,6 +64,8 @@ extern "C" {
#define RTEMS_SCORE_COREMSG_ENABLE_BLOCKING_SEND
#endif
+typedef struct CORE_message_queue_Control CORE_message_queue_Control;
+
/**
* @brief Data types needed to manipulate the contents of message buffers.
*
@@ -117,7 +120,10 @@ typedef enum {
* notification handler is invoked when the message queue makes a
* 0->1 transition on pending messages.
*/
- typedef void (*CORE_message_queue_Notify_Handler)( void * );
+ typedef void (*CORE_message_queue_Notify_Handler)(
+ CORE_message_queue_Control *,
+ ISR_lock_Context *
+ );
#endif
/**
@@ -126,7 +132,7 @@ typedef enum {
* The following defines the control block used to manage each
* Message Queue.
*/
-typedef struct {
+struct CORE_message_queue_Control {
/** This field is the Waiting Queue used to manage the set of tasks
* which are blocked waiting to receive a message from this queue.
*/
@@ -162,14 +168,12 @@ typedef struct {
* from zero (0) messages pending to one (1) message pending.
*/
CORE_message_queue_Notify_Handler notify_handler;
- /** This field is the argument passed to the @ref notify_argument. */
- void *notify_argument;
#endif
/** This chain is the set of inactive messages. A message is inactive
* when it does not contain a pending message.
*/
Chain_Control Inactive_messages;
-} CORE_message_queue_Control;
+};
/**@}*/
diff --git a/cpukit/score/include/rtems/score/coremsgimpl.h b/cpukit/score/include/rtems/score/coremsgimpl.h
index b6103978e8..e3f0153fd9 100644
--- a/cpukit/score/include/rtems/score/coremsgimpl.h
+++ b/cpukit/score/include/rtems/score/coremsgimpl.h
@@ -612,17 +612,15 @@ RTEMS_INLINE_ROUTINE
#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
RTEMS_INLINE_ROUTINE void _CORE_message_queue_Set_notify (
CORE_message_queue_Control *the_message_queue,
- CORE_message_queue_Notify_Handler the_handler,
- void *the_argument
+ CORE_message_queue_Notify_Handler the_handler
)
{
- the_message_queue->notify_handler = the_handler;
- the_message_queue->notify_argument = the_argument;
+ the_message_queue->notify_handler = the_handler;
}
#else
/* turn it into nothing if not enabled */
- #define _CORE_message_queue_Set_notify( \
- the_message_queue, the_handler, the_argument )
+ #define _CORE_message_queue_Set_notify( the_message_queue, the_handler ) \
+ do { } while ( 0 )
#endif
RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Do_dequeue_receiver(
diff --git a/cpukit/score/src/coremsg.c b/cpukit/score/src/coremsg.c
index b184585964..03c0587448 100644
--- a/cpukit/score/src/coremsg.c
+++ b/cpukit/score/src/coremsg.c
@@ -55,7 +55,7 @@ bool _CORE_message_queue_Initialize(
the_message_queue->maximum_pending_messages = maximum_pending_messages;
the_message_queue->number_of_pending_messages = 0;
the_message_queue->maximum_message_size = maximum_message_size;
- _CORE_message_queue_Set_notify( the_message_queue, NULL, NULL );
+ _CORE_message_queue_Set_notify( the_message_queue, NULL );
allocated_message_size = maximum_message_size;
diff --git a/cpukit/score/src/coremsginsert.c b/cpukit/score/src/coremsginsert.c
index 8baea36067..4613f50436 100644
--- a/cpukit/score/src/coremsginsert.c
+++ b/cpukit/score/src/coremsginsert.c
@@ -46,9 +46,6 @@ void _CORE_message_queue_Insert_message(
)
{
Chain_Control *pending_messages;
-#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
- bool notify;
-#endif
the_message->Contents.size = content_size;
@@ -63,10 +60,6 @@ void _CORE_message_queue_Insert_message(
#endif
pending_messages = &the_message_queue->Pending_messages;
-
-#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
- notify = ( the_message_queue->number_of_pending_messages == 0 );
-#endif
++the_message_queue->number_of_pending_messages;
if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) {
@@ -82,14 +75,4 @@ void _CORE_message_queue_Insert_message(
} else {
_Chain_Prepend_unprotected( pending_messages, &the_message->Node );
}
-
- #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
- /*
- * 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 ( notify && the_message_queue->notify_handler )
- (*the_message_queue->notify_handler)(the_message_queue->notify_argument);
- #endif
}
diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c
index 1d6d298ea7..7e589e7754 100644
--- a/cpukit/score/src/coremsgsubmit.c
+++ b/cpukit/score/src/coremsgsubmit.c
@@ -79,7 +79,28 @@ CORE_message_queue_Status _CORE_message_queue_Do_submit(
size,
submit_type
);
+
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
+ /*
+ * 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 != NULL
+ ) {
+ ( *the_message_queue->notify_handler )(
+ the_message_queue,
+ lock_context
+ );
+ } else {
+ _CORE_message_queue_Release( the_message_queue, lock_context );
+ }
+#else
_CORE_message_queue_Release( the_message_queue, lock_context );
+#endif
+
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
}