15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Google Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/Timer.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformThreadData.h" 311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/ThreadTimers.h" 327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/CurrentTime.h" 337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/HashSet.h" 341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include <limits.h> 351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include <math.h> 361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include <limits> 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class TimerHeapReference; 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Timers are stored in a heap data structure, used to implement a priority queue. 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This allows us to efficiently determine which timer needs to fire the soonest. 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Then we set a single shared system timer to fire at that time. 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// When a timer's "next fire time" changes, we need to move it around in the priority queue. 47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static Vector<TimerBase*>& threadGlobalTimerHeap() 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return PlatformThreadData::current().threadTimers().timerHeap(); 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// ---------------- 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class TimerHeapPointer { 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapPointer(TimerBase** pointer) : m_pointer(pointer) { } 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapReference operator*() const; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase* operator->() const { return *m_pointer; } 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase** m_pointer; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class TimerHeapReference { 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapReference(TimerBase*& reference) : m_reference(reference) { } 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) operator TimerBase*() const { return m_reference; } 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapPointer operator&() const { return &m_reference; } 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapReference& operator=(TimerBase*); 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapReference& operator=(TimerHeapReference); 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase*& m_reference; 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline TimerHeapReference TimerHeapPointer::operator*() const 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return *m_pointer; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline TimerHeapReference& TimerHeapReference::operator=(TimerBase* timer) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reference = timer; 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Vector<TimerBase*>& heap = timer->timerHeap(); 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (&m_reference >= heap.data() && &m_reference < heap.data() + heap.size()) 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) timer->m_heapIndex = &m_reference - heap.data(); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return *this; 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline TimerHeapReference& TimerHeapReference::operator=(TimerHeapReference b) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase* timer = b; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return *this = timer; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void swap(TimerHeapReference a, TimerHeapReference b) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase* timerA = a; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase* timerB = b; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Invoke the assignment operator, since that takes care of updating m_heapIndex. 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) a = timerB; 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) b = timerA; 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// ---------------- 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Class to represent iterators in the heap when calling the standard library heap algorithms. 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Uses a custom pointer and reference type that update indices for pointers in the heap. 1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass TimerHeapIterator : public std::iterator<std::random_access_iterator_tag, TimerBase*, ptrdiff_t, TimerHeapPointer, TimerHeapReference> { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) explicit TimerHeapIterator(TimerBase** pointer) : m_pointer(pointer) { checkConsistency(); } 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapIterator& operator++() { checkConsistency(); ++m_pointer; checkConsistency(); return *this; } 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapIterator operator++(int) { checkConsistency(1); return TimerHeapIterator(m_pointer++); } 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapIterator& operator--() { checkConsistency(); --m_pointer; checkConsistency(); return *this; } 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapIterator operator--(int) { checkConsistency(-1); return TimerHeapIterator(m_pointer--); } 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapIterator& operator+=(ptrdiff_t i) { checkConsistency(); m_pointer += i; checkConsistency(); return *this; } 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapIterator& operator-=(ptrdiff_t i) { checkConsistency(); m_pointer -= i; checkConsistency(); return *this; } 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapReference operator*() const { return TimerHeapReference(*m_pointer); } 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerHeapReference operator[](ptrdiff_t i) const { return TimerHeapReference(m_pointer[i]); } 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase* operator->() const { return *m_pointer; } 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void checkConsistency(ptrdiff_t offset = 0) const 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_pointer >= threadGlobalTimerHeap().data()); 128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_pointer <= threadGlobalTimerHeap().data() + threadGlobalTimerHeap().size()); 129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_UNUSED(offset, m_pointer + offset >= threadGlobalTimerHeap().data()); 130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_UNUSED(offset, m_pointer + offset <= threadGlobalTimerHeap().data() + threadGlobalTimerHeap().size()); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend bool operator==(TimerHeapIterator, TimerHeapIterator); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend bool operator!=(TimerHeapIterator, TimerHeapIterator); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend bool operator<(TimerHeapIterator, TimerHeapIterator); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend bool operator>(TimerHeapIterator, TimerHeapIterator); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend bool operator<=(TimerHeapIterator, TimerHeapIterator); 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend bool operator>=(TimerHeapIterator, TimerHeapIterator); 13902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend TimerHeapIterator operator+(TimerHeapIterator, size_t); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend TimerHeapIterator operator+(size_t, TimerHeapIterator); 14202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend TimerHeapIterator operator-(TimerHeapIterator, size_t); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend ptrdiff_t operator-(TimerHeapIterator, TimerHeapIterator); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase** m_pointer; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator==(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer == b.m_pointer; } 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator!=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer != b.m_pointer; } 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator<(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer < b.m_pointer; } 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator>(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer > b.m_pointer; } 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator<=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer <= b.m_pointer; } 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator>=(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer >= b.m_pointer; } 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline TimerHeapIterator operator+(TimerHeapIterator a, size_t b) { return TimerHeapIterator(a.m_pointer + b); } 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline TimerHeapIterator operator+(size_t a, TimerHeapIterator b) { return TimerHeapIterator(a + b.m_pointer); } 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline TimerHeapIterator operator-(TimerHeapIterator a, size_t b) { return TimerHeapIterator(a.m_pointer - b); } 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline ptrdiff_t operator-(TimerHeapIterator a, TimerHeapIterator b) { return a.m_pointer - b.m_pointer; } 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// ---------------- 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class TimerHeapLessThanFunction { 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) bool operator()(const TimerBase*, const TimerBase*) const; 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline bool TimerHeapLessThanFunction::operator()(const TimerBase* a, const TimerBase* b) const 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 17102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // The comparisons below are "backwards" because the heap puts the largest 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // element first and we want the lowest time to be the first one in the heap. 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double aFireTime = a->m_nextFireTime; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double bFireTime = b->m_nextFireTime; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (bFireTime != aFireTime) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return bFireTime < aFireTime; 17702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 17802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // We need to look at the difference of the insertion orders instead of comparing the two 17902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // outright in case of overflow. 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned difference = a->m_heapInsertionOrder - b->m_heapInsertionOrder; 1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return difference < std::numeric_limits<unsigned>::max() / 2; 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// ---------------- 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TimerBase::TimerBase() 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_nextFireTime(0) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_unalignedNextFireTime(0) 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_repeatInterval(0) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_heapIndex(-1) 191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_cachedThreadGlobalTimerHeap(0) 192197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_thread(currentThread()) 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TimerBase::~TimerBase() 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stop(); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!inHeap()); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 204d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void TimerBase::start(double nextFireInterval, double repeatInterval, const TraceLocation& caller) 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_thread == currentThread()); 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_location = caller; 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_repeatInterval = repeatInterval; 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setNextFireTime(monotonicallyIncreasingTime() + nextFireInterval); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void TimerBase::stop() 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_thread == currentThread()); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_repeatInterval = 0; 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setNextFireTime(0); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_nextFireTime == 0); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_repeatInterval == 0); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!inHeap()); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double TimerBase::nextFireInterval() const 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isActive()); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double current = monotonicallyIncreasingTime(); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_nextFireTime < current) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_nextFireTime - current; 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void TimerBase::checkHeapIndex() const 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(timerHeap() == threadGlobalTimerHeap()); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!timerHeap().isEmpty()); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_heapIndex >= 0); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_heapIndex < static_cast<int>(timerHeap().size())); 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(timerHeap()[m_heapIndex] == this); 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void TimerBase::checkConsistency() const 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Timers should be in the heap if and only if they have a non-zero next fire time. 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(inHeap() == (m_nextFireTime != 0)); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (inHeap()) 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkHeapIndex(); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void TimerBase::heapDecreaseKey() 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_nextFireTime != 0); 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkHeapIndex(); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase** heapData = timerHeap().data(); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) push_heap(TimerHeapIterator(heapData), TimerHeapIterator(heapData + m_heapIndex + 1), TimerHeapLessThanFunction()); 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkHeapIndex(); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void TimerBase::heapDelete() 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_nextFireTime == 0); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heapPop(); 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) timerHeap().removeLast(); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_heapIndex = -1; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void TimerBase::heapDeleteMin() 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_nextFireTime == 0); 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heapPopMin(); 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) timerHeap().removeLast(); 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_heapIndex = -1; 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void TimerBase::heapIncreaseKey() 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_nextFireTime != 0); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heapPop(); 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heapDecreaseKey(); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void TimerBase::heapInsert() 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!inHeap()); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) timerHeap().append(this); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_heapIndex = timerHeap().size() - 1; 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heapDecreaseKey(); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void TimerBase::heapPop() 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Temporarily force this timer to have the minimum key so we can pop it. 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double fireTime = m_nextFireTime; 2957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_nextFireTime = -std::numeric_limits<double>::infinity(); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heapDecreaseKey(); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heapPopMin(); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_nextFireTime = fireTime; 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void TimerBase::heapPopMin() 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(this == timerHeap().first()); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkHeapIndex(); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<TimerBase*>& heap = timerHeap(); 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TimerBase** heapData = heap.data(); 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pop_heap(TimerHeapIterator(heapData), TimerHeapIterator(heapData + heap.size()), TimerHeapLessThanFunction()); 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkHeapIndex(); 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(this == timerHeap().last()); 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 312926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline bool parentHeapPropertyHolds(const TimerBase* current, const Vector<TimerBase*>& heap, unsigned currentIndex) 313926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 314926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!currentIndex) 315926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 316926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned parentIndex = (currentIndex - 1) / 2; 317926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) TimerHeapLessThanFunction compareHeapPosition; 318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return compareHeapPosition(current, heap[parentIndex]); 319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 320926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline bool childHeapPropertyHolds(const TimerBase* current, const Vector<TimerBase*>& heap, unsigned childIndex) 322926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 323926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (childIndex >= heap.size()) 324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 325926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) TimerHeapLessThanFunction compareHeapPosition; 326926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return compareHeapPosition(heap[childIndex], current); 327926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 328926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 329926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool TimerBase::hasValidHeapPosition() const 330926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 331926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_nextFireTime); 332926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!inHeap()) 333926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 334926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Check if the heap property still holds with the new fire time. If it does we don't need to do anything. 335926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // This assumes that the STL heap is a standard binary heap. In an unlikely event it is not, the assertions 336926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // in updateHeapIfNeeded() will get hit. 337926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const Vector<TimerBase*>& heap = timerHeap(); 338926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!parentHeapPropertyHolds(this, heap, m_heapIndex)) 339926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned childIndex1 = 2 * m_heapIndex + 1; 341926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned childIndex2 = childIndex1 + 1; 342926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return childHeapPropertyHolds(this, heap, childIndex1) && childHeapPropertyHolds(this, heap, childIndex2); 343926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 344926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 345926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void TimerBase::updateHeapIfNeeded(double oldTime) 346926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 347926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_nextFireTime && hasValidHeapPosition()) 348926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 349197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 350926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int oldHeapIndex = m_heapIndex; 351926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif 352926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!oldTime) 353926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) heapInsert(); 354926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else if (!m_nextFireTime) 355926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) heapDelete(); 356926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else if (m_nextFireTime < oldTime) 357926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) heapDecreaseKey(); 358926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else 359926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) heapIncreaseKey(); 360926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(m_heapIndex != oldHeapIndex); 361926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(!inHeap() || hasValidHeapPosition()); 362926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 363926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void TimerBase::setNextFireTime(double newUnalignedTime) 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_thread == currentThread()); 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_unalignedNextFireTime != newUnalignedTime) 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_unalignedNextFireTime = newUnalignedTime; 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 371926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Accessing thread global data is slow. Cache the heap pointer. 372926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_cachedThreadGlobalTimerHeap) 373926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_cachedThreadGlobalTimerHeap = &threadGlobalTimerHeap(); 374926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Keep heap valid while changing the next-fire time. 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double oldTime = m_nextFireTime; 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double newTime = alignedFireTime(newUnalignedTime); 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (oldTime != newTime) { 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_nextFireTime = newTime; 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static unsigned currentHeapInsertionOrder; 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_heapInsertionOrder = currentHeapInsertionOrder++; 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool wasFirstTimerInHeap = m_heapIndex == 0; 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 385926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) updateHeapIfNeeded(oldTime); 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isFirstTimerInHeap = m_heapIndex == 0; 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wasFirstTimerInHeap || isFirstTimerInHeap) 3901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) PlatformThreadData::current().threadTimers().updateSharedTimer(); 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) checkConsistency(); 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void TimerBase::fireTimersInNestedEventLoop() 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Redirect to ThreadTimers. 3991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) PlatformThreadData::current().threadTimers().fireTimersInNestedEventLoop(); 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void TimerBase::didChangeAlignmentInterval() 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setNextFireTime(m_unalignedNextFireTime); 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double TimerBase::nextUnalignedFireInterval() const 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isActive()); 4107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return std::max(m_unalignedNextFireTime - monotonicallyIncreasingTime(), 0.0); 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 413c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 415