/* * Copyright (C) 2018-present ScyllaDB */ /* * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 */ #pragma once #include #include #include #include #include "seastarx.hh" class is_preemptible_tag; using is_preemptible = bool_class; /// A function which decides when to preempt. /// If it returns true then the algorithm will be interrupted. using preemption_check = noncopyable_function; inline preemption_check default_preemption_check() { return [] () noexcept { return seastar::need_preempt(); }; } inline preemption_check never_preempt() { return [] () noexcept { return false; }; } inline preemption_check always_preempt() { return [] () noexcept { return true; }; } struct basic_preemption_source { bool should_preempt() { return seastar::need_preempt(); } void thread_yield() { seastar::thread::yield(); } }; struct custom_preemption_source { struct impl { virtual bool should_preempt() = 0; virtual void thread_yield() = 0; virtual ~impl() = default; }; std::unique_ptr _impl; bool should_preempt() { return _impl ? _impl->should_preempt() : seastar::need_preempt(); } void thread_yield() { _impl ? _impl->thread_yield() : seastar::thread::yield(); } custom_preemption_source() = default; custom_preemption_source(std::unique_ptr i) : _impl(std::move(i)) {} }; #ifdef SCYLLA_ENABLE_PREEMPTION_SOURCE using preemption_source = custom_preemption_source; #else using preemption_source = basic_preemption_source; #endif