0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-12 04:51:08 +01:00

ircd::ctx: Switch from steady_timer to deadline_timer.

This commit is contained in:
Jason Volk 2019-09-22 20:02:23 -07:00
parent 320af9e9b8
commit 39ade19ae3
14 changed files with 80 additions and 52 deletions

View file

@ -144,14 +144,14 @@ void
ircd::ctx::future<T>::wait() ircd::ctx::future<T>::wait()
const const
{ {
this->wait_until(steady_point::max()); this->wait_until(system_point::max());
} }
inline void inline void
ircd::ctx::future<void>::wait() ircd::ctx::future<void>::wait()
const const
{ {
this->wait_until(steady_point::max()); this->wait_until(system_point::max());
} }
template<class T> template<class T>
@ -160,7 +160,7 @@ void
ircd::ctx::future<T>::wait(const duration &d) ircd::ctx::future<T>::wait(const duration &d)
const const
{ {
this->wait_until(now<steady_point>() + d); this->wait_until(now<system_point>() + d);
} }
template<class duration> template<class duration>
@ -168,7 +168,7 @@ void
ircd::ctx::future<void>::wait(const duration &d) ircd::ctx::future<void>::wait(const duration &d)
const const
{ {
this->wait_until(now<steady_point>() + d); this->wait_until(now<system_point>() + d);
} }
template<class T> template<class T>
@ -178,7 +178,7 @@ ircd::ctx::future<T>::wait(const duration &d,
std::nothrow_t) std::nothrow_t)
const const
{ {
return this->wait_until(now<steady_point>() + d, std::nothrow); return this->wait_until(now<system_point>() + d, std::nothrow);
} }
template<class duration> template<class duration>
@ -187,7 +187,7 @@ ircd::ctx::future<void>::wait(const duration &d,
std::nothrow_t) std::nothrow_t)
const const
{ {
return this->wait_until(now<steady_point>() + d, std::nothrow); return this->wait_until(now<system_point>() + d, std::nothrow);
} }
template<class T> template<class T>

View file

@ -108,7 +108,7 @@ template<class duration>
bool bool
ircd::ctx::mutex::try_lock_for(const duration &d) ircd::ctx::mutex::try_lock_for(const duration &d)
{ {
return try_lock_until(steady_clock::now() + d); return try_lock_until(system_clock::now() + d);
} }
template<class time_point> template<class time_point>

View file

@ -171,21 +171,21 @@ template<class duration>
bool bool
ircd::ctx::shared_mutex::try_unlock_upgrade_and_lock_for(duration&& d) ircd::ctx::shared_mutex::try_unlock_upgrade_and_lock_for(duration&& d)
{ {
return try_unlock_upgrade_and_lock_until(steady_clock::now() + d); return try_unlock_upgrade_and_lock_until(system_clock::now() + d);
} }
template<class duration> template<class duration>
bool bool
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_upgrade_for(duration&& d) ircd::ctx::shared_mutex::try_unlock_shared_and_lock_upgrade_for(duration&& d)
{ {
return try_unlock_shared_and_lock_upgrade_until(steady_clock::now() + d); return try_unlock_shared_and_lock_upgrade_until(system_clock::now() + d);
} }
template<class duration> template<class duration>
bool bool
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_for(duration&& d) ircd::ctx::shared_mutex::try_unlock_shared_and_lock_for(duration&& d)
{ {
return try_unlock_shared_and_lock_until(steady_clock::now() + d); return try_unlock_shared_and_lock_until(system_clock::now() + d);
} }
template<class time_point> template<class time_point>
@ -279,21 +279,21 @@ template<class duration>
bool bool
ircd::ctx::shared_mutex::try_lock_upgrade_for(duration&& d) ircd::ctx::shared_mutex::try_lock_upgrade_for(duration&& d)
{ {
return try_lock_upgrade_until(steady_clock::now() + d); return try_lock_upgrade_until(system_clock::now() + d);
} }
template<class duration> template<class duration>
bool bool
ircd::ctx::shared_mutex::try_lock_shared_for(duration&& d) ircd::ctx::shared_mutex::try_lock_shared_for(duration&& d)
{ {
return try_lock_shared_until(steady_clock::now() + d); return try_lock_shared_until(system_clock::now() + d);
} }
template<class duration> template<class duration>
bool bool
ircd::ctx::shared_mutex::try_lock_for(duration&& d) ircd::ctx::shared_mutex::try_lock_for(duration&& d)
{ {
return try_lock_until(steady_clock::now() + d); return try_lock_until(system_clock::now() + d);
} }
template<class time_point> template<class time_point>

View file

