mirror of
https://github.com/matrix-construct/construct
synced 2025-02-16 16:50:12 +01:00
modules/media/magick: Add conf limit for CPU cycles of a running ImageMagick job.
This commit is contained in:
parent
55bc296068
commit
0def9bd5f1
1 changed files with 41 additions and 1 deletions
|
@ -33,6 +33,7 @@ namespace ircd::magick
|
||||||
static void fini();
|
static void fini();
|
||||||
|
|
||||||
extern conf::item<uint64_t> limit_span;
|
extern conf::item<uint64_t> limit_span;
|
||||||
|
extern conf::item<uint64_t> limit_cycles;
|
||||||
extern conf::item<uint64_t> yield_threshold;
|
extern conf::item<uint64_t> yield_threshold;
|
||||||
extern conf::item<uint64_t> yield_interval;
|
extern conf::item<uint64_t> yield_interval;
|
||||||
extern log::log log;
|
extern log::log log;
|
||||||
|
@ -74,6 +75,13 @@ ircd::magick::limit_span
|
||||||
{ "default", 10000L },
|
{ "default", 10000L },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
decltype(ircd::magick::limit_cycles)
|
||||||
|
ircd::magick::limit_cycles
|
||||||
|
{
|
||||||
|
{ "name", "ircd.magick.limit.cycles" },
|
||||||
|
{ "default", 0L },
|
||||||
|
};
|
||||||
|
|
||||||
decltype(ircd::magick::yield_threshold)
|
decltype(ircd::magick::yield_threshold)
|
||||||
ircd::magick::yield_threshold
|
ircd::magick::yield_threshold
|
||||||
{
|
{
|
||||||
|
@ -466,6 +474,8 @@ ircd::magick::call(function&& f,
|
||||||
namespace ircd::magick
|
namespace ircd::magick
|
||||||
{
|
{
|
||||||
static thread_local uint64_t job_ctr;
|
static thread_local uint64_t job_ctr;
|
||||||
|
static thread_local uint64_t job_cycles;
|
||||||
|
static thread_local uint64_t last_cycles;
|
||||||
static thread_local int64_t last_quantum;
|
static thread_local int64_t last_quantum;
|
||||||
static thread_local uint64_t last_yield;
|
static thread_local uint64_t last_yield;
|
||||||
}
|
}
|
||||||
|
@ -477,12 +487,23 @@ ircd::magick::handle_progress(const char *text,
|
||||||
ExceptionInfo *ei)
|
ExceptionInfo *ei)
|
||||||
noexcept try
|
noexcept try
|
||||||
{
|
{
|
||||||
|
// Sample the current reference cycle count first and once. This is an
|
||||||
|
// accumulated cycle count for only this ircd::ctx and the current slice,
|
||||||
|
// (all other cycles are not accumulated here) which is non-zero by now
|
||||||
|
// and monotonically increases across jobs as well.
|
||||||
|
const auto cur_cycles
|
||||||
|
{
|
||||||
|
cycles(ctx::cur()) + ctx::prof::cur_slice_cycles()
|
||||||
|
};
|
||||||
|
|
||||||
// This is a new job; reset any global state here
|
// This is a new job; reset any global state here
|
||||||
if(quantum == 0)
|
if(quantum == 0)
|
||||||
{
|
{
|
||||||
++job_ctr;
|
++job_ctr;
|
||||||
last_quantum = 0;
|
last_quantum = 0;
|
||||||
last_yield = 0;
|
last_yield = 0;
|
||||||
|
job_cycles = 0;
|
||||||
|
last_cycles = cur_cycles;
|
||||||
|
|
||||||
// This job is too large based on the span measurement. This is an ad hoc
|
// This job is too large based on the span measurement. This is an ad hoc
|
||||||
// measurement of the job size created internally by ImageMagick.
|
// measurement of the job size created internally by ImageMagick.
|
||||||
|
@ -496,18 +517,37 @@ noexcept try
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the cycle counters first so the log::debug has better info.
|
||||||
|
assert(cur_cycles >= last_cycles);
|
||||||
|
job_cycles += cur_cycles - last_cycles;
|
||||||
|
last_cycles = cur_cycles;
|
||||||
|
|
||||||
#ifdef IRCD_MAGICK_DEBUG_PROGRESS
|
#ifdef IRCD_MAGICK_DEBUG_PROGRESS
|
||||||
log::debug
|
log::debug
|
||||||
{
|
{
|
||||||
log, "job:%lu progress %2.2lf%% (%ld/%ld) :%s",
|
log, "job:%lu progress %2.2lf%% (%ld/%ld) cycles:%lu :%s",
|
||||||
job_ctr,
|
job_ctr,
|
||||||
(quantum / double(span) * 100.0),
|
(quantum / double(span) * 100.0),
|
||||||
quantum,
|
quantum,
|
||||||
span,
|
span,
|
||||||
|
job_cycles,
|
||||||
text,
|
text,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Check if job exceeded its reference cycle limit if enabled.
|
||||||
|
if(unlikely(uint64_t(limit_cycles) && job_cycles > uint64_t(limit_cycles)))
|
||||||
|
throw error
|
||||||
|
{
|
||||||
|
"job:%lu CPU cycles:%lu exceeded server limit:%lu (progress %2.2lf%% (%ld/%ld))",
|
||||||
|
job_ctr,
|
||||||
|
job_cycles,
|
||||||
|
uint64_t(limit_cycles),
|
||||||
|
(quantum / double(span) * 100.0),
|
||||||
|
quantum,
|
||||||
|
span,
|
||||||
|
};
|
||||||
|
|
||||||
// This is a larger job; we yield this ircd::ctx at interval
|
// This is a larger job; we yield this ircd::ctx at interval
|
||||||
if(span > uint64_t(yield_threshold))
|
if(span > uint64_t(yield_threshold))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue