summaryrefslogtreecommitdiffstats
path: root/net/disk_cache
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-14 22:23:01 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-14 22:23:01 +0000
commitb05474d73e1f33770648ac9e11d58c6393caa82d (patch)
treee4fc5694358bf016a3fd0aa609ac59b10566d8de /net/disk_cache
parent0e38171bbd68e2a008fdc340942dc6eef9766563 (diff)
downloadchromium_src-b05474d73e1f33770648ac9e11d58c6393caa82d.zip
chromium_src-b05474d73e1f33770648ac9e11d58c6393caa82d.tar.gz
chromium_src-b05474d73e1f33770648ac9e11d58c6393caa82d.tar.bz2
Disk cache: Implement request throttling.
Note that no throttling is performed with this change, the backend is not activating the feature. BUG=54338 TEST=none. Review URL: http://codereview.chromium.org/3416002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59437 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache')
-rw-r--r--net/disk_cache/backend_impl.cc5
-rw-r--r--net/disk_cache/backend_impl.h3
-rw-r--r--net/disk_cache/in_flight_backend_io.cc67
-rw-r--r--net/disk_cache/in_flight_backend_io.h17
4 files changed, 82 insertions, 10 deletions
diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc
index 653d5c2..4b8e361 100644
--- a/net/disk_cache/backend_impl.cc
+++ b/net/disk_cache/backend_impl.cc
@@ -12,6 +12,7 @@
#include "base/rand_util.h"
#include "base/string_util.h"
#include "base/sys_info.h"
+#include "base/time.h"
#include "base/timer.h"
#include "base/worker_pool.h"
#include "net/base/net_errors.h"
@@ -1197,6 +1198,10 @@ void BackendImpl::OnWrite(int32 bytes) {
OnRead(bytes);
}
+void BackendImpl::OnOperationCompleted(base::TimeDelta elapsed_time) {
+ CACHE_UMA(TIMES, "TotalIOTime", 0, elapsed_time);
+}
+
void BackendImpl::OnStatsTimer() {
stats_.OnEvent(Stats::TIMER);
int64 time = stats_.GetCounter(Stats::TIMER);
diff --git a/net/disk_cache/backend_impl.h b/net/disk_cache/backend_impl.h
index 47bbe96..6aff0e2 100644
--- a/net/disk_cache/backend_impl.h
+++ b/net/disk_cache/backend_impl.h
@@ -213,6 +213,9 @@ class BackendImpl : public Backend {
void OnRead(int bytes);
void OnWrite(int bytes);
+ // Keeps track of the time needed to complete some IO operations.
+ void OnOperationCompleted(base::TimeDelta elapsed_time);
+
// Timer callback to calculate usage statistics.
void OnStatsTimer();
diff --git a/net/disk_cache/in_flight_backend_io.cc b/net/disk_cache/in_flight_backend_io.cc
index 1e2ce9f..0881ca5 100644
--- a/net/disk_cache/in_flight_backend_io.cc
+++ b/net/disk_cache/in_flight_backend_io.cc
@@ -9,6 +9,7 @@
#include "net/base/net_errors.h"
#include "net/disk_cache/backend_impl.h"
#include "net/disk_cache/entry_impl.h"
+#include "net/disk_cache/histogram_macros.h"
namespace disk_cache {
@@ -18,6 +19,7 @@ BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend,
operation_(OP_NONE),
ALLOW_THIS_IN_INITIALIZER_LIST(
my_callback_(this, &BackendIO::OnIOComplete)) {
+ start_time_ = base::TimeTicks::Now();
}
// Runs on the background thread.
@@ -44,6 +46,10 @@ void BackendIO::ReleaseEntry() {
entry_ = NULL;
}
+base::TimeDelta BackendIO::ElapsedTime() const {
+ return base::TimeTicks::Now() - start_time_;
+}
+
void BackendIO::Init() {
operation_ = OP_INIT;
}
@@ -262,6 +268,16 @@ void BackendIO::ExecuteEntryOperation() {
// ---------------------------------------------------------------------------
+InFlightBackendIO::InFlightBackendIO(BackendImpl* backend,
+ base::MessageLoopProxy* background_thread)
+ : backend_(backend),
+ background_thread_(background_thread),
+ queue_entry_ops_(false) {
+}
+
+InFlightBackendIO::~InFlightBackendIO() {
+}
+
void InFlightBackendIO::Init(CompletionCallback* callback) {
scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback);
operation->Init();
@@ -409,6 +425,14 @@ void InFlightBackendIO::WaitForPendingIO() {
InFlightIO::WaitForPendingIO();
}
+void InFlightBackendIO::StartQueingOperations() {
+ queue_entry_ops_ = true;
+}
+
+void InFlightBackendIO::StopQueingOperations() {
+ queue_entry_ops_ = false;
+}
+
void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation,
bool cancel) {
BackendIO* op = static_cast<BackendIO*>(operation);
@@ -417,9 +441,22 @@ void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation,
// Process the next request. Note that invoking the callback may result
// in the backend destruction (and with it this object), so we should deal
// with the next operation before invoking the callback.
- scoped_refptr<BackendIO> next_op = pending_ops_.front();
- pending_ops_.pop_front();
- PostOperation(next_op);
+ PostQueuedOperation(&pending_ops_);
+ }
+
+ if (op->IsEntryOperation()) {
+ backend_->OnOperationCompleted(op->ElapsedTime());
+ if (!pending_entry_ops_.empty()) {
+ PostQueuedOperation(&pending_entry_ops_);
+
+ // If we are not throttling requests anymore, dispatch the whole queue.
+ if (!queue_entry_ops_) {
+ CACHE_UMA(COUNTS_10000, "FinalQueuedOperations", 0,
+ pending_entry_ops_.size());
+ while (!pending_entry_ops_.empty())
+ PostQueuedOperation(&pending_entry_ops_);
+ }
+ }
}
if (op->callback() && (!cancel || op->IsEntryOperation()))
@@ -430,13 +467,15 @@ void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation,
}
void InFlightBackendIO::QueueOperation(BackendIO* operation) {
- if (operation->IsEntryOperation())
- return PostOperation(operation);
+ if (!operation->IsEntryOperation())
+ return QueueOperationToList(operation, &pending_ops_);
- if (pending_ops_.empty())
+ if (!queue_entry_ops_)
return PostOperation(operation);
- pending_ops_.push_back(operation);
+ CACHE_UMA(COUNTS_10000, "QueuedOperations", 0, pending_entry_ops_.size());
+
+ QueueOperationToList(operation, &pending_entry_ops_);
}
void InFlightBackendIO::PostOperation(BackendIO* operation) {
@@ -445,4 +484,18 @@ void InFlightBackendIO::PostOperation(BackendIO* operation) {
OnOperationPosted(operation);
}
+void InFlightBackendIO::PostQueuedOperation(OperationList* from_list) {
+ scoped_refptr<BackendIO> next_op = from_list->front();
+ from_list->pop_front();
+ PostOperation(next_op);
+}
+
+void InFlightBackendIO::QueueOperationToList(BackendIO* operation,
+ OperationList* list) {
+ if (list->empty())
+ return PostOperation(operation);
+
+ list->push_back(operation);
+}
+
} // namespace
diff --git a/net/disk_cache/in_flight_backend_io.h b/net/disk_cache/in_flight_backend_io.h
index 083c6fd..213c261 100644
--- a/net/disk_cache/in_flight_backend_io.h
+++ b/net/disk_cache/in_flight_backend_io.h
@@ -39,6 +39,9 @@ class BackendIO : public BackgroundIO {
void ReleaseEntry();
+ // Returns the time that has passed since the operation was created.
+ base::TimeDelta ElapsedTime() const;
+
// The operations we proxy:
void Init();
void OpenEntry(const std::string& key, Entry** entry);
@@ -124,6 +127,7 @@ class BackendIO : public BackgroundIO {
bool truncate_;
int64 offset64_;
int64* start_;
+ base::TimeTicks start_time_;
DISALLOW_COPY_AND_ASSIGN(BackendIO);
};
@@ -132,9 +136,8 @@ class BackendIO : public BackgroundIO {
class InFlightBackendIO : public InFlightIO {
public:
InFlightBackendIO(BackendImpl* backend,
- base::MessageLoopProxy* background_thread)
- : backend_(backend), background_thread_(background_thread) {}
- ~InFlightBackendIO() {}
+ base::MessageLoopProxy* background_thread);
+ ~InFlightBackendIO();
// The operations we proxy:
void Init(net::CompletionCallback* callback);
@@ -182,6 +185,10 @@ class InFlightBackendIO : public InFlightIO {
return background_thread_->BelongsToCurrentThread();
}
+ // Controls the queing of entry (async) operations.
+ void StartQueingOperations();
+ void StopQueingOperations();
+
protected:
virtual void OnOperationComplete(BackgroundIO* operation, bool cancel);
@@ -189,10 +196,14 @@ class InFlightBackendIO : public InFlightIO {
typedef std::list<scoped_refptr<BackendIO> > OperationList;
void QueueOperation(BackendIO* operation);
void PostOperation(BackendIO* operation);
+ void PostQueuedOperation(OperationList* from_list);
+ void QueueOperationToList(BackendIO* operation, OperationList* list);
BackendImpl* backend_;
scoped_refptr<base::MessageLoopProxy> background_thread_;
OperationList pending_ops_; // The list of operations to be posted.
+ OperationList pending_entry_ops_; // Entry (async) operations to be posted.
+ bool queue_entry_ops_; // True if we are queuing entry (async) operations.
DISALLOW_COPY_AND_ASSIGN(InFlightBackendIO);
};