Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/stats_table.h" | 5 #include "base/stats_table.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/platform_thread.h" | 8 #include "base/platform_thread.h" |
| 9 #include "base/process_util.h" | |
| 9 #include "base/shared_memory.h" | 10 #include "base/shared_memory.h" |
| 10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 11 #include "base/thread_local_storage.h" | 12 #include "base/thread_local_storage.h" |
| 12 | 13 |
| 13 #if defined(OS_POSIX) | 14 #if defined(OS_POSIX) |
| 14 #include "errno.h" | 15 #include "errno.h" |
| 15 #endif | 16 #endif |
| 16 | 17 |
| 17 // The StatsTable uses a shared memory segment that is laid out as follows | 18 // The StatsTable uses a shared memory segment that is laid out as follows |
| 18 // | 19 // |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 // StatsTable. This is used so that we can properly cleanup when the | 85 // StatsTable. This is used so that we can properly cleanup when the |
| 85 // thread exits and return the table slot. | 86 // thread exits and return the table slot. |
| 86 // | 87 // |
| 87 // Each thread that calls RegisterThread in the StatsTable will have | 88 // Each thread that calls RegisterThread in the StatsTable will have |
| 88 // a StatsTableTLSData stored in its TLS. | 89 // a StatsTableTLSData stored in its TLS. |
| 89 struct StatsTableTLSData { | 90 struct StatsTableTLSData { |
| 90 StatsTable* table; | 91 StatsTable* table; |
| 91 int slot; | 92 int slot; |
| 92 }; | 93 }; |
| 93 | 94 |
| 94 // The SlotReturnFunction is called at thread exit for each thread | |
| 95 // which used the StatsTable. | |
| 96 static void SlotReturnFunction(void* data) { | |
| 97 StatsTableTLSData* tls_data = static_cast<StatsTableTLSData*>(data); | |
| 98 if (tls_data) { | |
| 99 DCHECK(tls_data->table); | |
| 100 tls_data->table->UnregisterThread(); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 } // namespace | 95 } // namespace |
| 105 | 96 |
| 106 // The StatsTablePrivate maintains convenience pointers into the | 97 // The StatsTablePrivate maintains convenience pointers into the |
| 107 // shared memory segment. Use this class to keep the data structure | 98 // shared memory segment. Use this class to keep the data structure |
| 108 // clean and accessible. | 99 // clean and accessible. |
| 109 class StatsTablePrivate { | 100 class StatsTablePrivate { |
| 110 public: | 101 public: |
| 111 // Various header information contained in the memory mapped segment. | 102 // Various header information contained in the memory mapped segment. |
| 112 struct TableHeader { | 103 struct TableHeader { |
| 113 int version; | 104 int version; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 | 297 |
| 307 DCHECK(impl_); | 298 DCHECK(impl_); |
| 308 | 299 |
| 309 // We have space, so consume a column in the table. | 300 // We have space, so consume a column in the table. |
| 310 std::wstring thread_name = name; | 301 std::wstring thread_name = name; |
| 311 if (name.empty()) | 302 if (name.empty()) |
| 312 thread_name = kUnknownName; | 303 thread_name = kUnknownName; |
| 313 base::wcslcpy(impl_->thread_name(slot), thread_name.c_str(), | 304 base::wcslcpy(impl_->thread_name(slot), thread_name.c_str(), |
| 314 kMaxThreadNameLength); | 305 kMaxThreadNameLength); |
| 315 *(impl_->thread_tid(slot)) = PlatformThread::CurrentId(); | 306 *(impl_->thread_tid(slot)) = PlatformThread::CurrentId(); |
| 316 // TODO(pinkerton): these should go into process_utils when it's ported | 307 *(impl_->thread_pid(slot)) = process_util::GetCurrentProcId(); |
| 317 #if defined(OS_WIN) | |
| 318 *(impl_->thread_pid(slot)) = GetCurrentProcessId(); | |
| 319 #elif defined(OS_POSIX) | |
| 320 *(impl_->thread_pid(slot)) = getpid(); | |
| 321 #endif | |
| 322 } | 308 } |
| 323 | 309 |
| 324 // Set our thread local storage. | 310 // Set our thread local storage. |
| 325 StatsTableTLSData* data = new StatsTableTLSData; | 311 StatsTableTLSData* data = new StatsTableTLSData; |
| 326 data->table = this; | 312 data->table = this; |
| 327 data->slot = slot; | 313 data->slot = slot; |
| 328 tls_index_.Set(data); | 314 tls_index_.Set(data); |
| 329 return slot; | 315 return slot; |
| 330 } | 316 } |
| 331 | 317 |
| 332 StatsTableTLSData* StatsTable::GetTLSData() const { | 318 StatsTableTLSData* StatsTable::GetTLSData() const { |
| 333 StatsTableTLSData* data = | 319 StatsTableTLSData* data = |
| 334 static_cast<StatsTableTLSData*>(tls_index_.Get()); | 320 static_cast<StatsTableTLSData*>(tls_index_.Get()); |
| 335 if (!data) | 321 if (!data) |
| 336 return NULL; | 322 return NULL; |
| 337 | 323 |
| 338 DCHECK(data->slot); | 324 DCHECK(data->slot); |
| 339 DCHECK_EQ(data->table, this); | 325 DCHECK_EQ(data->table, this); |
| 340 return data; | 326 return data; |
| 341 } | 327 } |
| 342 | 328 |
| 343 void StatsTable::UnregisterThread() { | 329 void StatsTable::UnregisterThread() { |
| 344 StatsTableTLSData* data = GetTLSData(); | 330 UnregisterThread(GetTLSData()); |
| 331 } | |
| 332 | |
| 333 void StatsTable::UnregisterThread(StatsTableTLSData* data) { | |
| 345 if (!data) | 334 if (!data) |
| 346 return; | 335 return; |
| 347 DCHECK(impl_); | 336 DCHECK(impl_); |
| 348 | 337 |
| 349 // Mark the slot free by zeroing out the thread name. | 338 // Mark the slot free by zeroing out the thread name. |
| 350 wchar_t* name = impl_->thread_name(data->slot); | 339 wchar_t* name = impl_->thread_name(data->slot); |
| 351 *name = L'\0'; | 340 *name = L'\0'; |
| 352 | 341 |
| 353 // Remove the calling thread's TLS so that it cannot use the slot. | 342 // Remove the calling thread's TLS so that it cannot use the slot. |
| 354 tls_index_.Set(NULL); | 343 tls_index_.Set(NULL); |
| 355 delete data; | 344 delete data; |
| 356 } | 345 } |
| 357 | 346 |
|
Dean McNamee
2008/10/31 19:20:37
Is this because you can no longer access the TLS k
| |
| 347 void StatsTable::SlotReturnFunction(void* data) { | |
| 348 StatsTableTLSData* tls_data = static_cast<StatsTableTLSData*>(data); | |
| 349 if (tls_data) { | |
| 350 DCHECK(tls_data->table); | |
| 351 tls_data->table->UnregisterThread(tls_data); | |
| 352 } | |
| 353 } | |
| 354 | |
| 358 int StatsTable::CountThreadsRegistered() const { | 355 int StatsTable::CountThreadsRegistered() const { |
| 359 if (!impl_) | 356 if (!impl_) |
| 360 return 0; | 357 return 0; |
| 361 | 358 |
| 362 // Loop through the shared memory and count the threads that are active. | 359 // Loop through the shared memory and count the threads that are active. |
| 363 // We intentionally do not lock the table during the operation. | 360 // We intentionally do not lock the table during the operation. |
| 364 int count = 0; | 361 int count = 0; |
| 365 for (int index = 1; index <= impl_->max_threads(); index++) { | 362 for (int index = 1; index <= impl_->max_threads(); index++) { |
| 366 wchar_t* name = impl_->thread_name(index); | 363 wchar_t* name = impl_->thread_name(index); |
| 367 if (*name != L'\0') | 364 if (*name != L'\0') |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 return NULL; | 546 return NULL; |
| 550 | 547 |
| 551 // Find the counter id for the counter. | 548 // Find the counter id for the counter. |
| 552 std::wstring str_name(name); | 549 std::wstring str_name(name); |
| 553 int counter = table->FindCounter(str_name); | 550 int counter = table->FindCounter(str_name); |
| 554 | 551 |
| 555 // Now we can find the location in the table. | 552 // Now we can find the location in the table. |
| 556 return table->GetLocation(counter, slot); | 553 return table->GetLocation(counter, slot); |
| 557 } | 554 } |
| 558 | 555 |
| OLD | NEW |