|
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