OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync/syncable/syncable.h" | 5 #include "chrome/browser/sync/syncable/syncable.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 #include <functional> | 9 #include <functional> |
10 #include <iomanip> | 10 #include <iomanip> |
11 #include <iterator> | 11 #include <iterator> |
12 #include <limits> | 12 #include <limits> |
13 #include <set> | 13 #include <set> |
14 #include <string> | 14 #include <string> |
15 | 15 |
16 #include "base/debug/trace_event.h" | |
16 #include "base/compiler_specific.h" | 17 #include "base/compiler_specific.h" |
17 #include "base/file_util.h" | 18 #include "base/file_util.h" |
18 #include "base/hash_tables.h" | 19 #include "base/hash_tables.h" |
19 #include "base/location.h" | 20 #include "base/location.h" |
20 #include "base/logging.h" | 21 #include "base/logging.h" |
21 #include "base/memory/scoped_ptr.h" | 22 #include "base/memory/scoped_ptr.h" |
22 #include "base/perftimer.h" | 23 #include "base/perftimer.h" |
23 #include "base/stl_util.h" | 24 #include "base/stl_util.h" |
24 #include "base/string_number_conversions.h" | 25 #include "base/string_number_conversions.h" |
25 #include "base/string_util.h" | 26 #include "base/string_util.h" |
(...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1121 // ScopedKernelLock | 1122 // ScopedKernelLock |
1122 | 1123 |
1123 ScopedKernelLock::ScopedKernelLock(const Directory* dir) | 1124 ScopedKernelLock::ScopedKernelLock(const Directory* dir) |
1124 : scoped_lock_(dir->kernel_->mutex), dir_(const_cast<Directory*>(dir)) { | 1125 : scoped_lock_(dir->kernel_->mutex), dir_(const_cast<Directory*>(dir)) { |
1125 } | 1126 } |
1126 | 1127 |
1127 /////////////////////////////////////////////////////////////////////////// | 1128 /////////////////////////////////////////////////////////////////////////// |
1128 // Transactions | 1129 // Transactions |
1129 | 1130 |
1130 void BaseTransaction::Lock() { | 1131 void BaseTransaction::Lock() { |
1131 base::TimeTicks start_time = base::TimeTicks::Now(); | 1132 TRACE_EVENT2("sync_lock_contention", "AcquireLock", |
1133 "src_file", from_here_.file_name(), | |
1134 "src_func", from_here_.function_name()); | |
1132 | 1135 |
1133 dirkernel_->transaction_mutex.Acquire(); | 1136 dirkernel_->transaction_mutex.Acquire(); |
1134 | |
1135 time_acquired_ = base::TimeTicks::Now(); | |
1136 const base::TimeDelta elapsed = time_acquired_ - start_time; | |
1137 VLOG_LOC(from_here_, 2) | |
1138 << name_ << " transaction waited " | |
1139 << elapsed.InSecondsF() << " seconds."; | |
1140 } | 1137 } |
1141 | 1138 |
1142 void BaseTransaction::Unlock() { | 1139 void BaseTransaction::Unlock() { |
1143 dirkernel_->transaction_mutex.Release(); | 1140 dirkernel_->transaction_mutex.Release(); |
1144 const base::TimeDelta elapsed = base::TimeTicks::Now() - time_acquired_; | |
1145 VLOG_LOC(from_here_, 2) | |
1146 << name_ << " transaction completed in " << elapsed.InSecondsF() | |
1147 << " seconds."; | |
1148 } | 1141 } |
1149 | 1142 |
1150 BaseTransaction::BaseTransaction(const tracked_objects::Location& from_here, | 1143 BaseTransaction::BaseTransaction(const tracked_objects::Location& from_here, |
1151 const char* name, | 1144 const char* name, |
1152 WriterTag writer, | 1145 WriterTag writer, |
1153 Directory* directory) | 1146 Directory* directory) |
1154 : from_here_(from_here), name_(name), writer_(writer), | 1147 : from_here_(from_here), name_(name), writer_(writer), |
1155 directory_(directory), dirkernel_(directory->kernel_) { | 1148 directory_(directory), dirkernel_(directory->kernel_) { |
1156 dirkernel_->observers->Notify( | 1149 dirkernel_->observers->Notify( |
1157 &TransactionObserver::OnTransactionStart, from_here_, writer_); | 1150 &TransactionObserver::OnTransactionStart, from_here_, writer_); |
rlarocque
2011/11/15 19:45:07
I'm tempted to remove the OnTransactionStart and O
| |
1158 } | 1151 } |
1159 | 1152 |
1160 BaseTransaction::~BaseTransaction() { | 1153 BaseTransaction::~BaseTransaction() { |
1161 dirkernel_->observers->Notify( | 1154 dirkernel_->observers->Notify( |
1162 &TransactionObserver::OnTransactionEnd, from_here_, writer_); | 1155 &TransactionObserver::OnTransactionEnd, from_here_, writer_); |
1163 } | 1156 } |
1164 | 1157 |
1165 ReadTransaction::ReadTransaction(const tracked_objects::Location& location, | 1158 ReadTransaction::ReadTransaction(const tracked_objects::Location& location, |
1166 Directory* directory) | 1159 Directory* directory) |
1167 : BaseTransaction(location, "Read", INVALID, directory) { | 1160 : BaseTransaction(location, "Read", INVALID, directory) { |
1161 TRACE_EVENT_BEGIN2("sync", "ReadTransaction", | |
1162 "src_file", from_here_.file_name(), | |
1163 "src_func", from_here_.function_name()); | |
1168 Lock(); | 1164 Lock(); |
1169 } | 1165 } |
1170 | 1166 |
1171 ReadTransaction::ReadTransaction(const tracked_objects::Location& location, | 1167 ReadTransaction::ReadTransaction(const tracked_objects::Location& location, |
1172 const ScopedDirLookup& scoped_dir) | 1168 const ScopedDirLookup& scoped_dir) |
1173 : BaseTransaction(location, "Read", INVALID, scoped_dir.operator->()) { | 1169 : BaseTransaction(location, "Read", INVALID, scoped_dir.operator->()) { |
1170 TRACE_EVENT_BEGIN2("sync", "ReadTransaction", | |
1171 "src_file", from_here_.file_name(), | |
1172 "src_func", from_here_.function_name()); | |
1174 Lock(); | 1173 Lock(); |
1175 } | 1174 } |
1176 | 1175 |
1177 ReadTransaction::~ReadTransaction() { | 1176 ReadTransaction::~ReadTransaction() { |
1178 Unlock(); | 1177 Unlock(); |
1178 TRACE_EVENT_END2("sync", "ReadTransaction", | |
1179 "src_file", from_here_.file_name(), | |
1180 "src_func", from_here_.function_name()); | |
1179 } | 1181 } |
1180 | 1182 |
1181 WriteTransaction::WriteTransaction(const tracked_objects::Location& location, | 1183 WriteTransaction::WriteTransaction(const tracked_objects::Location& location, |
1182 WriterTag writer, Directory* directory) | 1184 WriterTag writer, Directory* directory) |
1183 : BaseTransaction(location, "Write", writer, directory) { | 1185 : BaseTransaction(location, "Write", writer, directory) { |
1186 TRACE_EVENT_BEGIN2("sync", "WriteTransaction", | |
1187 "src_file", from_here_.file_name(), | |
1188 "src_func", from_here_.function_name()); | |
1184 Lock(); | 1189 Lock(); |
1185 } | 1190 } |
1186 | 1191 |
1187 WriteTransaction::WriteTransaction(const tracked_objects::Location& location, | 1192 WriteTransaction::WriteTransaction(const tracked_objects::Location& location, |
1188 WriterTag writer, | 1193 WriterTag writer, |
1189 const ScopedDirLookup& scoped_dir) | 1194 const ScopedDirLookup& scoped_dir) |
1190 : BaseTransaction(location, "Write", writer, scoped_dir.operator->()) { | 1195 : BaseTransaction(location, "Write", writer, scoped_dir.operator->()) { |
1196 TRACE_EVENT_BEGIN2("sync", "WriteTransaction", | |
1197 "src_file", from_here_.file_name(), | |
1198 "src_func", from_here_.function_name()); | |
1191 Lock(); | 1199 Lock(); |
1192 } | 1200 } |
1193 | 1201 |
1194 void WriteTransaction::SaveOriginal(const EntryKernel* entry) { | 1202 void WriteTransaction::SaveOriginal(const EntryKernel* entry) { |
1195 if (!entry) { | 1203 if (!entry) { |
1196 return; | 1204 return; |
1197 } | 1205 } |
1198 // Insert only if it's not already there. | 1206 // Insert only if it's not already there. |
1199 const int64 handle = entry->ref(META_HANDLE); | 1207 const int64 handle = entry->ref(META_HANDLE); |
1200 EntryKernelMutationMap::iterator it = mutations_.lower_bound(handle); | 1208 EntryKernelMutationMap::iterator it = mutations_.lower_bound(handle); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1284 | 1292 |
1285 if (OFF != kInvariantCheckLevel) { | 1293 if (OFF != kInvariantCheckLevel) { |
1286 const bool full_scan = (FULL_DB_VERIFICATION == kInvariantCheckLevel); | 1294 const bool full_scan = (FULL_DB_VERIFICATION == kInvariantCheckLevel); |
1287 if (full_scan) | 1295 if (full_scan) |
1288 directory()->CheckTreeInvariants(this, full_scan); | 1296 directory()->CheckTreeInvariants(this, full_scan); |
1289 else | 1297 else |
1290 directory()->CheckTreeInvariants(this, mutations.Get()); | 1298 directory()->CheckTreeInvariants(this, mutations.Get()); |
1291 } | 1299 } |
1292 | 1300 |
1293 UnlockAndNotify(mutations); | 1301 UnlockAndNotify(mutations); |
1302 TRACE_EVENT_END2("sync", "WriteTransaction", | |
1303 "src_file", from_here_.file_name(), | |
1304 "src_func", from_here_.function_name()); | |
1294 } | 1305 } |
1295 | 1306 |
1296 /////////////////////////////////////////////////////////////////////////// | 1307 /////////////////////////////////////////////////////////////////////////// |
1297 // Entry | 1308 // Entry |
1298 | 1309 |
1299 Entry::Entry(BaseTransaction* trans, GetById, const Id& id) | 1310 Entry::Entry(BaseTransaction* trans, GetById, const Id& id) |
1300 : basetrans_(trans) { | 1311 : basetrans_(trans) { |
1301 kernel_ = trans->directory()->GetEntryById(id); | 1312 kernel_ = trans->directory()->GetEntryById(id); |
1302 } | 1313 } |
1303 | 1314 |
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2019 if (entry->ref(NEXT_ID).IsRoot() || | 2030 if (entry->ref(NEXT_ID).IsRoot() || |
2020 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { | 2031 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { |
2021 return entry; | 2032 return entry; |
2022 } | 2033 } |
2023 } | 2034 } |
2024 // There were no children in the linked list. | 2035 // There were no children in the linked list. |
2025 return NULL; | 2036 return NULL; |
2026 } | 2037 } |
2027 | 2038 |
2028 } // namespace syncable | 2039 } // namespace syncable |
OLD | NEW |