0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-26 18:38:52 +02:00

ircd: Indicate noexcept on advised interfaces.

This commit is contained in:
Jason Volk 2019-08-05 16:15:56 -07:00
parent 86c4e2be36
commit 009d417273
14 changed files with 123 additions and 68 deletions

View file

@ -39,36 +39,36 @@ namespace ircd::ctx
IRCD_EXCEPTION(ircd::error, error)
IRCD_EXCEPTION(error, interrupted)
IRCD_EXCEPTION(error, timeout)
struct terminated {}; // Special exception
struct terminated {}; // Special exception
IRCD_OVERLOAD(threadsafe)
const uint64_t &id(const ctx &); // Unique ID for context
string_view name(const ctx &); // User's optional label for context
const size_t &stack_max(const ctx &); // Returns stack size allocated for ctx
const size_t &stack_at(const ctx &); // Stack at last sleep (also see this_ctx.h)
const int32_t &notes(const ctx &); // Peeks at internal semaphore count
const uint64_t &epoch(const ctx &); // Context switching counter
const ulong &cycles(const ctx &); // Accumulated tsc (not counting cur slice)
bool interruptible(const ctx &) noexcept; // Context can throw at interruption point
bool interruption(const ctx &) noexcept; // Context was marked for interruption
bool termination(const ctx &) noexcept; // Context was marked for termination
bool finished(const ctx &); // Context function returned (or exception).
bool started(const ctx &); // Context was ever entered.
bool running(const ctx &); // Context is the currently running ctx.
bool waiting(const ctx &); // started() && !finished() && !running()
bool queued(const ctx &); // !running() && notes() > 0
const uint64_t &id(const ctx &) noexcept; // Unique ID for context
string_view name(const ctx &) noexcept; // User's optional label for context
const size_t &stack_max(const ctx &) noexcept; // Returns stack size allocated for ctx
const size_t &stack_at(const ctx &) noexcept; // Stack at last sleep (also see this_ctx.h)
const int32_t &notes(const ctx &) noexcept; // Peeks at internal semaphore count
const uint64_t &epoch(const ctx &) noexcept; // Context switching counter
const ulong &cycles(const ctx &) noexcept; // Accumulated tsc (not counting cur slice)
bool interruptible(const ctx &) noexcept; // Context can throw at interruption point
bool interruption(const ctx &) noexcept; // Context was marked for interruption
bool termination(const ctx &) noexcept; // Context was marked for termination
bool finished(const ctx &) noexcept; // Context function returned (or exception).
bool started(const ctx &) noexcept; // Context was ever entered.
bool running(const ctx &) noexcept; // Context is the currently running ctx.
bool waiting(const ctx &) noexcept; // started() && !finished() && !running()
bool queued(const ctx &) noexcept; // !running() && notes() > 0
void interruptible(ctx &, const bool &); // False for interrupt suppression.
void interrupt(ctx &); // Interrupt the context.
void terminate(ctx &); // Interrupt for termination.
void signal(ctx &, std::function<void ()>); // Post function to context strand
void notify(ctx &, threadsafe_t); // Notify context with threadsafety.
bool notify(ctx &); // Queue a context switch to arg
void yield(ctx &); // Direct context switch to arg
void interruptible(ctx &, const bool &); // False for interrupt suppression.
void interrupt(ctx &); // Interrupt the context.
void terminate(ctx &); // Interrupt for termination.
void signal(ctx &, std::function<void ()>); // Post function to context strand
void notify(ctx &, threadsafe_t); // Notify context with threadsafety.
bool notify(ctx &) noexcept; // Queue a context switch to arg
void yield(ctx &); // Direct context switch to arg
bool for_each(const std::function<bool (ctx &)> &);
const uint64_t &epoch();
const uint64_t &epoch() noexcept;
extern log::log log;
}

View file

@ -32,27 +32,27 @@ namespace ircd::ctx::prof
enum class event :uint8_t;
struct ticker;
uint64_t cycles();
uint64_t cycles() noexcept;
string_view reflect(const event &);
// totals
const ticker &get();
const ticker &get() noexcept;
const uint64_t &get(const event &);
// specific context
const ticker &get(const ctx &c);
const ticker &get(const ctx &c) noexcept;
const uint64_t &get(const ctx &c, const event &);
// current slice state
const ulong &cur_slice_start();
ulong cur_slice_cycles();
const ulong &cur_slice_start() noexcept;
ulong cur_slice_cycles() noexcept;
// test accessors
bool slice_exceeded_warning(const ulong &cycles);
bool slice_exceeded_assertion(const ulong &cycles);
bool slice_exceeded_interrupt(const ulong &cycles);
bool stack_exceeded_warning(const size_t &size);
bool stack_exceeded_assertion(const size_t &size);
bool slice_exceeded_warning(const ulong &cycles) noexcept;
bool slice_exceeded_assertion(const ulong &cycles) noexcept;
bool slice_exceeded_interrupt(const ulong &cycles) noexcept;
bool stack_exceeded_warning(const size_t &size) noexcept;
bool stack_exceeded_assertion(const size_t &size) noexcept;
}
namespace ircd::ctx::prof::settings
@ -94,6 +94,7 @@ struct ircd::ctx::prof::ticker
inline uint64_t
ircd::ctx::prof::cur_slice_cycles()
noexcept
{
return cycles() - cur_slice_start();
}
@ -101,6 +102,7 @@ ircd::ctx::prof::cur_slice_cycles()
extern inline uint64_t
__attribute__((flatten, always_inline, gnu_inline, artificial))
ircd::ctx::prof::cycles()
noexcept
{
return ircd::prof::cycles();
}

View file

