source: rtems/cpukit/score/src/coremsginsert.c @ 0a97ba5b

5
Last change on this file since 0a97ba5b was cc18d7b, checked in by Sebastian Huber <sebastian.huber@…>, on 04/30/15 at 11:12:54

score: Fine grained locking for message queues

Aggregate several critical sections into a bigger one. Sending and
receiving messages is now protected by an ISR lock. Thread dispatching
is only disabled in case a blocking operation is necessary. The message
copy procedure is done inside the critical section (interrupts
disabled). Thus this change may have a negative impact on the interrupt
latency in case very large messages are transferred.

Update #2273.

  • Property mode set to 100644
File size: 2.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief Insert a Message into the Message Queue
5 * @ingroup ScoreMessageQueue
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2005.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/coremsgimpl.h>
22
23#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
24static bool _CORE_message_queue_Order(
25  const Chain_Node *left,
26  const Chain_Node *right
27)
28{
29   const CORE_message_queue_Buffer_control *left_message;
30   const CORE_message_queue_Buffer_control *right_message;
31
32   left_message = (const CORE_message_queue_Buffer_control *) left;
33   right_message = (const CORE_message_queue_Buffer_control *) right;
34
35   return _CORE_message_queue_Get_message_priority( left_message ) <
36     _CORE_message_queue_Get_message_priority( right_message );
37}
38#endif
39
40void _CORE_message_queue_Insert_message(
41  CORE_message_queue_Control        *the_message_queue,
42  CORE_message_queue_Buffer_control *the_message,
43  CORE_message_queue_Submit_types    submit_type
44)
45{
46  Chain_Control *pending_messages;
47#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
48  bool           notify;
49#endif
50
51  _CORE_message_queue_Set_message_priority( the_message, submit_type );
52  pending_messages = &the_message_queue->Pending_messages;
53
54#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
55  notify = ( the_message_queue->number_of_pending_messages == 0 );
56#endif
57  ++the_message_queue->number_of_pending_messages;
58
59  if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) {
60    _Chain_Append_unprotected( pending_messages, &the_message->Node );
61#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
62  } else  if ( submit_type != CORE_MESSAGE_QUEUE_URGENT_REQUEST ) {
63    _Chain_Insert_ordered_unprotected(
64      pending_messages,
65      &the_message->Node,
66      _CORE_message_queue_Order
67    );
68#endif
69  } else {
70    _Chain_Prepend_unprotected( pending_messages, &the_message->Node );
71  }
72
73  #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
74    /*
75     *  According to POSIX, does this happen before or after the message
76     *  is actually enqueued.  It is logical to think afterwards, because
77     *  the message is actually in the queue at this point.
78     */
79    if ( notify && the_message_queue->notify_handler )
80      (*the_message_queue->notify_handler)(the_message_queue->notify_argument);
81  #endif
82}
Note: See TracBrowser for help on using the repository browser.