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

Side by Side Diff: src/base/platform/time.cc

Issue 1304873011: Fix CPU profiler deadlock on Windows + AMD CPU. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: use unsigned types Created 5 years, 3 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project 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 "src/base/platform/time.h" 5 #include "src/base/platform/time.h"
6 6
7 #if V8_OS_POSIX 7 #if V8_OS_POSIX
8 #include <fcntl.h> // for O_RDONLY 8 #include <fcntl.h> // for O_RDONLY
9 #include <sys/time.h> 9 #include <sys/time.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 #endif 11 #endif
12 #if V8_OS_MACOSX 12 #if V8_OS_MACOSX
13 #include <mach/mach_time.h> 13 #include <mach/mach_time.h>
14 #endif 14 #endif
15 15
16 #include <cstring> 16 #include <cstring>
17 #include <ostream> 17 #include <ostream>
18 18
19 #if V8_OS_WIN 19 #if V8_OS_WIN
20 #include "src/base/atomicops.h"
20 #include "src/base/lazy-instance.h" 21 #include "src/base/lazy-instance.h"
21 #include "src/base/win32-headers.h" 22 #include "src/base/win32-headers.h"
22 #endif 23 #endif
23 #include "src/base/cpu.h" 24 #include "src/base/cpu.h"
24 #include "src/base/logging.h" 25 #include "src/base/logging.h"
25 #include "src/base/platform/platform.h" 26 #include "src/base/platform/platform.h"
26 27
27 namespace v8 { 28 namespace v8 {
28 namespace base { 29 namespace base {
29 30
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 428
428 bool IsHighResolution() override { return true; } 429 bool IsHighResolution() override { return true; }
429 430
430 private: 431 private:
431 int64_t ticks_per_second_; 432 int64_t ticks_per_second_;
432 }; 433 };
433 434
434 435
435 class RolloverProtectedTickClock final : public TickClock { 436 class RolloverProtectedTickClock final : public TickClock {
436 public: 437 public:
437 // We initialize rollover_ms_ to 1 to ensure that we will never 438 RolloverProtectedTickClock() : rollover_(0) {}
438 // return 0 from TimeTicks::HighResolutionNow() and TimeTicks::Now() below.
439 RolloverProtectedTickClock() : last_seen_now_(0), rollover_ms_(1) {}
440 virtual ~RolloverProtectedTickClock() {} 439 virtual ~RolloverProtectedTickClock() {}
441 440
442 int64_t Now() override { 441 int64_t Now() override {
443 LockGuard<Mutex> lock_guard(&mutex_);
444 // We use timeGetTime() to implement TimeTicks::Now(), which rolls over 442 // We use timeGetTime() to implement TimeTicks::Now(), which rolls over
445 // every ~49.7 days. We try to track rollover ourselves, which works if 443 // every ~49.7 days. We try to track rollover ourselves, which works if
446 // TimeTicks::Now() is called at least every 49 days. 444 // TimeTicks::Now() is called at least every 24 days.
447 // Note that we do not use GetTickCount() here, since timeGetTime() gives 445 // Note that we do not use GetTickCount() here, since timeGetTime() gives
448 // more predictable delta values, as described here: 446 // more predictable delta values, as described here:
449 // http://blogs.msdn.com/b/larryosterman/archive/2009/09/02/what-s-the-diffe rence-between-gettickcount-and-timegettime.aspx 447 // http://blogs.msdn.com/b/larryosterman/archive/2009/09/02/what-s-the-diffe rence-between-gettickcount-and-timegettime.aspx
450 // timeGetTime() provides 1ms granularity when combined with 448 // timeGetTime() provides 1ms granularity when combined with
451 // timeBeginPeriod(). If the host application for V8 wants fast timers, it 449 // timeBeginPeriod(). If the host application for V8 wants fast timers, it
452 // can use timeBeginPeriod() to increase the resolution. 450 // can use timeBeginPeriod() to increase the resolution.
453 DWORD now = timeGetTime(); 451 // We use a lock-free version because the sampler thread calls it
454 if (now < last_seen_now_) { 452 // while having the rest of the world stopped, that could cause a deadlock.
455 rollover_ms_ += V8_INT64_C(0x100000000); // ~49.7 days. 453 base::Atomic32 rollover = base::Acquire_Load(&rollover_);
454 uint32_t now = static_cast<uint32_t>(timeGetTime());
455 if ((now >> 31) != static_cast<uint32_t>(rollover & 1)) {
456 base::Release_CompareAndSwap(&rollover_, rollover, rollover + 1);
457 ++rollover;
456 } 458 }
457 last_seen_now_ = now; 459 uint64_t ms = (static_cast<uint64_t>(rollover) << 31) | now;
458 return (now + rollover_ms_) * Time::kMicrosecondsPerMillisecond; 460 return static_cast<int64_t>(ms * Time::kMicrosecondsPerMillisecond);
459 } 461 }
460 462
461 bool IsHighResolution() override { return false; } 463 bool IsHighResolution() override { return false; }
462 464
463 private: 465 private:
464 Mutex mutex_; 466 base::Atomic32 rollover_;
465 DWORD last_seen_now_;
466 int64_t rollover_ms_;
467 }; 467 };
468 468
469 469
470 static LazyStaticInstance<RolloverProtectedTickClock, 470 static LazyStaticInstance<RolloverProtectedTickClock,
471 DefaultConstructTrait<RolloverProtectedTickClock>, 471 DefaultConstructTrait<RolloverProtectedTickClock>,
472 ThreadSafeInitOnceTrait>::type tick_clock = 472 ThreadSafeInitOnceTrait>::type tick_clock =
473 LAZY_STATIC_INSTANCE_INITIALIZER; 473 LAZY_STATIC_INSTANCE_INITIALIZER;
474 474
475 475
476 struct CreateHighResTickClockTrait { 476 struct CreateHighResTickClockTrait {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 638
639 639
640 // static 640 // static
641 bool TimeTicks::KernelTimestampAvailable() { 641 bool TimeTicks::KernelTimestampAvailable() {
642 return kernel_tick_clock.Pointer()->Available(); 642 return kernel_tick_clock.Pointer()->Available();
643 } 643 }
644 644
645 #endif // V8_OS_WIN 645 #endif // V8_OS_WIN
646 646
647 } } // namespace v8::base 647 } } // namespace v8::base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698