From 8a0fbd4e8979e64cb06678f8618a5ee11c87864c Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 28 Sep 2018 13:16:46 -0400 Subject: [PATCH] Add --enable-experiment= and MONO_EXPERIMENT= support Experiments are unsupported and provide no stability or backward compatability guarantees. --- configure.ac | 20 +++++++++++++++ mono/utils/Makefile.am | 4 ++- mono/utils/mono-experiments.c | 54 +++++++++++++++++++++++++++++++++++++++++ mono/utils/mono-experiments.def | 32 ++++++++++++++++++++++++ mono/utils/mono-experiments.h | 29 ++++++++++++++++++++++ 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 mono/utils/mono-experiments.c create mode 100644 mono/utils/mono-experiments.def create mode 100644 mono/utils/mono-experiments.h diff --git a/configure.ac b/configure.ac index 59cb1fa2f73..c55136d9055 100644 --- a/configure.ac +++ b/configure.ac @@ -5033,6 +5033,26 @@ AM_CONDITIONAL([ENABLE_HYBRID_SUSPEND], [test x$enable_hybrid_suspend != xno]) dnl End of thread suspend policy +dnl *************************** +dnl *** feature experiments *** +dnl *************************** + +dnl When adding experiments, also add to mono/utils/mono-experiments.def +AC_ARG_ENABLE(experiment, [ --enable-experiment=LIST Enable experimental fatures from the comma-separate LIST. Available experiments: ],[ + + if test x$enable_experiment != x ; then + AC_DEFINE(ENABLE_EXPERIMENTS,1,[Enable feature experiments]) + fi + for feature in `echo "$enable_experiment" | sed -e "s/,/ /g"`; do + eval "mono_experiment_test_enable_$feature='yes'" + done + + if test "x$mono_experiment_test_enable_all" = "xyes"; then + true + fi + +],[]) + dnl ********************** dnl *** checked builds *** dnl ********************** diff --git a/mono/utils/Makefile.am b/mono/utils/Makefile.am index 6efa0ba5e25..d5ed57941ad 100644 --- a/mono/utils/Makefile.am +++ b/mono/utils/Makefile.am @@ -71,6 +71,8 @@ monoutils_sources = \ mono-dl-wasm.c \ mono-dl.h \ mono-dl-windows-internals.h \ + mono-experiments.h \ + mono-experiments.c \ mono-log-windows.c \ mono-log-common.c \ mono-log-posix.c \ @@ -321,7 +323,7 @@ libmonoutilsinclude_HEADERS = \ mono-dl-fallback.h \ mono-counters.h -EXTRA_DIST = mono-embed.h mono-embed.c ../../support/libm/complex.c +EXTRA_DIST = mono-embed.h mono-embed.c ../../support/libm/complex.c mono-experiments.def DIST_SUBDIRS = jemalloc diff --git a/mono/utils/mono-experiments.c b/mono/utils/mono-experiments.c new file mode 100644 index 00000000000..5f83034032b --- /dev/null +++ b/mono/utils/mono-experiments.c @@ -0,0 +1,54 @@ + +#include "config.h" +#include +#include "mono/utils/mono-lazy-init.h" +#include "mono/utils/mono-experiments.h" + +mono_lazy_init_t mono_experiments_enabled_init; + +guint8 mono_experiments_enabled_table[] = { +#define EXPERIMENT(id,ghurl) 0, +#include "mono-experiments.def" +#undef EXPERIMENT +}; + +static +const char* mono_experiment_names[] = { +#define EXPERIMENT(id,ghurl) #id, +#include "mono-experiments.def" +#undef EXPERIMENT +}; + +static int +lookup_experiment_by_name (const char *exp_name) +{ + /* slow loop, but we only do this once, on demand. */ + for (int i = 0; i < MONO_EXPERIMENT_NUM_EXPERIMENTS; i++) { + if (!strcmp (mono_experiment_names[i], exp_name)) + return i; + } + return -1; +} + +void +mono_experiments_initialize_table (void) +{ + char *str = g_getenv ("MONO_EXPERIMENT"); + if (str == NULL) + return; + char **experiments = g_strsplit (str, ",", 0); + + char **exp_name = &experiments[0]; + while (*exp_name) { + int exp_id = lookup_experiment_by_name (*exp_name); + if (exp_id < 0) { + g_warning ("This version of Mono does not include experiment '%s'. Experiments have no stability, backward compatability or deprecation guarantees.", *exp_name); + } else { + mono_experiments_enabled_table [exp_id] = 1; + } + exp_name++; + } + + g_free (str); + g_strfreev (experiments); +} diff --git a/mono/utils/mono-experiments.def b/mono/utils/mono-experiments.def new file mode 100644 index 00000000000..5d9363f8f95 --- /dev/null +++ b/mono/utils/mono-experiments.def @@ -0,0 +1,32 @@ +/* + * Mono Experiments. + * + * Experiments are UNSUPPORTED. Do not rely on experiments in production. + * Experiments are not guaranteed to be stable, backward compatible or + * available in future versions of Mono. + * + */ + +/* Defining experiments: + * use the EXPERIMENT(id,"GH link") format. + * + * id: a unique identifier for the experiment. Will be used in the + * MONO_EXPERIMENT=id1,id2,... environment variable to enable an experiment at + * runtime and a MONO_EXPERIMENT_id enumeration value that can be used to check + * for whether an experiment is enabled. + * + * GH Link: a URL of a GitHub tracking issue for the experiment. The issue is + * closed when the experiment is removed from Mono. + * + * To add a compile-time check for an experiment, see configure.ac macro AC_ARG_ENABLE(experiment,...) + * To add a new compile-time constant ENABLE_EXPERIMENT_myfeaturename: + * 1. Add eval "mono_experiment_test_enable_myfeaturename='yes'" to the mono_experiment_test_enable_all block + * 2. Add a block like + * if test "x$mono_experiment_test_enable_myfeaturename" = "xyes"; then + * AC_DEFINE(ENABLE_EXPERIMENT_myfeaturename, 1, [Enable experiment 'myfeaturename']) + * fi + * 3. use both `#if defined (ENABLE_EXPERIMENT_myfeaturename)` and + * `if (mono_experiment_enabled (MONO_EXPERIMENT_myfeaturename))` to check that the experiment + * is compiled in and also enabled at runtime. + * It is optional to add the compile-time check, but if you add it, add the runtime check too. + */ diff --git a/mono/utils/mono-experiments.h b/mono/utils/mono-experiments.h new file mode 100644 index 00000000000..30cd4b1e978 --- /dev/null +++ b/mono/utils/mono-experiments.h @@ -0,0 +1,29 @@ + +#ifndef _MONO_EXPERIMENTS_H_ +#define _MONO_EXPERIMENTS_H_ + +#include + +#include "mono/utils/mono-lazy-init.h" + + +extern mono_lazy_init_t mono_experiments_enabled_init; + +extern guint8 mono_experiments_enabled_table[]; + +void mono_experiments_initialize_table (void); + +static inline gboolean +mono_experiment_enabled (int experiment_id) { + mono_lazy_initialize (&mono_experiments_enabled_init, mono_experiments_initialize_table); + return !!mono_experiments_enabled_table[experiment_id]; +} + +typedef enum MonoExperimentId { +#define EXPERIMENT(id,ghurl) MONO_EXPERIMENT_ ## id , +#include "mono-experiments.def" +#undef EXPERIMENT + MONO_EXPERIMENT_NUM_EXPERIMENTS +} MonoExperimentId; + +#endif -- 2.11.4.GIT