Ignore:
Timestamp:
Feb 17, 2017, 1:13:58 AM (8 years ago)
Author:
[email protected]
Message:

[GLib] GCActivityCallback::scheduleTimer() keeps pushing dispatch into the future
https://bugs.webkit.org/show_bug.cgi?id=168363

Reviewed by Carlos Garcia Campos.

Mimic the USE(CF) implementation of GCActivityCallback and HeapTimer by
scheduling the timer a decade into the future instead of completely
cancelling it. That way new dispatch times for GCActivityCallback can be
computed by simply deducting the difference in the new and previous
delay from the GSource's current dispatch time. Previously we handled an
extra 'paused' state (where m_delay was -1) and allowed for a delay of
an infinite value to be valid, complicating the next dispatch time
computation.

HeapTimer gains the static s_decade variable. The dispatch function in
heapTimerSourceFunctions only dispatches the callback, which now delays
the GSource by a decade. HeapTimer::scheduleTimer() simply schedules the
source to dispatch in the specified amount of time, and cancelTimer()
'cancels' the source by setting the dispatch time to a decade.

GCActivityCallback constructor initializes the delay to the s_decade
value and immediately sets the ready time for GSource a decade into the
future, avoiding the default -1 value as the ready time that would cause
problems in scheduleTimer(). scheduleTimer() doesn't special-case the
zero-delay value anymore, instead it just computes the difference
between the old and the new delay and rolls back the GSource's ready
time for that amount. cancelTimer() sets m_delay to the decade value and
delays the GSource for that same amount.

  • heap/GCActivityCallback.cpp:

(JSC::GCActivityCallback::GCActivityCallback):
(JSC::GCActivityCallback::scheduleTimer):
(JSC::GCActivityCallback::cancelTimer):

  • heap/GCActivityCallback.h:
  • heap/HeapTimer.cpp:

(JSC::HeapTimer::HeapTimer):
(JSC::HeapTimer::scheduleTimer):
(JSC::HeapTimer::cancelTimer):

  • heap/HeapTimer.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/heap/HeapTimer.cpp

    r212464 r212541  
    109109#elif USE(GLIB)
    110110
     111const long HeapTimer::s_decade = 60 * 60 * 24 * 365 * 10;
     112
    111113static GSourceFuncs heapTimerSourceFunctions = {
    112114    nullptr, // prepare
    113115    nullptr, // check
    114116    // dispatch
    115     [](GSource* source, GSourceFunc callback, gpointer userData) -> gboolean
     117    [](GSource*, GSourceFunc callback, gpointer userData) -> gboolean
    116118    {
    117         if (g_source_get_ready_time(source) == -1)
    118             return G_SOURCE_CONTINUE;
    119         g_source_set_ready_time(source, -1);
    120119        return callback(userData);
    121120    },
     
    132131    g_source_set_name(m_timer.get(), "[JavaScriptCore] HeapTimer");
    133132    g_source_set_callback(m_timer.get(), [](gpointer userData) -> gboolean {
    134         static_cast<HeapTimer*>(userData)->timerDidFire();
     133        auto& heapTimer = *static_cast<HeapTimer*>(userData);
     134        g_source_set_ready_time(heapTimer.m_timer.get(), g_get_monotonic_time() + HeapTimer::s_decade * G_USEC_PER_SEC);
     135        heapTimer.timerDidFire();
    135136        return G_SOURCE_CONTINUE;
    136137    }, this, nullptr);
     
    163164void HeapTimer::scheduleTimer(double intervalInSeconds)
    164165{
    165     auto delayDuration = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(intervalInSeconds));
    166     gint64 currentTime = g_get_monotonic_time();
    167     gint64 targetTime = currentTime + std::min<gint64>(G_MAXINT64 - currentTime, delayDuration.count());
    168     ASSERT(targetTime >= currentTime);
    169     g_source_set_ready_time(m_timer.get(), targetTime);
     166    g_source_set_ready_time(m_timer.get(), g_get_monotonic_time() + intervalInSeconds * G_USEC_PER_SEC);
    170167    m_isScheduled = true;
    171168}
     
    173170void HeapTimer::cancelTimer()
    174171{
    175     g_source_set_ready_time(m_timer.get(), -1);
     172    g_source_set_ready_time(m_timer.get(), g_get_monotonic_time() + s_decade * G_USEC_PER_SEC);
    176173    m_isScheduled = false;
    177174}
Note: See TracChangeset for help on using the changeset viewer.