Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(503)

Side by Side Diff: base/stats_table.cc

Issue 8751: Port last remaining test case in base/stats_table_unittest.cc, and... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698