@ -15,13 +15,13 @@
namespace ircd::ctx {
inline namespace this_ctx
{
struct ctx &cur(); ///< Assumptional reference to *current
struct ctx &cur() noexcept; ///< Assumptional reference to *current
const uint64_t &id(); // Unique ID for cur ctx
string_view name(); // Optional label for cur ctx
ulong cycles(); // misc profiling related
ulong cycles() noexcept; // misc profiling related
bool interruption_requested(); // interruption(cur())
bool interruption_requested() noexcept; // interruption(cur())
void interruption_point(); // throws if interruption_requested()
void wait(); // Returns when context is woken up.
@ -128,6 +128,7 @@ ircd::ctx::this_ctx::wait(const duration &d)
inline ulong
ircd::ctx::this_ctx::cycles()
noexcept
{
return cycles(cur()) + prof::cur_slice_cycles();
}
@ -136,6 +137,7 @@ ircd::ctx::this_ctx::cycles()
/// context. Otherwise use the ctx::current pointer.
inline ircd::ctx::ctx &
ircd::ctx::this_ctx::cur()
noexcept
{
assert(current);
return *current;

View file

@ -31,11 +31,11 @@ namespace ircd
bool system_category(const boost::system::error_code &) noexcept;
bool is(const std::error_code &, const std::errc &) noexcept;
bool is(const boost::system::error_code &, const std::errc &) noexcept;
std::error_code make_error_code(const int &code = errno);
std::error_code make_error_code(const std::error_code &);
std::error_code make_error_code(const std::system_error &);
std::error_code make_error_code(const boost::system::error_code &);
std::error_code make_error_code(const boost::system::system_error &);
std::error_code make_error_code(const int &code = errno) noexcept;
std::error_code make_error_code(const std::error_code &) noexcept;
std::error_code make_error_code(const std::system_error &) noexcept;
std::error_code make_error_code(const boost::system::error_code &) noexcept;
std::error_code make_error_code(const boost::system::system_error &) noexcept;
std::system_error make_system_error(const int &code = errno);
std::system_error make_system_error(const std::errc &);
std::system_error make_system_error(const std::error_code &);

View file

@ -15,7 +15,7 @@ namespace ircd::fs
{
struct opts extern const opts_default;
int reqprio(int);
int reqprio(int) noexcept __attribute__((const));
}
/// Options common to all operations

View file

@ -54,8 +54,8 @@ namespace ircd::ios
bool is_static_thread();
void assert_main_thread();
bool available();
asio::io_context &get();
bool available() noexcept;
asio::io_context &get() noexcept;
void forked_parent();
void forked_child();

View file

@ -22,12 +22,12 @@ namespace ircd::prof
IRCD_OVERLOAD(sample)
// Samples
uint64_t cycles(); ///< Monotonic reference cycles (since system boot)
uint64_t time_user(); ///< Nanoseconds of CPU time in userspace.
uint64_t time_kern(); ///< Nanoseconds of CPU time in kernelland.
uint64_t time_real(); ///< Nanoseconds of CPU time real.
uint64_t time_proc(); ///< Nanoseconds of CPU time for process.
uint64_t time_thrd(); ///< Nanoseconds of CPU time for thread.
uint64_t cycles() noexcept; ///< Monotonic reference cycles (since system boot)
uint64_t time_user() noexcept; ///< Nanoseconds of CPU time in userspace.
uint64_t time_kern() noexcept; ///< Nanoseconds of CPU time in kernelland.
uint64_t time_real() noexcept; ///< Nanoseconds of CPU time real.
uint64_t time_proc(); ///< Nanoseconds of CPU time for process.
uint64_t time_thrd(); ///< Nanoseconds of CPU time for thread.
// Control panel
void stop(group &);
@ -89,11 +89,13 @@ struct ircd::prof::init
extern inline uint64_t
__attribute__((flatten, always_inline, gnu_inline, artificial))
ircd::prof::cycles()
noexcept
{
return x86::rdtsc();
}
#else
ircd::prof::cycles()
noexcept
{
static_assert(false, "Select reference cycle counter for platform.");
return 0;

View file

@ -14,21 +14,23 @@
/// X86 platform related
namespace ircd::prof::x86
{
unsigned long long rdpmc(const uint &);
unsigned long long rdtscp();
unsigned long long rdtsc();
unsigned long long rdpmc(const uint &) noexcept;
unsigned long long rdtscp() noexcept;
unsigned long long rdtsc() noexcept;
}
#if defined(__x86_64__) || defined(__i386__)
extern inline unsigned long long
__attribute__((always_inline, gnu_inline, artificial))
ircd::prof::x86::rdtsc()
noexcept
{
return __builtin_ia32_rdtsc();
}
#else
inline unsigned long long
ircd::prof::x86::rdtsc()
noexcept
{
return 0;
}
@ -38,6 +40,7 @@ ircd::prof::x86::rdtsc()
extern inline unsigned long long
__attribute__((always_inline, gnu_inline, artificial))
ircd::prof::x86::rdtscp()
noexcept
{
uint32_t ia32_tsc_aux;
return __builtin_ia32_rdtscp(&ia32_tsc_aux);
@ -45,6 +48,7 @@ ircd::prof::x86::rdtscp()
#else
inline unsigned long long
ircd::prof::x86::rdtscp()
noexcept
{
return 0;
}
@ -54,12 +58,14 @@ ircd::prof::x86::rdtscp()
extern inline unsigned long long
__attribute__((always_inline, gnu_inline, artificial))
ircd::prof::x86::rdpmc(const uint &c)
noexcept
{
return __builtin_ia32_rdpmc(c);
}
#else
inline unsigned long long
ircd::prof::x86::rdpmc(const uint &c)
noexcept
{
return 0;
}

View file

@ -234,6 +234,7 @@ ircd::ctx::ctx::wait()
/// while it's been suspended or false if it's already been notified.
bool
ircd::ctx::ctx::note()
noexcept
{
if(notes++ > 0)
return false;
@ -247,7 +248,7 @@ ircd::ctx::ctx::note()
/// Wakes a context without a note (internal)
bool
ircd::ctx::ctx::wake()
try
noexcept try
{
alarm.cancel();
return true;
@ -299,6 +300,7 @@ ircd::ctx::ctx::interruption_point()
// interrupted which simplifies the termination process.
bool
ircd::ctx::ctx::termination_point(std::nothrow_t)
noexcept
{
if(flags & context::TERMINATED)
{
@ -314,6 +316,7 @@ ircd::ctx::ctx::termination_point(std::nothrow_t)
/// clears the flag.
bool
ircd::ctx::ctx::interruption_point(std::nothrow_t)
noexcept
{
if(flags & context::INTERRUPTED)
{
@ -327,14 +330,14 @@ ircd::ctx::ctx::interruption_point(std::nothrow_t)
bool
ircd::ctx::ctx::started()
const
const noexcept
{
return stack.base != 0;
}
bool
ircd::ctx::ctx::finished()
const
const noexcept
{
return started() && yc == nullptr;
}
@ -346,6 +349,7 @@ const
const uint64_t &
ircd::ctx::epoch()
noexcept
{
return prof::get(prof::event::YIELD);
}
@ -397,6 +401,7 @@ ircd::ctx::notify(ctx &ctx,
/// directly to `ctx`.
bool
ircd::ctx::notify(ctx &ctx)
noexcept
{
return ctx.note();
}
@ -473,6 +478,7 @@ ircd::ctx::interruptible(ctx &ctx,
/// !running() && notes > 0
bool
ircd::ctx::queued(const ctx &ctx)
noexcept
{
return !running(ctx) && notes(ctx) > 0;
}
@ -480,6 +486,7 @@ ircd::ctx::queued(const ctx &ctx)
/// started() && !finished() && !running
bool
ircd::ctx::waiting(const ctx &ctx)
noexcept
{
return started(ctx) && !finished(ctx) && !running(ctx);
}
@ -487,6 +494,7 @@ ircd::ctx::waiting(const ctx &ctx)
/// Indicates if `ctx` is the current ctx
bool
ircd::ctx::running(const ctx &ctx)
noexcept
{
return &ctx == current;
}
@ -494,6 +502,7 @@ ircd::ctx::running(const ctx &ctx)
/// Indicates if `ctx` was ever jumped to
bool
ircd::ctx::started(const ctx &ctx)
noexcept
{
return ctx.started();
}
@ -501,6 +510,7 @@ ircd::ctx::started(const ctx &ctx)
/// Indicates if the base frame for `ctx` returned
bool
ircd::ctx::finished(const ctx &ctx)
noexcept
{
return ctx.finished();
}
@ -532,6 +542,7 @@ noexcept
/// Returns the cycle count for `ctx`
const ulong &
ircd::ctx::cycles(const ctx &ctx)
noexcept
{
return prof::get(ctx, prof::event::CYCLES);
}
@ -539,6 +550,7 @@ ircd::ctx::cycles(const ctx &ctx)
/// Returns the yield count for `ctx`
const uint64_t &
ircd::ctx::epoch(const ctx &ctx)
noexcept
{
return prof::get(ctx, prof::event::YIELD);
}
@ -546,6 +558,7 @@ ircd::ctx::epoch(const ctx &ctx)
/// Returns the notification count for `ctx`
const int32_t &
ircd::ctx::notes(const ctx &ctx)
noexcept
{
return ctx.notes;
}
@ -553,6 +566,7 @@ ircd::ctx::notes(const ctx &ctx)
/// Returns the notification count for `ctx`
const size_t &
ircd::ctx::stack_at(const ctx &ctx)
noexcept
{
return ctx.stack.at;
}
@ -560,6 +574,7 @@ ircd::ctx::stack_at(const ctx &ctx)
/// Returns the notification count for `ctx`
const size_t &
ircd::ctx::stack_max(const ctx &ctx)
noexcept
{
return ctx.stack.max;
}
@ -567,6 +582,7 @@ ircd::ctx::stack_max(const ctx &ctx)
/// Returns the developer's optional name literal for `ctx`
ircd::string_view
ircd::ctx::name(const ctx &ctx)
noexcept
{
return ctx.name;
}
@ -574,6 +590,7 @@ ircd::ctx::name(const ctx &ctx)
/// Returns a reference to unique ID for `ctx` (which will go away with `ctx`)
const uint64_t &
ircd::ctx::id(const ctx &ctx)
noexcept
{
return ctx.id;
}
@ -713,6 +730,7 @@ ircd::ctx::this_ctx::interruption_point()
/// the interrupt flag.
bool
ircd::ctx::this_ctx::interruption_requested()
noexcept
{
return interruption(cur()) || termination(cur());
}
@ -1560,15 +1578,15 @@ namespace ircd::ctx::prof
static void check_stack();
static void check_slice();
static void slice_enter();
static void slice_leave();
static void slice_enter() noexcept;
static void slice_leave() noexcept;
static void handle_cur_continue();
static void handle_cur_yield();
static void handle_cur_leave();
static void handle_cur_enter();
static void inc_ticker(const event &e);
static void inc_ticker(const event &e) noexcept;
}
// stack_usage_warning at 1/3 engineering tolerance
@ -1630,6 +1648,7 @@ ircd::ctx::prof::mark(const event &e)
void
ircd::ctx::prof::inc_ticker(const event &e)
noexcept
{
assert(uint8_t(e) < num_of<event>());
@ -1670,6 +1689,7 @@ ircd::ctx::prof::handle_cur_continue()
void
ircd::ctx::prof::slice_enter()
noexcept
{
assert(ctx::ios_desc.stats);
++ctx::ios_desc.stats->calls;
@ -1679,6 +1699,7 @@ ircd::ctx::prof::slice_enter()
void
ircd::ctx::prof::slice_leave()
noexcept
{
_slice_stop = cycles();
@ -1790,6 +1811,7 @@ ircd::ctx::prof::check_stack()
bool
ircd::ctx::prof::stack_exceeded_assertion(const size_t &stack_at)
noexcept
{
const auto &c(cur());
const auto &stack_max(c.stack.max);
@ -1801,6 +1823,7 @@ ircd::ctx::prof::stack_exceeded_assertion(const size_t &stack_at)
bool
ircd::ctx::prof::stack_exceeded_warning(const size_t &stack_at)
noexcept
{
const auto &c(cur());
const auto &stack_max(c.stack.max);
@ -1812,6 +1835,7 @@ ircd::ctx::prof::stack_exceeded_warning(const size_t &stack_at)
bool
ircd::ctx::prof::slice_exceeded_interrupt(const ulong &cycles)
noexcept
{
const ulong &threshold(settings::slice_interrupt);
return threshold > 0 && cycles >= threshold;
@ -1819,6 +1843,7 @@ ircd::ctx::prof::slice_exceeded_interrupt(const ulong &cycles)
bool
ircd::ctx::prof::slice_exceeded_assertion(const ulong &cycles)
noexcept
{
const ulong &threshold(settings::slice_assertion);
return threshold > 0 && cycles >= threshold;
@ -1826,6 +1851,7 @@ ircd::ctx::prof::slice_exceeded_assertion(const ulong &cycles)
bool
ircd::ctx::prof::slice_exceeded_warning(const ulong &cycles)
noexcept
{
const ulong &threshold(settings::slice_warning);
return threshold > 0 && cycles >= threshold;
@ -1833,6 +1859,7 @@ ircd::ctx::prof::slice_exceeded_warning(const ulong &cycles)
const ulong &
ircd::ctx::prof::cur_slice_start()
noexcept
{
return _slice_start;
}
@ -1846,6 +1873,7 @@ ircd::ctx::prof::get(const ctx &c,
const ircd::ctx::prof::ticker &
ircd::ctx::prof::get(const ctx &c)
noexcept
{
return c.profile;
}
@ -1858,6 +1886,7 @@ ircd::ctx::prof::get(const event &e)
const ircd::ctx::prof::ticker &
ircd::ctx::prof::get()
noexcept
{
return _total;
}

View file

@ -62,15 +62,15 @@ struct ircd::ctx::ctx
prof::ticker profile; // prof related structure
dock adjoindre; // contexts waiting for this to join()
bool started() const; // context was ever entered
bool finished() const; // context will not be further entered.
bool started() const noexcept; // context was ever entered
bool finished() const noexcept; // context will not be further entered.
bool interruption_point(std::nothrow_t); // Check for interrupt (and clear flag)
bool termination_point(std::nothrow_t); // Check for terminate
void interruption_point(); // throws interrupted or terminated
bool interruption_point(std::nothrow_t) noexcept;
bool termination_point(std::nothrow_t) noexcept;
void interruption_point();
bool wake(); // jump to context by queueing with ios (use note())
bool note(); // properly request wake()
bool wake() noexcept; // jump to context by queueing with ios (use note())
bool note() noexcept; // properly request wake()
bool wait(); // yield context to ios queue (returns on this resume)
void jump(); // jump to context directly (returns on your resume)

View file

@ -203,6 +203,7 @@ ircd::make_system_error(const int &code)
std::error_code
ircd::make_error_code(const boost::system::system_error &e)
noexcept
{
return std::error_code
{
@ -212,6 +213,7 @@ ircd::make_error_code(const boost::system::system_error &e)
std::error_code
ircd::make_error_code(const boost::system::error_code &ec)
noexcept
{
return std::error_code
{
@ -221,12 +223,14 @@ ircd::make_error_code(const boost::system::error_code &ec)
std::error_code
ircd::make_error_code(const std::system_error &e)
noexcept
{
return e.code();
}
std::error_code
ircd::make_error_code(const int &code)
noexcept
{
return std::error_code
{
@ -236,6 +240,7 @@ ircd::make_error_code(const int &code)
std::error_code
ircd::make_error_code(const std::error_code &ec)
noexcept
{
return ec;
}

View file

@ -1224,7 +1224,8 @@ ircd::fs::flags(const write_opts &opts)
namespace ircd::fs
{
static asio::posix::stream_descriptor::wait_type translate(const ready &);
static constexpr asio::posix::stream_descriptor::wait_type translate(const ready &) noexcept
__attribute__((const));
}
decltype(ircd::fs::wait_opts_default)
@ -1270,8 +1271,10 @@ ircd::fs::wait(const fd &fd,
throw_system_error(ec);
}
constexpr
boost::asio::posix::stream_descriptor::wait_type
ircd::fs::translate(const ready &ready)
noexcept
{
using wait_type = boost::asio::posix::stream_descriptor::wait_type;
@ -2415,6 +2418,7 @@ ircd::fs::posix_flags(const std::ios::openmode &mode)
/// shifts it to the AIO value.
int
ircd::fs::reqprio(int input)
noexcept
{
const auto &max_reqprio
{

View file

@ -483,6 +483,7 @@ ircd::ios::post::post(descriptor &descriptor,
boost::asio::io_context &
ircd::ios::get()
noexcept
{
assert(user);
return *user;
@ -490,6 +491,7 @@ ircd::ios::get()
bool
ircd::ios::available()
noexcept
{
return bool(user);
}

View file

@ -26,18 +26,21 @@ ircd::prof::enable
uint64_t
ircd::prof::time_real()
noexcept
{
return boost::chrono::process_real_cpu_clock::now().time_since_epoch().count();
}
uint64_t
ircd::prof::time_kern()
noexcept
{
return boost::chrono::process_system_cpu_clock::now().time_since_epoch().count();
}
uint64_t
ircd::prof::time_user()
noexcept
{
return boost::chrono::process_user_cpu_clock::now().time_since_epoch().count();
}