summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2023-07-28 15:20:58 -0700
committerVito Caputo <vcaputo@pengaru.com>2023-07-28 16:34:18 -0700
commit5221c25be67ee96a747c4e527436c0daa394a44e (patch)
tree88baa2f1310d0fe140e578009b44d012ba71dd91 /src
parentddb8c7e9ef62a699646745273b0e28324ddde455 (diff)
til: introduce til_module_render_limited() variant
With the introduction of discoverable on-stream contexts, with the intention of modules finding them at runtime for nested rendering, relying exclusively on limiting n_cpus @ til_module_create_context() is no longer adequate. When the nested rendering makes use of a context created elsewhere, it can't make any assumptions about what its n_cpus is, nor should it be attempting to change that value for its use. So this variant just adds a max_cpus parameter for setting an upper bound to whatever is found in the context's n_cpus. The impetus for this is to fix the ref builtin, which you can currently trick into deadlock by performing a nested threaded render within a threaded render. What the ref module should be doing is propagating its own context's n_cpus down as the upper bound, via this new render variant.
Diffstat (limited to 'src')
-rw-r--r--src/til.c30
-rw-r--r--src/til.h1
2 files changed, 24 insertions, 7 deletions
diff --git a/src/til.c b/src/til.c
index d374759..b4a903c 100644
--- a/src/til.c
+++ b/src/til.c
@@ -386,7 +386,7 @@ char * til_get_module_names(unsigned flags_excluded, const char **exclusions)
}
-static void module_render_fragment(til_module_context_t *context, til_stream_t *stream, til_threads_t *threads, unsigned ticks, til_fb_fragment_t **fragment_ptr)
+static void module_render_fragment(til_module_context_t *context, til_stream_t *stream, til_threads_t *threads, unsigned n_cpus, unsigned ticks, til_fb_fragment_t **fragment_ptr)
{
const til_module_t *module;
int touched = 0;
@@ -395,6 +395,7 @@ static void module_render_fragment(til_module_context_t *context, til_stream_t *
assert(context->module);
assert(threads);
assert(fragment_ptr && *fragment_ptr);
+ assert(n_cpus);
module = context->module;
@@ -409,7 +410,7 @@ static void module_render_fragment(til_module_context_t *context, til_stream_t *
assert(frame_plan.fragmenter);
assert(module->render_fragment);
- if (context->n_cpus > 1) {
+ if (n_cpus > 1) {
til_threads_frame_submit(threads, fragment_ptr, &frame_plan, module->render_fragment, context, stream, ticks);
til_threads_wait_idle(threads);
} else {
@@ -437,14 +438,11 @@ static void module_render_fragment(til_module_context_t *context, til_stream_t *
}
-/* This is a public interface to the threaded module rendering intended for use by
- * modules that wish to get the output of other modules for their own use.
- */
-void til_module_render(til_module_context_t *context, til_stream_t *stream, unsigned ticks, til_fb_fragment_t **fragment_ptr)
+static void _til_module_render(til_module_context_t *context, til_stream_t *stream, unsigned n_cpus, unsigned ticks, til_fb_fragment_t **fragment_ptr)
{
unsigned start = til_ticks_now();
- module_render_fragment(context, stream, til_threads, ticks, fragment_ptr);
+ module_render_fragment(context, stream, til_threads, n_cpus, ticks, fragment_ptr);
context->last_render_duration = til_ticks_now() - start;
if (context->last_render_duration > context->max_render_duration)
@@ -454,6 +452,24 @@ void til_module_render(til_module_context_t *context, til_stream_t *stream, unsi
}
+/* This is a public interface to the threaded module rendering intended for use by
+ * modules that wish to get the output of other modules for their own use.
+ */
+void til_module_render(til_module_context_t *context, til_stream_t *stream, unsigned ticks, til_fb_fragment_t **fragment_ptr)
+{
+ return _til_module_render(context, stream, context->n_cpus, ticks, fragment_ptr);
+}
+
+
+/* Identical to til_module_render() except with a parameterized upper bound for context->c_cpus,
+ * this is primarily intended for modules performing nested rendering
+ */
+void til_module_render_limited(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned max_cpus, til_fb_fragment_t **fragment_ptr)
+{
+ return _til_module_render(context, stream, MIN(context->n_cpus, max_cpus), ticks, fragment_ptr);
+}
+
+
/* if n_cpus == 0, it will be automatically set to n_threads.
* to explicitly set n_cpus, just pass the value. This is primarily intended for
* the purpose of explicitly constraining rendering parallelization to less than n_threads,
diff --git a/src/til.h b/src/til.h
index eea8009..ec078db 100644
--- a/src/til.h
+++ b/src/til.h
@@ -45,6 +45,7 @@ const til_module_t * til_lookup_module(const char *name);
void til_get_modules(const til_module_t ***res_modules, size_t *res_n_modules);
char * til_get_module_names(unsigned flags_excluded, const char **exclusions);
void til_module_render(til_module_context_t *context, til_stream_t *stream, unsigned ticks, til_fb_fragment_t **fragment_ptr);
+void til_module_render_limited(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned max_cpus, til_fb_fragment_t **fragment_ptr);
int til_module_create_contexts(const til_module_t *module, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup, size_t n_contexts, til_module_context_t **res_contexts);
int til_module_create_context(const til_module_t *module, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup, til_module_context_t **res_context);
til_module_context_t * til_module_destroy_context(til_module_context_t *context, til_stream_t *stream);
© All Rights Reserved