return false;
// is there an I/O request we could potentially delay?
- if (!queue->popReady()) {
- // unlike pop(), popReady() is not reliable and does not block reader
+ int processId;
+ IpcIoMsg ipcIo;
+ if (!queue->peek(processId, ipcIo)) {
+ // unlike pop(), peek() is not reliable and does not block reader
// so we must proceed with pop() even if it is likely to fail
return false;
}
debugs(47, 7, HERE << "rate limiting balance: " << balance << " after +" << credit << " -" << debit);
- if (balance > maxImbalance) {
- // if we accumulated too much time for future slow I/Os,
- // then shed accumulated time to keep just half of the excess
+ if (ipcIo.command == IpcIo::cmdWrite && balance > maxImbalance) {
+ // if the next request is (likely) write and we accumulated
+ // too much time for future slow I/Os, then shed accumulated
+ // time to keep just half of the excess
const int64_t toSpend = balance - maxImbalance/2;
if (toSpend/1e3 > Timeout)
expected swap wait time.
max-swap-rate=swaps/sec: Artificially limits disk access using
- the specified I/O rate limit. Swap in and swap out requests that
+ the specified I/O rate limit. Swap out requests that
would cause the average I/O rate to exceed the limit are
- delayed. This is necessary on file systems that buffer "too
+ delayed. Individual swap in requests (i.e., hits or reads) are
+ not delayed, but they do contribute to measured swap rate and
+ since they are placed in the same FIFO queue as swap out
+ requests, they may wait longer if max-swap-rate is smaller.
+ This is necessary on file systems that buffer "too
many" writes and then start blocking Squid and other processes
while committing those writes to disk. Usually used together
with swap-timeout to avoid excessive delays and queue overflows
// theLastPopProcessId = remoteProcessId;
}
-bool
-Ipc::FewToFewBiQueue::popReady() const
-{
- // mimic FewToFewBiQueue::pop() but quit just before popping
- int popProcessId = theLastPopProcessId; // preserve for future pop()
- for (int i = 0; i < remoteGroupSize(); ++i) {
- if (++popProcessId >= remoteGroupIdOffset() + remoteGroupSize())
- popProcessId = remoteGroupIdOffset();
- const OneToOneUniQueue &queue = oneToOneQueue(remoteGroup(), popProcessId, theLocalGroup, theLocalProcessId);
- if (!queue.empty())
- return true;
- }
- return false; // most likely, no process had anything to pop
-}
-
Ipc::QueueReader::Balance &
Ipc::FewToFewBiQueue::localBalance()
{
/// us and the given remote process
template<class Value> bool findOldest(const int remoteProcessId, Value &value) const;
- /// returns true if pop() would have probably succeeded but does not pop()
- bool popReady() const;
+ /// peeks at the item likely to be pop()ed next
+ template<class Value> bool peek(int &remoteProcessId, Value &value) const;
/// returns local reader's balance
QueueReader::Balance &localBalance();
return out.peek(value);
}
+template <class Value>
+bool
+FewToFewBiQueue::peek(int &remoteProcessId, Value &value) const
+{
+ // mimic FewToFewBiQueue::pop() but quit just before popping
+ int popProcessId = theLastPopProcessId; // preserve for future pop()
+ for (int i = 0; i < remoteGroupSize(); ++i) {
+ if (++popProcessId >= remoteGroupIdOffset() + remoteGroupSize())
+ popProcessId = remoteGroupIdOffset();
+ const OneToOneUniQueue &queue =
+ oneToOneQueue(remoteGroup(), popProcessId,
+ theLocalGroup, theLocalProcessId);
+ if (queue.peek(value)) {
+ remoteProcessId = popProcessId;
+ return true;
+ }
+ }
+ return false; // most likely, no process had anything to pop
+}
+
} // namespace Ipc
#endif // SQUID_IPC_QUEUE_H