mirror of
https://github.com/matrix-construct/construct
synced 2025-03-14 05:20:17 +01:00
ircd::ctx::dock: Eliminate inlined template complex; optimize linkages.
This commit is contained in:
parent
29b0523dfc
commit
8b6679c5e9
3 changed files with 175 additions and 160 deletions
|
@ -34,11 +34,11 @@ class ircd::ctx::dock
|
|||
size_t size() const noexcept;
|
||||
bool waiting(const ctx &) const noexcept;
|
||||
|
||||
template<class time_point> bool wait_until(time_point&&, const predicate &);
|
||||
template<class time_point> bool wait_until(time_point&&);
|
||||
bool wait_until(const system_point, const predicate &);
|
||||
bool wait_until(const system_point);
|
||||
|
||||
template<class duration> bool wait_for(const duration &, const predicate &);
|
||||
template<class duration> bool wait_for(const duration &);
|
||||
template<class duration> bool wait_for(const duration, const predicate &);
|
||||
template<class duration> bool wait_for(const duration);
|
||||
|
||||
void wait(const predicate &);
|
||||
void wait();
|
||||
|
@ -50,6 +50,57 @@ class ircd::ctx::dock
|
|||
void notify() noexcept;
|
||||
};
|
||||
|
||||
namespace ircd::ctx
|
||||
{
|
||||
template<> bool dock::wait_for(const microseconds, const predicate &);
|
||||
template<> bool dock::wait_for(const microseconds);
|
||||
}
|
||||
|
||||
/// Wake up the next context waiting on the dock
|
||||
inline void
|
||||
ircd::ctx::dock::notify_one()
|
||||
noexcept
|
||||
{
|
||||
if(q.empty())
|
||||
return;
|
||||
|
||||
ircd::ctx::notify(*q.front());
|
||||
}
|
||||
|
||||
template<class duration>
|
||||
inline bool
|
||||
ircd::ctx::dock::wait_for(const duration dur,
|
||||
const predicate &pred)
|
||||
{
|
||||
static_assert(!std::is_same<duration, microseconds>());
|
||||
return wait_for(duration_cast<microseconds>(dur), pred);
|
||||
}
|
||||
|
||||
template<class duration>
|
||||
inline bool
|
||||
ircd::ctx::dock::wait_for(const duration dur)
|
||||
{
|
||||
static_assert(!std::is_same<duration, microseconds>());
|
||||
return wait_for(duration_cast<microseconds>(dur));
|
||||
}
|
||||
|
||||
|
||||
/// The number of contexts waiting in the queue.
|
||||
inline size_t
|
||||
ircd::ctx::dock::size()
|
||||
const noexcept
|
||||
{
|
||||
return q.size();
|
||||
}
|
||||
|
||||
/// The number of contexts waiting in the queue.
|
||||
inline bool
|
||||
ircd::ctx::dock::empty()
|
||||
const noexcept
|
||||
{
|
||||
return q.empty();
|
||||
}
|
||||
|
||||
inline void
|
||||
ircd::ctx::notify(dock &dock)
|
||||
noexcept
|
||||
|
@ -70,134 +121,3 @@ noexcept
|
|||
{
|
||||
dock.terminate_all();
|
||||
}
|
||||
|
||||
//
|
||||
// dock::dock
|
||||
//
|
||||
|
||||
/// Wake up the next context waiting on the dock
|
||||
inline void
|
||||
ircd::ctx::dock::notify_one()
|
||||
noexcept
|
||||
{
|
||||
if(q.empty())
|
||||
return;
|
||||
|
||||
ircd::ctx::notify(*q.front());
|
||||
}
|
||||
|
||||
/// Returns true if notified; false if timed out
|
||||
template<class duration>
|
||||
inline bool
|
||||
ircd::ctx::dock::wait_for(const duration &dur)
|
||||
{
|
||||
static const duration zero(0);
|
||||
|
||||
assert(current);
|
||||
const unwind_exceptional renotify{[this]
|
||||
{
|
||||
notify_one();
|
||||
}};
|
||||
|
||||
const unwind remove{[this]
|
||||
{
|
||||
q.remove(current);
|
||||
}};
|
||||
|
||||
q.push_back(current);
|
||||
return ircd::ctx::wait<std::nothrow_t>(dur) > zero;
|
||||
}
|
||||
|
||||
/// Returns true if predicate passed; false if timed out
|
||||
template<class duration>
|
||||
inline bool
|
||||
ircd::ctx::dock::wait_for(const duration &dur,
|
||||
const predicate &pred)
|
||||
{
|
||||
static const duration zero(0);
|
||||
|
||||
if(pred())
|
||||
return true;
|
||||
|
||||
assert(current);
|
||||
const unwind_exceptional renotify{[this]
|
||||
{
|
||||
notify_one();
|
||||
}};
|
||||
|
||||
const unwind remove{[this]
|
||||
{
|
||||
q.remove(current);
|
||||
}};
|
||||
|
||||
q.push_back(current); do
|
||||
{
|
||||
const bool expired
|
||||
{
|
||||
ircd::ctx::wait<std::nothrow_t>(dur) <= zero
|
||||
};
|
||||
|
||||
if(pred())
|
||||
return true;
|
||||
|
||||
if(expired)
|
||||
return false;
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
/// Returns true if notified; false if timed out
|
||||
template<class time_point>
|
||||
inline bool
|
||||
ircd::ctx::dock::wait_until(time_point&& tp)
|
||||
{
|
||||
assert(current);
|
||||
const unwind_exceptional renotify{[this]
|
||||
{
|
||||
notify_one();
|
||||
}};
|
||||
|
||||
const unwind remove{[this]
|
||||
{
|
||||
q.remove(current);
|
||||
}};
|
||||
|
||||
q.push_back(current);
|
||||
return !ircd::ctx::wait_until<std::nothrow_t>(tp);
|
||||
}
|
||||
|
||||
/// Returns true if predicate passed; false if timed out
|
||||
template<class time_point>
|
||||
inline bool
|
||||
ircd::ctx::dock::wait_until(time_point&& tp,
|
||||
const predicate &pred)
|
||||
{
|
||||
if(pred())
|
||||
return true;
|
||||
|
||||
assert(current);
|
||||
const unwind_exceptional renotify{[this]
|
||||
{
|
||||
notify_one();
|
||||
}};
|
||||
|
||||
const unwind remove{[this]
|
||||
{
|
||||
q.remove(current);
|
||||
}};
|
||||
|
||||
q.push_back(current); do
|
||||
{
|
||||
const bool expired
|
||||
{
|
||||
ircd::ctx::wait_until<std::nothrow_t>(tp)
|
||||
};
|
||||
|
||||
if(pred())
|
||||
return true;
|
||||
|
||||
if(expired)
|
||||
return false;
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
|
|
@ -45,10 +45,10 @@ namespace ircd::ctx { inline namespace this_ctx
|
|||
/// exception (= timeout) is thrown.
|
||||
/// interruption point.
|
||||
template<class E>
|
||||
ircd::throw_overload<E>
|
||||
inline ircd::throw_overload<E>
|
||||
ircd::ctx::this_ctx::wait_until(const system_point &tp)
|
||||
{
|
||||
if(wait_until<std::nothrow_t>(tp))
|
||||
if(unlikely(wait_until<std::nothrow_t>(tp)))
|
||||
throw E{};
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ ircd::ctx::this_ctx::wait_until(const system_point &tp)
|
|||
/// then returns true. If there's never a notification then returns false.
|
||||
/// interruption point. this is not noexcept.
|
||||
template<class E>
|
||||
ircd::nothrow_overload<E, bool>
|
||||
inline ircd::nothrow_overload<E, bool>
|
||||
ircd::ctx::this_ctx::wait_until(const system_point &tp)
|
||||
{
|
||||
return wait_until(tp, std::nothrow);
|
||||
|
@ -68,7 +68,7 @@ ircd::ctx::this_ctx::wait_until(const system_point &tp)
|
|||
/// interruption point
|
||||
template<class E,
|
||||
class duration>
|
||||
ircd::throw_overload<E, duration>
|
||||
inline ircd::throw_overload<E, duration>
|
||||
ircd::ctx::this_ctx::wait(const duration &d)
|
||||
{
|
||||
const auto ret
|
||||
|
@ -76,9 +76,10 @@ ircd::ctx::this_ctx::wait(const duration &d)
|
|||
wait<std::nothrow_t>(d)
|
||||
};
|
||||
|
||||
return ret <= duration(0)?
|
||||
throw E{}:
|
||||
ret;
|
||||
if(unlikely(ret <= duration(0)))
|
||||
throw E{};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Wait for a notification for some amount of time. This function returns
|
||||
|
@ -87,7 +88,7 @@ ircd::ctx::this_ctx::wait(const duration &d)
|
|||
/// interruption point. this is not noexcept.
|
||||
template<class E,
|
||||
class duration>
|
||||
ircd::nothrow_overload<E, duration>
|
||||
inline ircd::nothrow_overload<E, duration>
|
||||
ircd::ctx::this_ctx::wait(const duration &d)
|
||||
{
|
||||
const auto ret
|
||||
|
|
128
ircd/ctx.cc
128
ircd/ctx.cc
|
@ -2837,7 +2837,6 @@ noexcept
|
|||
});
|
||||
}
|
||||
|
||||
[[gnu::hot]]
|
||||
void
|
||||
ircd::ctx::dock::wait()
|
||||
{
|
||||
|
@ -2880,6 +2879,117 @@ ircd::ctx::dock::wait(const predicate &pred)
|
|||
while(!pred());
|
||||
}
|
||||
|
||||
template<>
|
||||
bool
|
||||
ircd::ctx::dock::wait_for(const microseconds dur)
|
||||
{
|
||||
static const microseconds zero {0};
|
||||
|
||||
assert(current);
|
||||
const unwind_exceptional renotify{[this]
|
||||
{
|
||||
notify_one();
|
||||
}};
|
||||
|
||||
const unwind remove{[this]
|
||||
{
|
||||
q.remove(current);
|
||||
}};
|
||||
|
||||
q.push_back(current);
|
||||
return ircd::ctx::wait<std::nothrow_t>(dur) > zero;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool
|
||||
ircd::ctx::dock::wait_for(const microseconds dur,
|
||||
const predicate &pred)
|
||||
{
|
||||
static const microseconds zero {0};
|
||||
|
||||
if(pred())
|
||||
return true;
|
||||
|
||||
assert(current);
|
||||
const unwind_exceptional renotify{[this]
|
||||
{
|
||||
notify_one();
|
||||
}};
|
||||
|
||||
const unwind remove{[this]
|
||||
{
|
||||
q.remove(current);
|
||||
}};
|
||||
|
||||
q.push_back(current); do
|
||||
{
|
||||
const bool expired
|
||||
{
|
||||
ircd::ctx::wait<std::nothrow_t>(dur) <= zero
|
||||
};
|
||||
|
||||
if(pred())
|
||||
return true;
|
||||
|
||||
if(expired)
|
||||
return false;
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::ctx::dock::wait_until(const system_point tp)
|
||||
{
|
||||
assert(current);
|
||||
const unwind_exceptional renotify{[this]
|
||||
{
|
||||
notify_one();
|
||||
}};
|
||||
|
||||
const unwind remove{[this]
|
||||
{
|
||||
q.remove(current);
|
||||
}};
|
||||
|
||||
q.push_back(current);
|
||||
return !ircd::ctx::wait_until<std::nothrow_t>(tp);
|
||||
}
|
||||
|
||||
/// Returns true if predicate passed; false if timed out
|
||||
bool
|
||||
ircd::ctx::dock::wait_until(const system_point tp,
|
||||
const predicate &pred)
|
||||
{
|
||||
if(pred())
|
||||
return true;
|
||||
|
||||
assert(current);
|
||||
const unwind_exceptional renotify{[this]
|
||||
{
|
||||
notify_one();
|
||||
}};
|
||||
|
||||
const unwind remove{[this]
|
||||
{
|
||||
q.remove(current);
|
||||
}};
|
||||
|
||||
q.push_back(current); do
|
||||
{
|
||||
const bool expired
|
||||
{
|
||||
ircd::ctx::wait_until<std::nothrow_t>(tp)
|
||||
};
|
||||
|
||||
if(pred())
|
||||
return true;
|
||||
|
||||
if(expired)
|
||||
return false;
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
/// The number of contexts waiting in the queue.
|
||||
bool
|
||||
ircd::ctx::dock::waiting(const ctx &a)
|
||||
|
@ -2894,22 +3004,6 @@ const noexcept
|
|||
}});
|
||||
}
|
||||
|
||||
/// The number of contexts waiting in the queue.
|
||||
size_t
|
||||
ircd::ctx::dock::size()
|
||||
const noexcept
|
||||
{
|
||||
return q.size();
|
||||
}
|
||||
|
||||
/// The number of contexts waiting in the queue.
|
||||
bool
|
||||
ircd::ctx::dock::empty()
|
||||
const noexcept
|
||||
{
|
||||
return q.empty();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ctx_list.h
|
||||
|
|
Loading…
Add table
Reference in a new issue