static inline int32_t
ticks_until_next_timeout(void)
{
    struct timespec ts;
    bool ret;

    sol_mainloop_impl_lock();
    ret = (sol_mainloop_common_idler_first() != NULL);
    sol_mainloop_impl_unlock();
    if (ret)
        return TICKS_NONE;

    sol_mainloop_impl_lock();
    ret = sol_mainloop_common_timespec_first(&ts);
    sol_mainloop_impl_unlock();
    if (!ret)
        return TICKS_UNLIMITED;

    return ts.tv_sec * sys_clock_ticks_per_sec +
        ((long long)sys_clock_ticks_per_sec * ts.tv_nsec) / NSEC_PER_SEC;
}
static inline uint32_t
sleeptime_until_next_timeout(void)
{
    struct timespec ts;
    uint32_t sleeptime = DEFAULT_USLEEP_TIME;
    bool ret;

    sol_mainloop_impl_lock();
    ret = sol_mainloop_common_timespec_first(&ts);
    sol_mainloop_impl_unlock();

    if (ret) {
        if (ts.tv_sec < 0)
            sleeptime = 0;
        else
            sleeptime = ts.tv_sec * USEC_PER_SEC + ts.tv_nsec / NSEC_PER_USEC;
    }

    return sleeptime;
}