1325254 - optimize TimerThread data structures

1325254 P1 Make TimerThread::mTimers store RefPtr<nsTimerImpl> objects.

1325254 P2 Make TimerThread list store an entry struct and just drop nsTimerImpl ref on cancel.

1325254 P3 Sort TimerThread list as a binary heap.

1325254 P4 Dynamically allocate Entry structs stored in TimerThread::mTimers.

1325254 P5 Make nsITimer::Cancel() O(c).
This commit is contained in:
win7-7 2024-04-27 20:04:28 +03:00 committed by wuggy
commit f109b02bc3
4 changed files with 157 additions and 43 deletions

View file

@ -19,6 +19,8 @@
#include "mozilla/Attributes.h"
#include "mozilla/Monitor.h"
#include <algorithm>
namespace mozilla {
class TimeStamp;
} // namespace mozilla
@ -60,12 +62,12 @@ private:
mozilla::Atomic<bool> mInitInProgress;
bool mInitialized;
// These two internal helper methods must be called while mMonitor is held.
// AddTimerInternal returns the position where the timer was added in the
// list, or -1 if it failed.
int32_t AddTimerInternal(nsTimerImpl* aTimer);
// These internal helper methods must be called while mMonitor is held.
// AddTimerInternal returns false if the insertion failed.
bool AddTimerInternal(nsTimerImpl* aTimer);
bool RemoveTimerInternal(nsTimerImpl* aTimer);
void ReleaseTimerInternal(nsTimerImpl* aTimer);
void RemoveLeadingCanceledTimersInternal();
void RemoveFirstTimerInternal();
already_AddRefed<nsTimerImpl> PostTimerEvent(already_AddRefed<nsTimerImpl> aTimerRef);
@ -81,7 +83,43 @@ private:
bool mNotified;
bool mSleeping;
nsTArray<nsTimerImpl*> mTimers;
class Entry final : public nsTimerImplHolder
{
const TimeStamp mTimeout;
public:
Entry(const TimeStamp& aMinTimeout, const TimeStamp& aTimeout,
nsTimerImpl* aTimerImpl)
: nsTimerImplHolder(aTimerImpl)
, mTimeout(std::max(aMinTimeout, aTimeout))
{
}
nsTimerImpl*
Value() const
{
return mTimerImpl;
}
already_AddRefed<nsTimerImpl>
Take()
{
if (mTimerImpl) {
mTimerImpl->SetHolder(nullptr);
}
return mTimerImpl.forget();
}
static bool
UniquePtrLessThan(UniquePtr<Entry>& aLeft, UniquePtr<Entry>& aRight)
{
// This is reversed because std::push_heap() sorts the "largest" to
// the front of the heap. We want that to be the earliest timer.
return aRight->mTimeout < aLeft->mTimeout;
}
};
nsTArray<UniquePtr<Entry>> mTimers;
};
struct TimerAdditionComparator