Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/debug/trace_event_impl.h" | 5 #include "base/debug/trace_event_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/leak_annotations.h" | |
| 10 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
| 11 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 12 #include "base/format_macros.h" | 13 #include "base/format_macros.h" |
| 13 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 14 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
| 15 #include "base/process_util.h" | 16 #include "base/process_util.h" |
| 17 #include "base/stl_util.h" | |
| 16 #include "base/stringprintf.h" | 18 #include "base/stringprintf.h" |
| 17 #include "base/string_tokenizer.h" | 19 #include "base/string_tokenizer.h" |
| 20 #include "base/string_util.h" | |
| 21 #include "base/sys_info.h" | |
| 22 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | |
| 18 #include "base/threading/platform_thread.h" | 23 #include "base/threading/platform_thread.h" |
| 19 #include "base/threading/thread_local.h" | 24 #include "base/threading/thread_local.h" |
| 25 #include "base/time.h" | |
| 20 #include "base/utf_string_conversions.h" | 26 #include "base/utf_string_conversions.h" |
| 21 #include "base/stl_util.h" | |
| 22 #include "base/sys_info.h" | |
| 23 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | |
| 24 #include "base/time.h" | |
| 25 | 27 |
| 26 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
| 27 #include "base/debug/trace_event_win.h" | 29 #include "base/debug/trace_event_win.h" |
| 28 #endif | 30 #endif |
| 29 | 31 |
| 30 class DeleteTraceLogForTesting { | 32 class DeleteTraceLogForTesting { |
| 31 public: | 33 public: |
| 32 static void Delete() { | 34 static void Delete() { |
| 33 Singleton<base::debug::TraceLog, | 35 Singleton<base::debug::TraceLog, |
| 34 StaticMemorySingletonTraits<base::debug::TraceLog> >::OnExit(0); | 36 StaticMemorySingletonTraits<base::debug::TraceLog> >::OnExit(0); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 void TraceResultBuffer::Finish() { | 311 void TraceResultBuffer::Finish() { |
| 310 output_callback_.Run("]"); | 312 output_callback_.Run("]"); |
| 311 } | 313 } |
| 312 | 314 |
| 313 //////////////////////////////////////////////////////////////////////////////// | 315 //////////////////////////////////////////////////////////////////////////////// |
| 314 // | 316 // |
| 315 // TraceLog | 317 // TraceLog |
| 316 // | 318 // |
| 317 //////////////////////////////////////////////////////////////////////////////// | 319 //////////////////////////////////////////////////////////////////////////////// |
| 318 | 320 |
| 321 TraceLog::NotificationHelper::NotificationHelper(TraceLog* trace_log) | |
| 322 : trace_log_(trace_log) | |
| 323 , notification_(0) { | |
| 324 } | |
| 325 | |
| 326 TraceLog::NotificationHelper::~NotificationHelper() { | |
| 327 } | |
| 328 | |
| 329 void TraceLog::NotificationHelper::AddNotificationWhileLocked( | |
| 330 int notification) { | |
| 331 if (notification_ == 0) { | |
| 332 callback_copy_ = trace_log_->notification_callback_; | |
| 333 ++trace_log_->notification_thread_count_; | |
|
ccameron
2012/08/21 01:06:34
[RW-lock evangelism]: With a separate reader-write
| |
| 334 } | |
| 335 notification_ |= notification; | |
| 336 } | |
| 337 | |
| 338 void TraceLog::NotificationHelper::SendNotificationIfAny() { | |
| 339 if (notification_) { | |
|
ccameron
2012/08/21 01:06:34
[RW-lock evangelism]: With a separate reader-write
| |
| 340 callback_copy_.Run(notification_); | |
| 341 callback_copy_.Reset(); | |
| 342 | |
| 343 AutoLock lock(trace_log_->lock_); | |
| 344 --trace_log_->notification_thread_count_; | |
| 345 // Signal other waiters (if any) in case they are waiting for the | |
| 346 // callback object to be unreferenced. | |
| 347 if (trace_log_->notification_thread_count_ == 0) | |
| 348 trace_log_->notification_condition_.Signal(); | |
| 349 } | |
| 350 } | |
| 351 | |
| 319 // static | 352 // static |
| 320 TraceLog* TraceLog::GetInstance() { | 353 TraceLog* TraceLog::GetInstance() { |
| 321 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); | 354 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); |
| 322 } | 355 } |
| 323 | 356 |
| 324 TraceLog::TraceLog() | 357 TraceLog::TraceLog() |
| 325 : enabled_(false) | 358 : enabled_(false) |
| 326 , dispatching_to_observer_list_(false) { | 359 , notification_condition_(&lock_) |
| 360 , notification_thread_count_(0) | |
| 361 , dispatching_to_observer_list_(false) | |
| 362 , watch_category_(NULL) | |
| 363 , watch_count_(0) { | |
| 327 // Trace is enabled or disabled on one thread while other threads are | 364 // Trace is enabled or disabled on one thread while other threads are |
| 328 // accessing the enabled flag. We don't care whether edge-case events are | 365 // accessing the enabled flag. We don't care whether edge-case events are |
| 329 // traced or not, so we allow races on the enabled flag to keep the trace | 366 // traced or not, so we allow races on the enabled flag to keep the trace |
| 330 // macros fast. | 367 // macros fast. |
| 331 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 368 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
| 332 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), | 369 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), |
| 333 // "trace_event category enabled"); | 370 // "trace_event category enabled"); |
| 334 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { | 371 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { |
| 335 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], | 372 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], |
| 336 "trace_event category enabled"); | 373 "trace_event category enabled"); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 for (int i = 0; i < g_category_index; i++) { | 436 for (int i = 0; i < g_category_index; i++) { |
| 400 if (strcmp(g_categories[i], name) == 0) | 437 if (strcmp(g_categories[i], name) == 0) |
| 401 return &g_category_enabled[i]; | 438 return &g_category_enabled[i]; |
| 402 } | 439 } |
| 403 | 440 |
| 404 // Create a new category | 441 // Create a new category |
| 405 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << | 442 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << |
| 406 "must increase TRACE_EVENT_MAX_CATEGORIES"; | 443 "must increase TRACE_EVENT_MAX_CATEGORIES"; |
| 407 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { | 444 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { |
| 408 int new_index = g_category_index++; | 445 int new_index = g_category_index++; |
| 409 g_categories[new_index] = name; | 446 // Don't hold on to the name pointer, so that we can create categories with |
| 447 // strings not known at compile time (this is required by SetWatchEvent). | |
| 448 const char* new_name = base::strdup(name); | |
| 449 ANNOTATE_LEAKING_OBJECT_PTR(new_name); | |
| 450 g_categories[new_index] = new_name; | |
| 410 DCHECK(!g_category_enabled[new_index]); | 451 DCHECK(!g_category_enabled[new_index]); |
| 411 if (enabled_) { | 452 if (enabled_) { |
| 412 // Note that if both included and excluded_categories are empty, the else | 453 // Note that if both included and excluded_categories are empty, the else |
| 413 // clause below excludes nothing, thereby enabling this category. | 454 // clause below excludes nothing, thereby enabling this category. |
| 414 if (!included_categories_.empty()) | 455 if (!included_categories_.empty()) |
| 415 EnableMatchingCategory(new_index, included_categories_, 1); | 456 EnableMatchingCategory(new_index, included_categories_, 1); |
| 416 else | 457 else |
| 417 EnableMatchingCategory(new_index, excluded_categories_, 0); | 458 EnableMatchingCategory(new_index, excluded_categories_, 0); |
| 418 } else { | 459 } else { |
| 419 g_category_enabled[new_index] = 0; | 460 g_category_enabled[new_index] = 0; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 std::vector<std::string>* included_out, | 525 std::vector<std::string>* included_out, |
| 485 std::vector<std::string>* excluded_out) { | 526 std::vector<std::string>* excluded_out) { |
| 486 AutoLock lock(lock_); | 527 AutoLock lock(lock_); |
| 487 if (enabled_) { | 528 if (enabled_) { |
| 488 *included_out = included_categories_; | 529 *included_out = included_categories_; |
| 489 *excluded_out = excluded_categories_; | 530 *excluded_out = excluded_categories_; |
| 490 } | 531 } |
| 491 } | 532 } |
| 492 | 533 |
| 493 void TraceLog::SetDisabled() { | 534 void TraceLog::SetDisabled() { |
| 494 { | 535 AutoLock lock(lock_); |
| 495 AutoLock lock(lock_); | 536 if (!enabled_) |
| 496 if (!enabled_) | 537 return; |
| 497 return; | |
| 498 | 538 |
| 499 if (dispatching_to_observer_list_) { | 539 if (dispatching_to_observer_list_) { |
| 500 DLOG(ERROR) | 540 DLOG(ERROR) |
| 501 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 541 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 502 return; | 542 return; |
| 503 } | 543 } |
| 504 | 544 |
| 505 dispatching_to_observer_list_ = true; | 545 dispatching_to_observer_list_ = true; |
| 506 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, | 546 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, |
| 507 OnTraceLogWillDisable()); | 547 OnTraceLogWillDisable()); |
| 508 dispatching_to_observer_list_ = false; | 548 dispatching_to_observer_list_ = false; |
| 509 | 549 |
| 510 enabled_ = false; | 550 enabled_ = false; |
| 511 included_categories_.clear(); | 551 included_categories_.clear(); |
| 512 excluded_categories_.clear(); | 552 excluded_categories_.clear(); |
| 513 for (int i = 0; i < g_category_index; i++) | 553 watch_category_ = NULL; |
| 514 g_category_enabled[i] = 0; | 554 watch_event_name_ = ""; |
| 515 AddThreadNameMetadataEvents(); | 555 for (int i = 0; i < g_category_index; i++) |
| 516 AddClockSyncMetadataEvents(); | 556 g_category_enabled[i] = 0; |
| 517 } // release lock | 557 AddThreadNameMetadataEvents(); |
| 518 Flush(); | 558 AddClockSyncMetadataEvents(); |
| 519 } | 559 } |
| 520 | 560 |
| 521 void TraceLog::SetEnabled(bool enabled) { | 561 void TraceLog::SetEnabled(bool enabled) { |
| 522 if (enabled) | 562 if (enabled) |
| 523 SetEnabled(std::vector<std::string>(), std::vector<std::string>()); | 563 SetEnabled(std::vector<std::string>(), std::vector<std::string>()); |
| 524 else | 564 else |
| 525 SetDisabled(); | 565 SetDisabled(); |
| 526 } | 566 } |
| 527 | 567 |
| 528 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { | 568 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { |
| 529 enabled_state_observer_list_.AddObserver(listener); | 569 enabled_state_observer_list_.AddObserver(listener); |
| 530 } | 570 } |
| 531 | 571 |
| 532 void TraceLog::RemoveEnabledStateObserver( | 572 void TraceLog::RemoveEnabledStateObserver( |
| 533 EnabledStateChangedObserver* listener) { | 573 EnabledStateChangedObserver* listener) { |
| 534 enabled_state_observer_list_.RemoveObserver(listener); | 574 enabled_state_observer_list_.RemoveObserver(listener); |
| 535 } | 575 } |
| 536 | 576 |
| 537 float TraceLog::GetBufferPercentFull() const { | 577 float TraceLog::GetBufferPercentFull() const { |
| 538 return (float)((double)logged_events_.size()/(double)kTraceEventBufferSize); | 578 return (float)((double)logged_events_.size()/(double)kTraceEventBufferSize); |
| 539 } | 579 } |
| 540 | 580 |
| 541 void TraceLog::SetOutputCallback(const TraceLog::OutputCallback& cb) { | 581 void TraceLog::SetNotificationCallback( |
| 582 const TraceLog::NotificationCallback& cb) { | |
| 542 AutoLock lock(lock_); | 583 AutoLock lock(lock_); |
|
ccameron
2012/08/21 01:06:34
[RW-lock evangelism]: With a separate reader-write
| |
| 543 output_callback_ = cb; | 584 // Wait until other threads are done using the callback. |
| 585 while (notification_thread_count_ > 0) | |
| 586 notification_condition_.Wait(); | |
| 587 notification_callback_ = cb; | |
| 544 } | 588 } |
| 545 | 589 |
| 546 void TraceLog::SetBufferFullCallback(const TraceLog::BufferFullCallback& cb) { | 590 void TraceLog::Flush(const TraceLog::OutputCallback& cb) { |
| 547 AutoLock lock(lock_); | |
| 548 buffer_full_callback_ = cb; | |
| 549 } | |
| 550 | |
| 551 void TraceLog::Flush() { | |
| 552 std::vector<TraceEvent> previous_logged_events; | 591 std::vector<TraceEvent> previous_logged_events; |
| 553 OutputCallback output_callback_copy; | |
| 554 { | 592 { |
| 555 AutoLock lock(lock_); | 593 AutoLock lock(lock_); |
| 556 previous_logged_events.swap(logged_events_); | 594 previous_logged_events.swap(logged_events_); |
| 557 output_callback_copy = output_callback_; | |
| 558 } // release lock | 595 } // release lock |
| 559 | 596 |
| 560 if (output_callback_copy.is_null()) | |
| 561 return; | |
| 562 | |
| 563 for (size_t i = 0; | 597 for (size_t i = 0; |
| 564 i < previous_logged_events.size(); | 598 i < previous_logged_events.size(); |
| 565 i += kTraceEventBatchSize) { | 599 i += kTraceEventBatchSize) { |
| 566 scoped_refptr<RefCountedString> json_events_str_ptr = | 600 scoped_refptr<RefCountedString> json_events_str_ptr = |
| 567 new RefCountedString(); | 601 new RefCountedString(); |
| 568 TraceEvent::AppendEventsAsJSON(previous_logged_events, | 602 TraceEvent::AppendEventsAsJSON(previous_logged_events, |
| 569 i, | 603 i, |
| 570 kTraceEventBatchSize, | 604 kTraceEventBatchSize, |
| 571 &(json_events_str_ptr->data())); | 605 &(json_events_str_ptr->data())); |
| 572 output_callback_copy.Run(json_events_str_ptr); | 606 cb.Run(json_events_str_ptr); |
| 573 } | 607 } |
| 574 } | 608 } |
| 575 | 609 |
| 576 int TraceLog::AddTraceEvent(char phase, | 610 int TraceLog::AddTraceEvent(char phase, |
| 577 const unsigned char* category_enabled, | 611 const unsigned char* category_enabled, |
| 578 const char* name, | 612 const char* name, |
| 579 unsigned long long id, | 613 unsigned long long id, |
| 580 int num_args, | 614 int num_args, |
| 581 const char** arg_names, | 615 const char** arg_names, |
| 582 const unsigned char* arg_types, | 616 const unsigned char* arg_types, |
| 583 const unsigned long long* arg_values, | 617 const unsigned long long* arg_values, |
| 584 int threshold_begin_id, | 618 int threshold_begin_id, |
| 585 long long threshold, | 619 long long threshold, |
| 586 unsigned char flags) { | 620 unsigned char flags) { |
| 587 DCHECK(name); | 621 DCHECK(name); |
| 588 TimeTicks now = TimeTicks::NowFromSystemTraceTime(); | 622 TimeTicks now = TimeTicks::NowFromSystemTraceTime(); |
| 589 BufferFullCallback buffer_full_callback_copy; | 623 NotificationHelper notifier(this); |
| 590 int ret_begin_id = -1; | 624 int ret_begin_id = -1; |
| 591 { | 625 { |
| 592 AutoLock lock(lock_); | 626 AutoLock lock(lock_); |
| 593 if (!*category_enabled) | 627 if (!*category_enabled) |
| 594 return -1; | 628 return -1; |
| 595 if (logged_events_.size() >= kTraceEventBufferSize) | 629 if (logged_events_.size() >= kTraceEventBufferSize) |
| 596 return -1; | 630 return -1; |
| 597 | 631 |
| 598 int thread_id = static_cast<int>(PlatformThread::CurrentId()); | 632 int thread_id = static_cast<int>(PlatformThread::CurrentId()); |
| 599 | 633 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 645 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) | 679 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) |
| 646 id ^= process_id_hash_; | 680 id ^= process_id_hash_; |
| 647 | 681 |
| 648 ret_begin_id = static_cast<int>(logged_events_.size()); | 682 ret_begin_id = static_cast<int>(logged_events_.size()); |
| 649 logged_events_.push_back( | 683 logged_events_.push_back( |
| 650 TraceEvent(thread_id, | 684 TraceEvent(thread_id, |
| 651 now, phase, category_enabled, name, id, | 685 now, phase, category_enabled, name, id, |
| 652 num_args, arg_names, arg_types, arg_values, | 686 num_args, arg_names, arg_types, arg_values, |
| 653 flags)); | 687 flags)); |
| 654 | 688 |
| 655 if (logged_events_.size() == kTraceEventBufferSize) { | 689 if (logged_events_.size() == kTraceEventBufferSize) |
| 656 buffer_full_callback_copy = buffer_full_callback_; | 690 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); |
| 691 | |
| 692 if (watch_category_ == category_enabled && watch_event_name_ == name && | |
| 693 --watch_count_ == 0) { | |
| 694 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); | |
| 695 // Clear watch state now so that only the one notification occurs. | |
| 696 watch_category_ = NULL; | |
| 697 watch_event_name_ = ""; | |
| 657 } | 698 } |
| 658 } // release lock | 699 } // release lock |
| 659 | 700 |
| 660 if (!buffer_full_callback_copy.is_null()) | 701 notifier.SendNotificationIfAny(); |
| 661 buffer_full_callback_copy.Run(); | |
| 662 | 702 |
| 663 return ret_begin_id; | 703 return ret_begin_id; |
| 664 } | 704 } |
| 665 | 705 |
| 666 void TraceLog::AddTraceEventEtw(char phase, | 706 void TraceLog::AddTraceEventEtw(char phase, |
| 667 const char* name, | 707 const char* name, |
| 668 const void* id, | 708 const void* id, |
| 669 const char* extra) { | 709 const char* extra) { |
| 670 #if defined(OS_WIN) | 710 #if defined(OS_WIN) |
| 671 TraceEventETWProvider::Trace(name, phase, id, extra); | 711 TraceEventETWProvider::Trace(name, phase, id, extra); |
| 672 #endif | 712 #endif |
| 673 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, | 713 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, |
| 674 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); | 714 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); |
| 675 } | 715 } |
| 676 | 716 |
| 677 void TraceLog::AddTraceEventEtw(char phase, | 717 void TraceLog::AddTraceEventEtw(char phase, |
| 678 const char* name, | 718 const char* name, |
| 679 const void* id, | 719 const void* id, |
| 680 const std::string& extra) | 720 const std::string& extra) |
| 681 { | 721 { |
| 682 #if defined(OS_WIN) | 722 #if defined(OS_WIN) |
| 683 TraceEventETWProvider::Trace(name, phase, id, extra); | 723 TraceEventETWProvider::Trace(name, phase, id, extra); |
| 684 #endif | 724 #endif |
| 685 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, | 725 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, |
| 686 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); | 726 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); |
| 687 } | 727 } |
| 688 | 728 |
| 729 void TraceLog::SetWatchEvent(const char* category_name, | |
| 730 const char* event_name, | |
| 731 int num_occurrences) { | |
| 732 DCHECK(num_occurrences > 0); | |
| 733 const unsigned char* category = GetCategoryEnabled(category_name); | |
| 734 NotificationHelper notifier(this); | |
| 735 { | |
| 736 AutoLock lock(lock_); | |
| 737 watch_category_ = category; | |
| 738 watch_event_name_ = event_name; | |
| 739 watch_count_ = num_occurrences; | |
| 740 | |
| 741 // First, search existing events for watch event because we want to catch it | |
| 742 // even if it has already occurred. | |
| 743 for (size_t i = 0u; i < logged_events_.size(); ++i) { | |
| 744 if (category == logged_events_[i].category_enabled() && | |
| 745 strcmp(event_name, logged_events_[i].name()) == 0 && | |
| 746 --watch_count_ == 0) { | |
| 747 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); | |
| 748 // Clear watch state now so that only the one notification occurs. | |
| 749 watch_category_ = NULL; | |
| 750 watch_event_name_ = ""; | |
| 751 break; | |
| 752 } | |
| 753 } | |
| 754 } // release lock | |
| 755 | |
| 756 notifier.SendNotificationIfAny(); | |
| 757 } | |
| 758 | |
| 759 void TraceLog::CancelWatchEvent() { | |
| 760 AutoLock lock(lock_); | |
| 761 watch_category_ = NULL; | |
| 762 watch_event_name_ = ""; | |
| 763 watch_count_ = 0; | |
| 764 } | |
| 765 | |
| 689 void TraceLog::AddClockSyncMetadataEvents() { | 766 void TraceLog::AddClockSyncMetadataEvents() { |
| 690 #if defined(OS_ANDROID) | 767 #if defined(OS_ANDROID) |
| 691 // Since Android does not support sched_setaffinity, we cannot establish clock | 768 // Since Android does not support sched_setaffinity, we cannot establish clock |
| 692 // sync unless the scheduler clock is set to global. If the trace_clock file | 769 // sync unless the scheduler clock is set to global. If the trace_clock file |
| 693 // can't be read, we will assume the kernel doesn't support tracing and do | 770 // can't be read, we will assume the kernel doesn't support tracing and do |
| 694 // nothing. | 771 // nothing. |
| 695 std::string clock_mode; | 772 std::string clock_mode; |
| 696 if (!file_util::ReadFileToString( | 773 if (!file_util::ReadFileToString( |
| 697 FilePath("/sys/kernel/debug/tracing/trace_clock"), | 774 FilePath("/sys/kernel/debug/tracing/trace_clock"), |
| 698 &clock_mode)) | 775 &clock_mode)) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 760 // Create a FNV hash from the process ID for XORing. | 837 // Create a FNV hash from the process ID for XORing. |
| 761 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. | 838 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. |
| 762 unsigned long long offset_basis = 14695981039346656037ull; | 839 unsigned long long offset_basis = 14695981039346656037ull; |
| 763 unsigned long long fnv_prime = 1099511628211ull; | 840 unsigned long long fnv_prime = 1099511628211ull; |
| 764 unsigned long long pid = static_cast<unsigned long long>(process_id_); | 841 unsigned long long pid = static_cast<unsigned long long>(process_id_); |
| 765 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; | 842 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; |
| 766 } | 843 } |
| 767 | 844 |
| 768 } // namespace debug | 845 } // namespace debug |
| 769 } // namespace base | 846 } // namespace base |
| OLD | NEW |