Skip to content
Snippets Groups Projects
meson.build 6.15 KiB
Newer Older
project('EMPER', 'c', 'cpp',
		version: '0.0.1-alpha1-SNAPSHOT',
		default_options : [
		  'warning_level=3',
		  'c_std=gnu11',
		  'cpp_std=c++2a',
		  'b_ndebug=if-release',
		  'werror=true',
		])

thread_dep = dependency('threads')

liburing_version = '2.0'
uring_dep = dependency('liburing', version: liburing_version, required: false)
if not uring_dep.found()
	message('liburing ' + liburing_version + ' not found in system, using liburing subproject')
	liburing_sp = subproject('liburing')
	uring_dep = liburing_sp.get_variable('uring').as_system()
endif

numa_dep = dependency('numa')

# boost header dependency needed for the circular_buffer used in emper/io/Stats.cpp
boost_dep = dependency('boost')

emper_dependencies = [thread_dep, uring_dep, numa_dep, boost_dep]
boost_thread_dep = dependency('boost', modules : ['thread'], required: false)

tools_dir = join_paths(meson.source_root(), 'tools')

		   command: join_paths(tools_dir, 'check-iwyu'))
conf_data = configuration_data()
option_urcu = get_option('userspace_rcu')
conf_data.set('EMPER_LIBURCU', option_urcu)
if option_urcu
	liburcu_dep = dependency('liburcu')
	emper_dependencies += [liburcu_dep]
endif

cpp_compiler = meson.get_compiler('cpp')
if cpp_compiler.has_header('compare')
  conf_data.set('EMPER_HAS_COMPARE_H', true)
endif

conf_data.set('EMPER_WORKER_SLEEP', get_option('worker_sleep'))
conf_data.set('EMPER_WORKER_WAKEUP_STRATEGY', get_option('worker_wakeup_strategy'))
conf_data.set('EMPER_LOCKED_WS_QUEUE', get_option('locked_ws_queue'))
conf_data.set('EMPER_LOCKED_MPSC_QUEUE', get_option('locked_mpsc_queue'))
conf_data.set('EMPER_OVERFLOW_QUEUE', get_option('overflow_queue'))
conf_data.set('EMPER_STATS', get_option('stats'))
conf_data.set('EMPER_OVERFLOW_QUEUE', get_option('overflow_queue'))
conf_data.set('EMPER_BLOCKED_CONTEXT_SET', get_option('blocked_context_set'))
conf_data.set('EMPER_SET_AFFINITY_ON_BLOCK', get_option('set_affinity_on_block'))
conf_data.set('EMPER_IO_COMPLETER_SCHED_PARAM', get_option('io_completer_sched_param'))
semaphore_impl = get_option('wakeup_semaphore_implementation')
conf_data.set('EMPER_' + semaphore_impl.to_upper() + '_WAKEUP_SEMAPHORE', true)

sleep_stratey = get_option('worker_sleep_strategy')
if sleep_stratey == 'semaphore'
	conf_data.set('EMPER_SEMAPHORE_SLEEP_STRATEGY', true)
elif sleep_stratey == 'pipe'
	conf_data.set('EMPER_PIPE_SLEEP_STRATEGY', true)
else
	error('Unsupported sleep strategy')
endif

locked_unbounded_queue_impl = get_option('locked_unbounded_queue_implementation')
if locked_unbounded_queue_impl == 'boost_shared_mutex'
	if not boost_thread_dep.found()
		error('Boost thread module not found, but locked_unbounded_queue_implementation set to boost_shared_mutex')
	endif
	emper_dependencies += [boost_thread_dep]
endif
conf_data.set('EMPER_' + locked_unbounded_queue_impl.to_upper() + '_LOCKED_UNBOUNDED_QUEUE', true)

default_scheduling_strategy = get_option('default_scheduling_strategy')
conf_data.set('EMPER_DEFAULT_SCHEDULING_STRATEGY_' + default_scheduling_strategy.to_upper(), true)

ws_victim_count = get_option('work_stealing_victim_count')
ws_victim_denominator = get_option('work_stealing_victim_denominator')
if ws_victim_count != 0 and ws_victim_denominator !=0
	error('work_stealing_victim_count and work_stealing_victim_denominator are mutally exclusive')
endif
conf_data.set('EMPER_WS_VICTIM_COUNT', ws_victim_count)
conf_data.set('EMPER_WS_VICTIM_DENOMINATOR', ws_victim_denominator)

conf_data.set('EMPER_WAITFREE_WORK_STEALING',  get_option('waitfree_work_stealing'))

log_level = get_option('log_level')
if log_level == 'automatic'
	# output only error messages in release builds
	log_level = get_option('debug') ? 'ALL' : 'Info'
endif
conf_data.set('EMPER_LOG_LEVEL', log_level)
conf_data.set('EMPER_LOG_TIMESTAMP', get_option('log_timestamp'))
option_io =  get_option('io')
if option_io
	conf_data.set('EMPER_IO', true)
endif

io_bool_options = [
	{'option': 'stealing'},
	{'option': 'lockless_cq'},
	{'option': 'single_uring',
	 'dependencies': {'io_completer_behavior': 'schedule'}},
	{'option': 'try_syscall'},
	{'option': 'waitfree_stealing',
	 'dependencies': {'io_stealing': true, 'io_lockless_cq': true}},
]

io_raw_options = [
	'worker_uring_entries',
foreach option_dict : io_bool_options
	option = option_dict['option']
	value = get_option('io_' + option)
		error('io_' + option + ' defined without io')
	endif

	dependencies = option_dict.get('dependencies', {})
	foreach dependency, dep_value: dependencies
		if get_option(dependency) != dep_value
			error('io_' + option + ' defined but dependency ' + dependency + ':'
			      + dep_value.to_string() + ' not satisfied')
		endif
	endforeach

	conf_data.set('EMPER_IO_' + option.to_upper(), value)
endforeach

foreach option : io_raw_options
	conf_data.set('EMPER_IO_' + option.to_upper(), get_option('io_' + option))
endforeach

io_sqpoll_option = get_option('io_uring_sq_poller')
if io_sqpoll_option != 'off' and not option_io
	error('io_uring_sq_poller set without io')
conf_data.set('EMPER_IO_SQ_POLLER', io_sqpoll_option)

io_completer_behavior = get_option('io_completer_behavior')
if io_completer_behavior == 'maybe_wakeup'
	if get_option('worker_sleep')
		io_completer_behavior = 'wakeup'
	else
		io_completer_behavior = 'none'
	endif
endif
conf_data.set('EMPER_IO_COMPLETER_BEHAVIOR', io_completer_behavior)

# Decide on scheduling optimization introduced because of the completer
# moving work to the AnywhereQueue.
check_anywhere_queue_while_stealing = get_option('check_anywhere_queue_while_stealing')
if check_anywhere_queue_while_stealing == 'auto'
	conf_data.set('EMPER_CHECK_ANYWHERE_QUEUE_WHILE_STEALING',
	              io_completer_behavior == 'schedule')
else
	conf_data.set('EMPER_CHECK_ANYWHERE_QUEUE_WHILE_STEALING',
	              check_anywhere_queue_while_stealing == 'true')
endif

# check io meson options consistency
if get_option('io_single_uring')
	if io_sqpoll_option == 'each' or io_sqpoll_option == 'numa'
		warning('sqpoller: ' + io_sqpoll_option + ' is useless when using a single io_uring')
	endif
endif

subdir('emper')
subdir('tests')
subdir('apps')
subdir('eval')
subdir('doc')