Skip to content
Snippets Groups Projects
meson.build 8.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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')
    
    conf_data = configuration_data()
    use_bundled_deps = get_option('use_bundled_deps')
    
    
    liburing_version = '2.1'
    
    uring_dep = dependency('liburing', version: liburing_version, required: use_bundled_deps == 'never')
    if not uring_dep.found() or use_bundled_deps == 'always'
    
    	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'))
    
    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
    
    cpp_is_clang = cpp_compiler.get_id() == 'clang'
    if cpp_is_clang
      # Clang does not know "__attribute__((optimize(-no-omit-frame-pointer)))".
      add_project_arguments('-Wno-unknown-attributes', language: 'cpp')
    endif
    
    continuation_stealing_mode = get_option('continuation_stealing_mode')
    
    ws_queue_default = get_option('ws_queue_default')
    ws_queue_scheduler = get_option('ws_queue_scheduler')
    
    assume_page_size = get_option('assume_page_size')
    assume_cache_line_size = get_option('assume_cache_line_size')
    
    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_WORKER_IGNORE_WAKEUP_HINT', get_option('worker_ignore_wakeup_hint'))
    
    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'))
    
    conf_data.set('EMPER_CONTINUATION_STEALING_MODE', continuation_stealing_mode)
    conf_data.set('EMPER_CONTINUATION_STEALING_MADVISE_STACK', get_option('continuation_stealing_madvise_stack'))
    conf_data.set('EMPER_BUILD_WITH_CLANG', cpp_is_clang)
    
    conf_data.set('EMPER_CONTEXT_MANAGER_WITH_MEMORY_MANAGER', get_option('context_manager_with_memory_manager'))
    
    conf_data.set('EMPER_MEMORY_MANAGER_VICTIM_PERCENTAGE', get_option('memory_manager_victim_percentage'))
    
    conf_data.set('EMPER_ASSUME_PAGE_SIZE', assume_page_size)
    
    conf_data.set('EMPER_MIN_CONTEXT_STACK_SIZE', get_option('min_context_stack_size'))
    
    conf_data.set('EMPER_ASSUME_CACHE_LINE_SIZE', assume_cache_line_size)
    
    conf_data.set('EMPER_STACK_GUARD_PAGE', get_option('stack_guard_page'))
    
    Florian Schmaus's avatar
    Florian Schmaus committed
    conf_data.set('EMPER_STATS_STACK_USAGE', get_option('stats_stack_usage'))
    
    
    context_alignment = get_option('context_alignment')
    if context_alignment == 'none'
      context_alignas = ''
    elif context_alignment == 'cache_line_size'
    
      context_alignas = 'alignas(@0@)'.format(assume_cache_line_size)
    
    elif context_alignment == 'page_size'
    
      context_alignas = 'alignas(@0@)'.format(assume_page_size)
    
    else
      error('Unknown context alignment option: ' + context_alignment)
    endif
    conf_data.set('EMPER_CONTEXT_ALIGNAS', context_alignas)
    
    if ws_queue_scheduler == 'locked' or (ws_queue_scheduler == 'default' and ws_queue_default == 'locked')
      ws_queue_scheduler_locked = true
    else
      ws_queue_scheduler_locked = false
    endif
    
    if continuation_stealing_mode == 'locked' and not ws_queue_scheduler_locked
      error('*Locked* continuation stealing only works with locked work-stealing queues (ws_queue_scheduler=locked)')
    
    endif
    if continuation_stealing_mode == 'waitfree'
      conf_data.set('EMPER_CONTINUATION_STEALING_MODE_WAITFREE', true)
    endif
    
    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',
    
    	'unbounded_iow_max',
    
    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')