Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79966 - trunk/boost/interprocess/ipc
From: igaztanaga_at_[hidden]
Date: 2012-08-11 08:48:53


Author: igaztanaga
Date: 2012-08-11 08:48:52 EDT (Sat, 11 Aug 2012)
New Revision: 79966
URL: http://svn.boost.org/trac/boost/changeset/79966

Log:
Optimized notify usage: called only when full or empty and outside the lock.
Text files modified:
   trunk/boost/interprocess/ipc/message_queue.hpp | 35 ++++++++++++++++++-----------------
   1 files changed, 18 insertions(+), 17 deletions(-)

Modified: trunk/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- trunk/boost/interprocess/ipc/message_queue.hpp (original)
+++ trunk/boost/interprocess/ipc/message_queue.hpp 2012-08-11 08:48:52 EDT (Sat, 11 Aug 2012)
@@ -697,13 +697,13 @@
       throw interprocess_exception(size_error);
    }
 
+ bool was_empty = false;
    //---------------------------------------------
    scoped_lock<interprocess_mutex> lock(p_hdr->m_mutex);
    //---------------------------------------------
    {
       //If the queue is full execute blocking logic
       if (p_hdr->is_full()) {
-
          switch(block){
             case non_blocking :
                return false;
@@ -724,7 +724,6 @@
                      break;
                   }
                }
-
                while (p_hdr->is_full());
             break;
             default:
@@ -732,10 +731,7 @@
          }
       }
 
- //Get the first free message from free message queue
- //ipcdetail::msg_hdr_t<VoidPointer> &free_msg_hdr = p_hdr->first_free_msg_hdr();
-
-// bool was_empty = p_hdr->is_empty();
+ was_empty = p_hdr->is_empty();
       //Insert the first free message in the priority queue
       ipcdetail::msg_hdr_t<VoidPointer> &free_msg_hdr = p_hdr->queue_free_msg(priority);
 
@@ -749,13 +745,15 @@
 
       //Copy user buffer to the message
       std::memcpy(free_msg_hdr.data(), buffer, buffer_size);
-
- //If this message changes the queue empty state, notify it to receivers
-// if (was_empty){
- p_hdr->m_cond_recv.notify_one();
-// }
    } // Lock end
 
+ //Notify outside lock to avoid contention. This might produce some
+ //spurious wakeups, but it's usually far better than notifying inside.
+ //If this message changes the queue empty state, notify it to receivers
+ if (was_empty){
+ p_hdr->m_cond_recv.notify_one();
+ }
+
    return true;
 }
 
@@ -796,6 +794,7 @@
       throw interprocess_exception(size_error);
    }
 
+ bool was_full = false;
    //---------------------------------------------
    scoped_lock<interprocess_mutex> lock(p_hdr->m_mutex);
    //---------------------------------------------
@@ -845,17 +844,19 @@
       //Copy data to receiver's bufers
       std::memcpy(buffer, top_msg.data(), recvd_size);
 
-// bool was_full = p_hdr->is_full();
+ was_full = p_hdr->is_full();
 
       //Free top message and put it in the free message list
       p_hdr->free_top_msg();
-
- //If this reception changes the queue full state, notify senders
-// if (was_full){
- p_hdr->m_cond_send.notify_one();
-// }
    } //Lock end
 
+ //Notify outside lock to avoid contention. This might produce some
+ //spurious wakeups, but it's usually far better than notifying inside.
+ //If this reception changes the queue full state, notify senders
+ if (was_full){
+ p_hdr->m_cond_send.notify_one();
+ }
+
    return true;
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk