0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-19 19:33:45 +02:00

ircd::ios: ABI simplify; fix double-indirection, AGU load, code size on context switch.

This commit is contained in:
Jason Volk 2023-03-20 10:12:29 -07:00
parent 82482278fb
commit 14f55f6110
5 changed files with 61 additions and 51 deletions

View file

@ -29,14 +29,14 @@ struct ircd::ios::descriptor
static uint64_t ids; static uint64_t ids;
static void *default_allocator(handler &, const size_t &); static void *default_allocator(handler &, const size_t);
static void default_deallocator(handler &, void *const &, const size_t &) noexcept; static void default_deallocator(handler &, void *, const size_t) noexcept;
string_view name; string_view name;
uint64_t id {++ids}; uint64_t id {++ids};
std::unique_ptr<struct stats> stats; std::unique_ptr<struct stats> stats;
void *(*allocator)(handler &, const size_t &); void *(*allocator)(handler &, const size_t);
void (*deallocator)(handler &, void *const &, const size_t &); void (*deallocator)(handler &, void *, const size_t);
std::vector<std::array<uint64_t, 2>> history; // epoch, cycles std::vector<std::array<uint64_t, 2>> history; // epoch, cycles
uint8_t history_pos {0}; uint8_t history_pos {0};
bool continuation {false}; bool continuation {false};
@ -72,10 +72,10 @@ struct ircd::ios::descriptor::stats
item alloc_bytes; item alloc_bytes;
item frees; item frees;
item free_bytes; item free_bytes;
item slice_total;
item slice_last; item slice_last;
item latency_total; item slice_total;
item latency_last; item latency_last;
item latency_total;
stats(descriptor &); stats(descriptor &);
stats() = delete; stats() = delete;
@ -87,8 +87,8 @@ struct ircd::ios::descriptor::stats
[[gnu::hot]] [[gnu::hot]]
inline void inline void
ircd::ios::descriptor::default_deallocator(handler &handler, ircd::ios::descriptor::default_deallocator(handler &handler,
void *const &ptr, void *const ptr,
const size_t &size) const size_t size)
noexcept noexcept
{ {
#ifdef __clang__ #ifdef __clang__
@ -101,7 +101,7 @@ noexcept
[[gnu::hot]] [[gnu::hot]]
inline void * inline void *
ircd::ios::descriptor::default_allocator(handler &handler, ircd::ios::descriptor::default_allocator(handler &handler,
const size_t &size) const size_t size)
{ {
return ::operator new(size); return ::operator new(size);
} }

View file

@ -28,13 +28,13 @@ struct ircd::ios::handler
static thread_local handler *current; static thread_local handler *current;
static thread_local uint64_t epoch; static thread_local uint64_t epoch;
static void enqueue(handler *const &) noexcept; static void enqueue(handler *) noexcept;
static void *allocate(handler *const &, const size_t &); static void *allocate(handler *, const size_t);
static void deallocate(handler *const &, void *const &, const size_t &) noexcept; static void deallocate(handler *, void *, const size_t) noexcept;
static bool continuation(handler *const &) noexcept; static bool continuation(handler *) noexcept;
static void enter(handler *const &) noexcept; static void enter(handler *) noexcept;
static void leave(handler *const &) noexcept; static void leave(handler *) noexcept;
static bool fault(handler *const &) noexcept; static bool fault(handler *) noexcept;
ios::descriptor *descriptor {nullptr}; ios::descriptor *descriptor {nullptr};
uint64_t ts {0}; // last tsc sample; for profiling each phase uint64_t ts {0}; // last tsc sample; for profiling each phase
@ -91,9 +91,9 @@ const
[[gnu::hot]] [[gnu::hot]]
inline void inline void
ircd::ios::handler::deallocate(handler *const &handler, ircd::ios::handler::deallocate(handler *const handler,
void *const &ptr, void *const ptr,
const size_t &size) const size_t size)
noexcept noexcept
{ {
assert(handler && handler->descriptor); assert(handler && handler->descriptor);
@ -110,8 +110,8 @@ noexcept
[[gnu::hot]] [[gnu::hot]]
inline void * inline void *
ircd::ios::handler::allocate(handler *const &handler, ircd::ios::handler::allocate(handler *const handler,
const size_t &size) const size_t size)
{ {
assert(handler && handler->descriptor); assert(handler && handler->descriptor);
auto &descriptor(*handler->descriptor); auto &descriptor(*handler->descriptor);
@ -127,7 +127,7 @@ ircd::ios::handler::allocate(handler *const &handler,
[[gnu::hot]] [[gnu::hot]]
inline void inline void
ircd::ios::handler::enqueue(handler *const &handler) ircd::ios::handler::enqueue(handler *const handler)
noexcept noexcept
{ {
assert(handler && handler->descriptor); assert(handler && handler->descriptor);
@ -152,7 +152,7 @@ noexcept
[[gnu::hot]] [[gnu::hot]]
inline bool inline bool
ircd::ios::handler::continuation(handler *const &handler) ircd::ios::handler::continuation(handler *const handler)
noexcept noexcept
{ {
assert(handler && handler->descriptor); assert(handler && handler->descriptor);

View file

@ -30,6 +30,7 @@ namespace ircd::ios
extern asio::executor user, main; extern asio::executor user, main;
extern std::thread::id main_thread_id; extern std::thread::id main_thread_id;
extern thread_local bool is_main_thread; extern thread_local bool is_main_thread;
extern bool user_available, main_available;
bool available() noexcept; bool available() noexcept;
const uint64_t &epoch() noexcept; const uint64_t &epoch() noexcept;
@ -64,3 +65,11 @@ noexcept
{ {
return handler::epoch; return handler::epoch;
} }
inline bool
__attribute__((always_inline))
ircd::ios::available()
noexcept
{
return main_available;
}

View file

@ -689,7 +689,7 @@ ircd::fs::aio::system::handle_descriptor
// appears to excessively allocate and deallocate 120 bytes; this // appears to excessively allocate and deallocate 120 bytes; this
// is a simple asynchronous operation, we can do better (and perhaps // is a simple asynchronous operation, we can do better (and perhaps
// even better than this below). // even better than this below).
[](ios::handler &handler, const size_t &size) -> void * [](ios::handler &handler, const size_t size) -> void *
{ {
assert(ircd::fs::aio::system); assert(ircd::fs::aio::system);
auto &system(*ircd::fs::aio::system); auto &system(*ircd::fs::aio::system);
@ -705,7 +705,7 @@ ircd::fs::aio::system::handle_descriptor
}, },
// no deallocation; satisfied by class member unique_ptr // no deallocation; satisfied by class member unique_ptr
[](ios::handler &handler, void *const &ptr, const size_t &size) {}, [](ios::handler &handler, void *const ptr, const size_t size) {},
// continuation // continuation
true, true,

View file

@ -39,6 +39,14 @@ ircd::ios::primary;
decltype(ircd::ios::main) decltype(ircd::ios::main)
ircd::ios::main; ircd::ios::main;
/// Indicates the user asio::executor is initialized.
decltype(ircd::ios::user_available)
ircd::ios::user_available;
/// Indicates the main asio::executor is initialized.
decltype(ircd::ios::main_available)
ircd::ios::main_available;
decltype(ircd::boost_version_api) decltype(ircd::boost_version_api)
ircd::boost_version_api ircd::boost_version_api
{ {
@ -71,12 +79,14 @@ ircd::ios::init(asio::executor &&user)
// Save a reference handle to the user's executor. // Save a reference handle to the user's executor.
ios::user = user; ios::user = user;
ios::user_available = bool(ios::user);
// Create our strand instance. // Create our strand instance.
ios::primary.emplace(static_cast<asio::io_context &>(user.context())); ios::primary.emplace(static_cast<asio::io_context &>(user.context()));
// Set the reference handle to our executor. // Set the reference handle to our executor.
ios::main = *ios::primary; ios::main = *ios::primary;
ios::main_available = bool(ios::main);
} }
[[using gnu: cold]] [[using gnu: cold]]
@ -180,13 +190,6 @@ ircd::ios::forked_parent()
#endif #endif
} }
bool
ircd::ios::available()
noexcept
{
return bool(main);
}
// //
// emption // emption
// //
@ -480,13 +483,6 @@ ircd::ios::descriptor::stats::stats(descriptor &d)
{ "name", stats_name(d, "free_bytes") }, { "name", stats_name(d, "free_bytes") },
}, },
} }
,slice_total
{
value + items++,
{
{ "name", stats_name(d, "slice_total") },
},
}
,slice_last ,slice_last
{ {
value + items++, value + items++,
@ -494,11 +490,11 @@ ircd::ios::descriptor::stats::stats(descriptor &d)
{ "name", stats_name(d, "slice_last") }, { "name", stats_name(d, "slice_last") },
}, },
} }
,latency_total ,slice_total
{ {
value + items++, value + items++,
{ {
{ "name", stats_name(d, "latency_total") }, { "name", stats_name(d, "slice_total") },
}, },
} }
,latency_last ,latency_last
@ -508,6 +504,13 @@ ircd::ios::descriptor::stats::stats(descriptor &d)
{ "name", stats_name(d, "latency_last") }, { "name", stats_name(d, "latency_last") },
}, },
} }
,latency_total
{
value + items++,
{
{ "name", stats_name(d, "latency_total") },
},
}
{ {
assert(items <= (sizeof(value) / sizeof(value[0]))); assert(items <= (sizeof(value) / sizeof(value[0])));
} }
@ -531,7 +534,7 @@ ircd::ios::handler::epoch;
[[gnu::cold]] [[gnu::cold]]
bool bool
ircd::ios::handler::fault(handler *const &handler) ircd::ios::handler::fault(handler *const handler)
noexcept noexcept
{ {
assert(handler && handler->descriptor); assert(handler && handler->descriptor);
@ -568,7 +571,7 @@ noexcept
[[gnu::hot]] [[gnu::hot]]
void void
ircd::ios::handler::leave(handler *const &handler) ircd::ios::handler::leave(handler *const handler)
noexcept noexcept
{ {
assert(handler && handler->descriptor); assert(handler && handler->descriptor);
@ -619,19 +622,14 @@ noexcept
[[gnu::hot]] [[gnu::hot]]
void void
ircd::ios::handler::enter(handler *const &handler) ircd::ios::handler::enter(handler *const handler)
noexcept noexcept
{ {
assert(!handler::current);
handler::current = handler;
++handler::epoch;
assert(handler && handler->descriptor); assert(handler && handler->descriptor);
auto &descriptor(*handler->descriptor); auto &descriptor(*handler->descriptor);
assert(descriptor.stats); assert(descriptor.stats);
auto &stats(*descriptor.stats); auto &stats(*descriptor.stats);
++stats.calls;
const auto last_ts const auto last_ts
{ {
@ -640,6 +638,11 @@ noexcept
stats.latency_last = handler->ts - last_ts; stats.latency_last = handler->ts - last_ts;
stats.latency_total += stats.latency_last; stats.latency_total += stats.latency_last;
++stats.calls;
assert(!handler::current);
handler::current = handler;
++handler::epoch;
if constexpr(profile::logging) if constexpr(profile::logging)
log::logf log::logf
@ -696,7 +699,6 @@ ircd::ios::dispatch::dispatch(descriptor &descriptor,
latch.wait(); latch.wait();
} }
[[gnu::hot]]
ircd::ios::dispatch::dispatch(descriptor &descriptor, ircd::ios::dispatch::dispatch(descriptor &descriptor,
defer_t, defer_t,
std::function<void ()> function) std::function<void ()> function)
@ -725,7 +727,6 @@ ircd::ios::dispatch::dispatch(descriptor &descriptor,
}; };
} }
[[gnu::hot]]
ircd::ios::dispatch::dispatch(descriptor &descriptor, ircd::ios::dispatch::dispatch(descriptor &descriptor,
std::function<void ()> function) std::function<void ()> function)
{ {