summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorRemy Noel <mocramis@gmail.com>2018-02-25 17:16:37 +0100
committerRemy Noel <mocramis@gmail.com>2018-02-25 17:25:49 +0100
commitcba7db6931932953fd0113a70019049234eb0b08 (patch)
tree6d0c14e881cee20e0dca1807b6177d5246eb3f85 /tools
parent652168fe3d867eec17ac7fa318c8743d524ef40f (diff)
parente8265363384bc3f8e6bb31466a3590ce27811efa (diff)
Merge branch 'master' into perfmon
Diffstat (limited to 'tools')
-rwxr-xr-xtools/build_configs.py150
1 files changed, 111 insertions, 39 deletions
diff --git a/tools/build_configs.py b/tools/build_configs.py
index 42124a9..04f278c 100755
--- a/tools/build_configs.py
+++ b/tools/build_configs.py
@@ -37,26 +37,33 @@ def gen_configs_values_str(options_dict):
# to all generated strings.
def gen_cc_options_list(options_dict):
return map(lambda x: '%s -Werror' % x, gen_configs_values_str(options_dict))
+def gen_exclusive_boolean_filter(args):
+ enabled_option, options_list = args
+ filter = dict()
-# Check whether a filter prototype is valid.
-#
-# A filter prototype is a list of (name, value) pairs used to build a filter.
-# Keep in mind that a valid filter must match invalid configurations. As a
-# result, a filter prototype is valid if and only if
-# - all options are included in the given list, and
-# - the number of enabled options is not 1
-def check_exclusive_boolean_filter(prototype):
- return (len(set(map(lambda x: x[0], prototype))) == len(prototype)
- and len(filter(lambda x: x[1][1] == 'y', prototype)) != 1)
-
-# Generate a list of filters on a list of boolean options.
+ for option in options_list:
+ if option == enabled_option:
+ value = [True, 'y']
+ else:
+ value = [True, 'n']
+
+ filter.update({option : value})
+
+ return filter
+
+# Generate a list of passing filters on a list of boolean options.
#
-# The resulting filters match configurations that don't have one and only
-# one of the given options enabled.
-def gen_exclusive_boolean_filters_list(options_list):
- product = itertools.product(options_list, [[True, 'y'], [True, 'n']])
- prototypes = list(itertools.combinations(product, len(options_list)))
- return map(dict, filter(check_exclusive_boolean_filter, prototypes))
+# The resulting filters match configurations that have only one of the given
+# options enabled, unless all_disabled is true, in which case an additional
+# filter is generated to match configurations where none of the options
+# are enabled.
+def gen_exclusive_boolean_filters_list(options_list, all_disabled=False):
+ option_and_options = map(lambda x: (x, options_list), options_list)
+
+ if all_disabled:
+ option_and_options += [(None, options_list)]
+
+ return map(gen_exclusive_boolean_filter, option_and_options)
# Dictionary of compiler options.
#
@@ -96,18 +103,48 @@ large_options_dict.update({
'CONFIG_THREAD_STACK_GUARD' : ['y', 'n'],
})
+test_list = [
+ 'CONFIG_TEST_MODULE_MUTEX',
+ 'CONFIG_TEST_MODULE_MUTEX_PI',
+ 'CONFIG_TEST_MODULE_PMAP_UPDATE_MP',
+ 'CONFIG_TEST_MODULE_RCU_DEFER',
+ 'CONFIG_TEST_MODULE_SREF_DIRTY_ZEROES',
+ 'CONFIG_TEST_MODULE_SREF_NOREF',
+ 'CONFIG_TEST_MODULE_SREF_WEAKREF',
+ 'CONFIG_TEST_MODULE_VM_PAGE_FILL',
+ 'CONFIG_TEST_MODULE_XCALL',
+]
+
+test_options_dict = dict(small_options_dict)
+
+for test in test_list:
+ test_options_dict.update({test : ['y', 'n']})
+
all_options_sets = {
'small' : small_options_dict,
'large' : large_options_dict,
+ 'test' : test_options_dict,
}
-# List of filters used to determine valid configurations.
+# Filters.
#
-# Each entry is a dictionary of options. The key matches an option name
-# whereas the value is a [match_flag, string/regular expression] list.
-# The match flag is true if the matching expression must match, false
-# otherwise.
-all_filters_list = [
+# A filter is a list of dictionaries of options. For each dictionary, the
+# key matches an option name whereas the value is a
+# [match_flag, string/regular expression] list. The match flag is true if
+# the matching expression must match, false otherwise.
+#
+# Passing filters are used to allow configurations that match the filters,
+# whereras blocking filters allow configurations that do not match.
+
+passing_filters_list = gen_exclusive_boolean_filters_list([
+ 'CONFIG_MUTEX_ADAPTIVE',
+ 'CONFIG_MUTEX_PI',
+ 'CONFIG_MUTEX_PLAIN',
+])
+passing_filters_list += gen_exclusive_boolean_filters_list(test_list,
+ all_disabled=True)
+
+blocking_filters_list = [
# XXX Clang currently cannot build the kernel with LTO.
{
'CONFIG_CC_EXE' : [True, 'clang'],
@@ -126,11 +163,6 @@ all_filters_list = [
'CONFIG_X86_PAE' : [True, 'y'],
},
]
-all_filters_list += gen_exclusive_boolean_filters_list([
- 'CONFIG_MUTEX_ADAPTIVE',
- 'CONFIG_MUTEX_PI',
- 'CONFIG_MUTEX_PLAIN'
-])
def gen_config_line(config_entry):
name, value = config_entry
@@ -183,34 +215,73 @@ def test_config(args):
return [retval, buildtree]
-# Return true if a filter doesn't completely match a configuration.
+# Return true if a filter completely matches a configuration.
def check_filter(config_dict, filter_dict):
for name, value in filter_dict.iteritems():
if not name in config_dict:
- return True
+ return False
if isinstance(value[1], str):
if value[0] != (config_dict[name] == value[1]):
- return True
+ return False
else:
if value[0] != bool(value[1].match(config_dict[name])):
- return True
+ return False
+
+ return True
+
+def check_filter_relevant(config_dict, filter_dict):
+ for name, value in filter_dict.iteritems():
+ if name in config_dict:
+ return True
+
+ return False
+
+def check_filters_list_relevant(config_dict, filters_list):
+ for filter_dict in filters_list:
+ if check_filter_relevant(config_dict, filter_dict):
+ return True
+
+ return False
+
+# Return true if a configuration doesn't pass any given filter.
+#
+# If the given filters list is irrelevant, i.e. it applies to none of
+# the options in the given configuration, the filters are considered
+# to match.
+def check_passing_filters(args):
+ config_dict, filters_list = args
+
+ if not check_filters_list_relevant(config_dict, filters_list):
+ return True
+
+ for filter_dict in filters_list:
+ if check_filter(config_dict, filter_dict):
+ return True
return False
# Return true if a configuration passes all the given filters.
-def check_filters(args):
+def check_blocking_filters(args):
config_dict, filters_list = args
for filter_dict in filters_list:
- if (not check_filter(config_dict, filter_dict)):
+ if check_filter(config_dict, filter_dict):
return False
return True
-def filter_configs_list(configs_list, filters_list):
- configs_and_filters = map(lambda x: (x, filters_list), configs_list)
- return map(lambda x: x[0], filter(check_filters, configs_and_filters))
+def filter_configs_list(configs_list, passing_filters_list,
+ blocking_filters_list):
+ configs_and_filters = map(lambda x: (x, passing_filters_list),
+ configs_list)
+ configs_list = map(lambda x: x[0], filter(check_passing_filters,
+ configs_and_filters))
+ configs_and_filters = map(lambda x: (x, blocking_filters_list),
+ configs_list)
+ configs_list = map(lambda x: x[0], filter(check_blocking_filters,
+ configs_and_filters))
+ return configs_list
def find_options_dict(options_sets, name):
if name not in options_sets:
@@ -250,7 +321,8 @@ def main():
print 'set: ' + args.set
configs_list = filter_configs_list(gen_configs_list(options_dict),
- all_filters_list)
+ passing_filters_list,
+ blocking_filters_list)
nr_configs = len(configs_list)
print 'total: ' + str(nr_configs)