@ -31,12 +31,12 @@ inline namespace this_ctx
template<class E = timeout, class duration> throw_overload<E, duration> wait(const duration &); template<class E = timeout, class duration> throw_overload<E, duration> wait(const duration &);
// Returns false if notified; true if time point reached, timeout thrown on throw_overloads // Returns false if notified; true if time point reached, timeout thrown on throw_overloads
bool wait_until(const steady_point &tp, const std::nothrow_t &); bool wait_until(const system_point &tp, const std::nothrow_t &);
template<class E> nothrow_overload<E, bool> wait_until(const steady_point &tp); template<class E> nothrow_overload<E, bool> wait_until(const system_point &tp);
template<class E = timeout> throw_overload<E> wait_until(const steady_point &tp); template<class E = timeout> throw_overload<E> wait_until(const system_point &tp);
// Ignores notes. Throws if interrupted. // Ignores notes. Throws if interrupted.
void sleep_until(const steady_point &tp); void sleep_until(const system_point &tp);
template<class duration> void sleep(const duration &); template<class duration> void sleep(const duration &);
void sleep(const int &secs); void sleep(const int &secs);
}} }}
@ -68,7 +68,7 @@ template<class duration>
void void
ircd::ctx::this_ctx::sleep(const duration &d) ircd::ctx::this_ctx::sleep(const duration &d)
{ {
sleep_until(steady_clock::now() + d); sleep_until(system_clock::now() + d);
} }
/// Wait for a notification until a point in time. If there is a notification /// Wait for a notification until a point in time. If there is a notification
@ -77,7 +77,7 @@ ircd::ctx::this_ctx::sleep(const duration &d)
/// interruption point. /// interruption point.
template<class E> template<class E>
ircd::throw_overload<E> ircd::throw_overload<E>
ircd::ctx::this_ctx::wait_until(const steady_point &tp) ircd::ctx::this_ctx::wait_until(const system_point &tp)
{ {
if(wait_until<std::nothrow_t>(tp)) if(wait_until<std::nothrow_t>(tp))
throw E{}; throw E{};
@ -88,7 +88,7 @@ ircd::ctx::this_ctx::wait_until(const steady_point &tp)
/// interruption point. this is not noexcept. /// interruption point. this is not noexcept.
template<class E> template<class E>
ircd::nothrow_overload<E, bool> ircd::nothrow_overload<E, bool>
ircd::ctx::this_ctx::wait_until(const steady_point &tp) ircd::ctx::this_ctx::wait_until(const system_point &tp)
{ {
return wait_until(tp, std::nothrow); return wait_until(tp, std::nothrow);
} }

View file

@ -126,7 +126,7 @@ T &
ircd::ctx::view<T, mutex>::wait_for(lock &l, ircd::ctx::view<T, mutex>::wait_for(lock &l,
const duration &dur) const duration &dur)
{ {
return wait_until(l, now<steady_point>() + dur); return wait_until(l, now<system_point>() + dur);
} }
template<class T, template<class T,

View file

@ -667,25 +667,11 @@ ircd::ctx::current;
/// Yield the currently running context until `time_point` ignoring notes /// Yield the currently running context until `time_point` ignoring notes
void void
ircd::ctx::this_ctx::sleep_until(const steady_clock::time_point &tp) ircd::ctx::this_ctx::sleep_until(const system_point &tp)
{ {
while(!wait_until(tp, std::nothrow)); while(!wait_until(tp, std::nothrow));
} }
/// Yield the currently running context until notified or `time_point`.
///
/// Returns true if this function returned because `time_point` was hit or
/// false because this context was notified.
bool
ircd::ctx::this_ctx::wait_until(const steady_clock::time_point &tp,
const std::nothrow_t &)
{
auto &c(cur());
c.alarm.expires_at(tp);
c.wait(); // now you're yielding with portals
return steady_clock::now() >= tp;
}
/// Yield the currently running context for `duration` or until notified. /// Yield the currently running context for `duration` or until notified.
/// ///
/// Returns the duration remaining if notified, or <= 0 if suspended for /// Returns the duration remaining if notified, or <= 0 if suspended for
@ -694,15 +680,57 @@ ircd::microseconds
ircd::ctx::this_ctx::wait(const microseconds &duration, ircd::ctx::this_ctx::wait(const microseconds &duration,
const std::nothrow_t &) const std::nothrow_t &)
{ {
const boost::posix_time::microseconds ptime_duration
{
duration.count()
};
auto &c(cur()); auto &c(cur());
c.alarm.expires_from_now(duration); c.alarm.expires_from_now(ptime_duration);
c.wait(); // now you're yielding with portals c.wait(); // now you're yielding with portals
const auto ret(c.alarm.expires_from_now()); const auto &ret
{
c.alarm.expires_from_now()
};
// return remaining duration. // return remaining duration.
// this is > 0 if notified // this is > 0 if notified
// this is unchanged if a note prevented any wait at all // this is unchanged if a note prevented any wait at all
return duration_cast<microseconds>(ret); return microseconds(ret.total_microseconds());
}
/// Yield the currently running context until notified or `time_point`.
///
/// Returns true if this function returned because `time_point` was hit or
/// false because this context was notified.
bool
ircd::ctx::this_ctx::wait_until(const system_point &tp,
const std::nothrow_t &)
{
const auto &diff
{
tp - now<system_point>()
};
const boost::posix_time::microseconds duration
{
duration_cast<microseconds>(diff).count()
};
const auto &expires_at
{
boost::posix_time::microsec_clock::universal_time() + duration
};
auto &c(cur());
c.alarm.expires_at(expires_at);
c.wait(); // now you're yielding with portals
const auto &ret
{
c.alarm.expires_from_now()
};
return ret <= boost::posix_time::microseconds(0);
} }
/// Yield the currently running context until notified. /// Yield the currently running context until notified.
@ -710,7 +738,7 @@ void
ircd::ctx::this_ctx::wait() ircd::ctx::this_ctx::wait()
{ {
auto &c(cur()); auto &c(cur());
c.alarm.expires_at(steady_clock::time_point::max()); c.alarm.expires_at(boost::posix_time::pos_infin);
c.wait(); // now you're yielding with portals c.wait(); // now you're yielding with portals
} }

View file

@ -54,7 +54,7 @@ struct ircd::ctx::ctx
context::flags flags; // User given flags context::flags flags; // User given flags
int32_t notes {0}; // norm: 0 = asleep; 1 = awake; inc by others; dec by self int32_t notes {0}; // norm: 0 = asleep; 1 = awake; inc by others; dec by self
boost::asio::io_service::strand strand; // mutex/serializer boost::asio::io_service::strand strand; // mutex/serializer
boost::asio::steady_timer alarm; // acting semaphore (64B) boost::asio::deadline_timer alarm; // acting semaphore (64B)
boost::asio::yield_context *yc {nullptr}; // boost interface boost::asio::yield_context *yc {nullptr}; // boost interface
continuation *cont {nullptr}; // valid when asleep; invalid when awake continuation *cont {nullptr}; // valid when asleep; invalid when awake
list::node node; // node for ctx::list list::node node; // node for ctx::list

View file

@ -297,7 +297,7 @@ noexcept
assert_main_thread(); assert_main_thread();
mu->AssertHeld(); mu->AssertHeld();
const std::chrono::microseconds us(abs_time_us); const std::chrono::microseconds us(abs_time_us);
const std::chrono::steady_clock::time_point tp(us); const std::chrono::system_clock::time_point tp(us);
const ctx::uninterruptible::nothrow ui; const ctx::uninterruptible::nothrow ui;
return cv.wait_until(mu->mu, tp) == std::cv_status::timeout; return cv.wait_until(mu->mu, tp) == std::cv_status::timeout;
} }

View file

@ -39,7 +39,7 @@ recv_response(const string_view &,
m::v1::user::keys::claim &, m::v1::user::keys::claim &,
failure_map &, failure_map &,
json::stack::object &, json::stack::object &,
const steady_point &); const system_point &);
static void static void
recv_responses(query_map &, recv_responses(query_map &,
@ -190,9 +190,9 @@ recv_responses(query_map &queries,
json::stack::object &out, json::stack::object &out,
const milliseconds &timeout) const milliseconds &timeout)
{ {
const steady_point timedout const system_point timedout
{ {
ircd::now<steady_point>() + timeout ircd::now<system_point>() + timeout
}; };
json::stack::object one_time_keys json::stack::object one_time_keys
@ -215,7 +215,7 @@ recv_response(const string_view &remote,
m::v1::user::keys::claim &request, m::v1::user::keys::claim &request,
failure_map &failures, failure_map &failures,
json::stack::object &object, json::stack::object &object,
const steady_point &timeout) const system_point &timeout)
try try
{ {
request.wait_until(timeout); request.wait_until(timeout);

View file

@ -199,9 +199,9 @@ recv_responses(query_map &queries,
const milliseconds &timeout) const milliseconds &timeout)
try try
{ {
const steady_point timedout const system_point timedout
{ {
ircd::now<steady_point>() + timeout ircd::now<system_point>() + timeout
}; };
json::stack::object response_keys json::stack::object response_keys

View file

@ -1113,7 +1113,7 @@ try
ret = std::min(ret, milliseconds(timeout_max)); ret = std::min(ret, milliseconds(timeout_max));
ret = std::max(ret, milliseconds(timeout_min)); ret = std::max(ret, milliseconds(timeout_min));
return now<steady_point>() + ret; return now<system_point>() + ret;
}()} }()}
,full_state ,full_state
{ {

View file

@ -51,7 +51,7 @@ struct ircd::m::sync::args
/// The point in time at which this /sync should stop longpolling and return /// The point in time at which this /sync should stop longpolling and return
/// an empty'ish response to the client. /// an empty'ish response to the client.
steady_point timesout; system_point timesout;
/// 6.2.1 Controls whether to include the full state for all rooms the user is a member of. /// 6.2.1 Controls whether to include the full state for all rooms the user is a member of.
/// If this is set to true, then all state events will be returned, even if since is non-empty. /// If this is set to true, then all state events will be returned, even if since is non-empty.

View file

@ -12614,7 +12614,7 @@ console_cmd__fed__sync(opt &out, const string_view &line)
const auto when const auto when
{ {
now<steady_point>() + timeout now<system_point>() + timeout
}; };
bfrequest.wait_until(when); bfrequest.wait_until(when);

View file

@ -358,7 +358,7 @@ ircd::m::feds::handler(request_list &reqs,
{ {
const auto when const auto when
{ {
now<steady_point>() + timeout now<system_point>() + timeout
}; };
while(!reqs.empty()) while(!reqs.empty())