Commit 5ccf7b2a authored by Ruben Laso Rodríguez's avatar Ruben Laso Rodríguez
Browse files

build: add 'pedantic' compilation options and treat warnings as errors....

build: add 'pedantic' compilation options and treat warnings as errors. refactor: change code to attend 'pedantic' compiler complaints
parent 7e61dcdc
Checks: 'bugprone-*,cert-*,cppcoreguidelines-*,clang-analyzer-*,cppcoreguidelines-*,hicpp-*,llvm-*,misc-*,modernize-*,performance-*,readability-*,-readability-identifier-length'
\ No newline at end of file
Checks: "bugprone-*,
cert-*,
cppcoreguidelines-*,
clang-analyzer-*,
cppcoreguidelines-*,
-cppcoreguidelines-pro-type-union-access,
hicpp-*,
llvm-*,
misc-*,
modernize-*,
performance-*,
readability-*,
-readability-identifier-length"
WarningsAsErrors: ''
HeaderFilterRegex: ''
\ No newline at end of file
cmake_minimum_required(VERSION 3.13)
project(thanos)
cmake_minimum_required(VERSION 3.16...3.23)
# Not ideal to use this global variable, but necessary to make sure
# that tooling and projects use the same version
set(CMAKE_CXX_STANDARD 20)
# strongly encouraged to enable this globally to avoid conflicts between
# -Wpedantic being enabled and -std=c++20 and -std=gnu++20 for example
# when compiling with PCH enabled
set(CMAKE_CXX_EXTENSIONS OFF)
# Change this to false if you want to disable warnings_as_errors in developer mode
set(OPT_WARNINGS_AS_ERRORS_DEVELOPER_DEFAULT TRUE)
# Additional (pedantic) compilation errors
add_compile_options(-Wall -Wextra -Wshadow -Wconversion -Wpedantic -Werror -Wno-unused-function)
# Set the project name and language
project(
thanos
VERSION 3.0
DESCRIPTION "Thread and memory migration Algorithms for NUMA Optimised Scheduling"
HOMEPAGE_URL "https://gitlab.citius.usc.es/ruben.laso/migration"
LANGUAGES CXX C)
include(CheckIPOSupported)
check_ipo_supported(RESULT IPOsupported OUTPUT error)
......@@ -62,15 +82,6 @@ if (CMAKE_BUILD_TYPE STREQUAL "Release")
MESSAGE(STATUS "Using further compiler optimisation flags: -march=native -ffast-math")
add_compile_options("-march=native")
add_compile_options("-ffast-math")
else ()
MESSAGE(STATUS "Compilation flags: ${CMAKE_CXX_FLAGS_DEBUG}")
MESSAGE(STATUS "Using compiler pedantic flags: -Wall -Wpedantic -Wextra -fdiagnostics-show-option -Wno-unused-function")
add_compile_options("-Wall")
add_compile_options("-Wpedantic")
add_compile_options("-Wextra")
# add_compile_options("-Weffc++") # Some third-party libs trigger a lot of warnings :(
add_compile_options("-fdiagnostics-show-option")
add_compile_options("-Wno-unused-function")
endif ()
include(FindLibpfm)
......@@ -84,13 +95,53 @@ else ()
" and re-run cmake")
endif ()
add_executable(thanos
src/main.cpp src/utils/verbose.cpp src/system_info/system_info.cpp src/system_info/memory_info.cpp
src/samples/samples.cpp src/samples/perf_event/perf_event.cpp src/migration/tickets.cpp
src/migration/utils/times.cpp src/migration/migration_var.cpp)
# Ranges
# From : https://alandefreitas.github.io/moderncpp/algorithms-data-structures/algorithm/ranges/
# Use range-v3 for now: https://github.com/ericniebler/range-v3
include(FetchContent)
find_package(range-v3 QUIET)
if (NOT range-v3_FOUND)
FetchContent_Declare(range-v3 URL https://github.com/ericniebler/range-v3/archive/0.12.0.zip)
FetchContent_GetProperties(range-v3)
if (NOT range-v3_POPULATED)
FetchContent_Populate(range-v3)
add_library(range-v3 INTERFACE IMPORTED)
target_include_directories(range-v3 INTERFACE "${range-v3_SOURCE_DIR}/include")
endif ()
endif ()
# Tabulate
find_package(tabulate QUIET)
if (NOT tabulate_FOUND)
FetchContent_Declare(tabulate URL https://github.com/p-ranav/tabulate/archive/refs/tags/v1.4.zip)
FetchContent_GetProperties(tabulate)
if (NOT tabulate_POPULATED)
FetchContent_Populate(tabulate)
add_library(tabulate INTERFACE IMPORTED)
target_include_directories(tabulate INTERFACE "${tabulate_SOURCE_DIR}/include")
endif ()
endif ()
file(GLOB_RECURSE sources CONFIGURE_DEPENDS src/*.cpp)
add_executable(thanos ${sources})
if (TARGET range-v3)
target_link_libraries(${PROJECT_NAME}
PRIVATE
range-v3
)
endif ()
if (TARGET tabulate)
target_link_libraries(${PROJECT_NAME}
PRIVATE
tabulate
)
endif ()
target_link_libraries(thanos numa)
target_link_libraries(thanos ${THANOS_EXTERNAL_LIBS})
target_link_libraries(thanos PUBLIC numa)
target_link_libraries(thanos PUBLIC ${THANOS_EXTERNAL_LIBS})
if (IPOsupported)
message(STATUS "IPO / LTO enabled")
......
......@@ -70,23 +70,23 @@ namespace {
bool update_mem = false;
real_t secs_update_proc = 0.1;
real_t secs_update_proc = static_cast<real_t>(0.1);
real_t secs_update_mem = migration::memory::min_time_between_migrations;
real_t secs_before_migr = 5;
real_t secs_before_migr = static_cast<real_t>(5);
real_t secs_between_balance = 0.5;
real_t secs_between_balance = static_cast<real_t>(0.5);
real_t secs_between_samples = 0.1;
real_t secs_between_samples = static_cast<real_t>(0.1);
real_t secs_between_iter = 0.1;
real_t secs_between_iter = static_cast<real_t>(0.1);
char * file_read_tickets;
char * file_write_tickets;
// Capture the child process signal to make a clean end (closing auxiliary files, free memory, etc.)
void clean_end(int signal, siginfo_t * siginfo, [[maybe_unused]] void * context) {
if (siginfo != nullptr && std::cmp_equal(signal, SIGCHLD) &&
if (siginfo != nullptr and std::cmp_equal(signal, SIGCHLD) and
std::cmp_not_equal(siginfo->si_pid, child_process)) {
// we can ignore this signal since it has been thrown by an auxiliary function of this program
if (verbose::print_with_lvl(verbose::LVL_MAX)) {
......@@ -343,7 +343,7 @@ namespace {
migration::remove_invalid_pids(removed_pids);
// If the children processes list has changed, a CPU balance is (likely) required
if (std::cmp_greater(migration::thread::max_thread_migrations, 0) && !removed_pids.empty()) {
if (std::cmp_greater(migration::thread::max_thread_migrations, 0) and !removed_pids.empty()) {
migration::balance();
}
......@@ -355,8 +355,8 @@ namespace {
samples::update_PIDs_to_filter(children);
}
if (update_mem && utils::time::time_until(last_mem_update, current_time) > secs_update_mem) {
if (!memory_info::update_vmstat() && verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
if (update_mem and utils::time::time_until(last_mem_update, current_time) > secs_update_mem) {
if (!memory_info::update_vmstat() and verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cerr << "Could not update values from /proc/" << child_process << "/vmstat" << '\n';
}
......@@ -387,7 +387,7 @@ namespace {
if (export_chart_info_memory) { migration::print_memory_info(timestamp, memory_info_file); }
}
if (migration::thread::max_thread_migrations > 0 &&
if (migration::thread::max_thread_migrations > 0 and
utils::time::time_until(last_cpu_balance, current_time) > secs_between_balance) {
last_cpu_balance = current_time;
migration::balance();
......@@ -450,7 +450,7 @@ namespace {
} // END OF ANONYMOUS NAMESPACE
int main(const int argc, char * const argv[]) {
const std::span<char * const> args(argv, argc);
const std::span<char * const> args(argv, static_cast<size_t>(argc));
int c = 0;
......@@ -529,13 +529,13 @@ int main(const int argc, char * const argv[]) {
}
break;
case 'f':
samples::ins_frequency = std::stoi(optarg);
samples::ins_frequency = std::strtoul(optarg, nullptr, 10);
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cout << "Instr. sampling frequency: " << samples::ins_frequency << '\n';
}
break;
case 'F':
samples::mem_frequency = std::stoi(optarg);
samples::mem_frequency = std::strtoul(optarg, nullptr, 10);
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cout << "Memory sampling frequency: " << samples::mem_frequency << '\n';
}
......@@ -553,13 +553,13 @@ int main(const int argc, char * const argv[]) {
}
break;
case 'l':
samples::minimum_latency = std::stoi(optarg);
samples::minimum_latency = std::strtol(optarg, nullptr, 10);
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cout << "Minimum latency: " << samples::minimum_latency << '\n';
}
break;
case 'm':
migration::thread::max_thread_migrations = std::stoi(optarg);
migration::thread::max_thread_migrations = std::strtoul(optarg, nullptr, 10);
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cout << "Max. number of thread migrations per iteration: "
<< migration::thread::max_thread_migrations << '\n';
......@@ -567,7 +567,7 @@ int main(const int argc, char * const argv[]) {
break;
case 'M': {
real_t percentage = std::stof(optarg);
if (percentage < 0 || percentage > 1) {
if (percentage < 0 or percentage > 1) {
percentage = migration::memory::portion_memory_migrations;
std::cerr << "Argument -M should be in the interval [0, 1]. Using default value "
<< migration::memory::portion_memory_migrations << '\n';
......@@ -594,7 +594,7 @@ int main(const int argc, char * const argv[]) {
}
break;
case 'P':
migration::memory::memory_prefetch_size = std::stol(optarg);
migration::memory::memory_prefetch_size = std::strtoul(optarg, nullptr, 10);
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cout << "Memory max. prefetch size: " << migration::memory::memory_prefetch_size << '\n';
}
......@@ -649,7 +649,7 @@ int main(const int argc, char * const argv[]) {
break;
case '1':
if (optarg != nullptr) {
memory_info::details::fake_thp_size = std::stol(optarg);
memory_info::details::fake_thp_size = std::strtoul(optarg, nullptr, 10);
update_mem = true;
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cout << "Fake THPs enabled with size: " << memory_info::details::fake_thp_size << '\n';
......@@ -661,7 +661,7 @@ int main(const int argc, char * const argv[]) {
const auto thp_size_kB = std::stol(thp_size_str);
const auto pagesize = memory_info::pagesize;
const auto thp_size_n_pages = thp_size_kB * 1024 / pagesize;
const auto thp_size_n_pages = static_cast<unsigned long>(thp_size_kB * 1024) / pagesize;
memory_info::details::fake_thp_size = thp_size_n_pages;
update_mem = true;
......
......@@ -190,7 +190,7 @@ namespace migration {
// IMPORTANT!!!!
// As memory samples are not trustable given its nature (out-of-order execution, 1 sample = 1 address, ...)
// it is considered sample[i].value = 1 no matter what.
static_assert(std::is_same<typename Map::key_type, addr_t>::value &&
static_assert(std::is_same<typename Map::key_type, addr_t>::value and
std::is_same<typename Map::mapped_type, node_t>::value,
"Use a map of the form Map<addr_t, node_t>");
......@@ -209,7 +209,7 @@ namespace migration {
}
}
node_t page_node = -1;
node_t page_node = system_info::max_node() + 1;
const auto & map_it = page_node_map.find(page_addr);
......@@ -221,7 +221,7 @@ namespace migration {
page_node = map_it->second;
}
if (std::cmp_less(page_node, 0)) { return false; }
if (std::cmp_greater(page_node, system_info::max_node())) { return false; }
// Due to how sampling works, you only know the number of requests of a given memory page
// from the number of samples obtained from it. So, one sample -> one memory operation -> one request
......@@ -293,7 +293,7 @@ namespace migration {
page_node_map.reserve(last_map_size);
for (const auto & [tid, addresses] : pid_pages_map) {
std::vector<addr_t> pages(addresses.begin(), addresses.end());
auto pages = addresses | ranges::to<std::vector<addr_t>>;
const auto nodes = memory_info::get_pages_current_node(pages, tid);
......
......@@ -182,7 +182,7 @@ namespace migration {
[[nodiscard]] inline auto tids_involved() const -> set<pid_t> {
set<pid_t> tids;
for (const auto migration : migrations_) {
for (const auto & migration : migrations_) {
tids.insert(migration.tid());
}
......@@ -192,7 +192,7 @@ namespace migration {
[[nodiscard]] inline auto balance(const std::vector<real_t> & new_perfs) const {
real_t balance = 0;
for (size_t i = 0; const auto migr : migrations_) {
for (size_t i = 0; const auto & migr : migrations_) {
const real_t prev_perf =
migr.prev_perf() == performance::PERFORMANCE_INVALID_VALUE ? real_t() : migr.prev_perf();
......
......@@ -21,10 +21,11 @@
#include <variant> // for variant
#include <vector> // for vector, vector<>::const...
#include <tabulate/table.hpp> // for Table, Format, FontAlign
#include "migration/utils/mem_sample.hpp" // for memory_sample_t
#include "samples/perf_event/perf_event.hpp" // for minimum_latency
#include "system_info/system_info.hpp" // for num_of_nodes, node_from...
#include "tabulate/tabulate.hpp" // for Table, Format, FontAlign
#include "utils/string.hpp" // for to_string, percentage
#include "utils/types.hpp" // for real_t, addr_t, node_t
......@@ -52,7 +53,7 @@ namespace performance {
req_t av_latency_ctr_ = 0;
pid_t last_pid_ = -1;
node_t last_node_ = -1;
node_t last_node_ = system_info::max_node() + 1;
inline void compute_ratios() const {
const auto total_accesses = std::accumulate(raw_accesses_.begin(), raw_accesses_.end(), size_t());
......
......@@ -13,8 +13,8 @@
#include "utils/types.hpp" // for real_t
namespace performance {
static constexpr real_t PERFORMANCE_INVALID_VALUE = -1;
static constexpr real_t NEGLIGIBLE_PERFORMANCE = 1e-3;
static constexpr real_t PERFORMANCE_INVALID_VALUE = static_cast<real_t>(-1);
static constexpr real_t NEGLIGIBLE_PERFORMANCE = static_cast<real_t>(1e-3);
} // namespace performance
#endif /* end of include guard: THANOS_PERFORMANCE_HPP */
......@@ -19,15 +19,16 @@
#include <string> // for string, to_string
#include <unistd.h> // for sysconf, _SC_LEVEL1...
#include <variant> // for variant
#include <vector> // for vector, vector<>::c...
#include <tabulate/tabulate.hpp> // for Table, Format, Font...
#include <vector> // for vector, vector<>::c...
#include "migration/performance/performance.hpp" // for PERFORMANCE_INVALID...
#include "migration/utils/inst_sample.hpp" // for inst_sample_t
#include "migration/utils/mem_sample.hpp" // for memory_sample_t
#include "migration/utils/reqs_sample.hpp" // for reqs_sample_t
#include "samples/perf_event/perf_event.hpp" // for minimum_latency
#include "system_info/system_info.hpp" // for num_of_nodes, node_...
#include "tabulate/tabulate.hpp" // for Table, Format, Font...
#include "utils/string.hpp" // for to_string
#include "utils/time.hpp" // for time_until_now
#include "utils/types.hpp" // for real_t, req_t, time...
......@@ -120,7 +121,7 @@ namespace performance {
[[nodiscard]] inline auto av_latency(const node_t node) const {
// If the average latency is negative, take minimum_latency.
// Sanity check since negative latency is physically impossible.
return (!std::isnormal(total_reqs_[node]) || mean_lat_[node] <= 0) ? samples::minimum_latency :
return (!std::isnormal(total_reqs_[node]) or mean_lat_[node] <= 0) ? samples::minimum_latency :
mean_lat_[node];
}
......@@ -136,7 +137,7 @@ namespace performance {
}
inline void calc_perf(const node_t node) {
if (!std::isnormal(times_[node]) || !std::isnormal(total_reqs_[node])) { // No data
if (!std::isnormal(times_[node]) or !std::isnormal(total_reqs_[node])) { // No data
perfs_[node] = PERFORMANCE_INVALID_VALUE;
return;
}
......@@ -173,12 +174,12 @@ namespace performance {
[[nodiscard]] inline auto perf_node(const node_t node) const -> real_t {
const auto perf = perfs_[node];
return (perf < 0 || !std::isnormal(perf)) ? PERFORMANCE_INVALID_VALUE : perf * decay(node);
return (perf < 0 or !std::isnormal(perf)) ? PERFORMANCE_INVALID_VALUE : perf * decay(node);
}
[[nodiscard]] inline auto raw_perf_node(const node_t node) const -> real_t {
const auto perf = perfs_[node];
return (perf < 0 || !std::isnormal(perf)) ? PERFORMANCE_INVALID_VALUE : perf;
return (perf < 0 or !std::isnormal(perf)) ? PERFORMANCE_INVALID_VALUE : perf;
}
[[nodiscard]] inline auto preferred_node() const -> node_t {
......@@ -193,7 +194,7 @@ namespace performance {
const auto scale = std::accumulate(total_reqs_.begin(), total_reqs_.end(), 0.0) /
std::accumulate(node_reqs_.begin(), node_reqs_.end(), 0.0);
if (!std::isnormal(scale) || scale <= 0) { return node_reqs_; }
if (!std::isnormal(scale) or scale <= 0) { return node_reqs_; }
auto scaled_reqs = node_reqs_;
......
......@@ -19,7 +19,8 @@
#include <sys/types.h> // for pid_t, size_t
#include <type_traits> // for add_const<>::type
#include <variant> // for variant
#include <vector> // for vector
#include <tabulate/tabulate.hpp> // for Table, Format, Font...
#include "migration/performance/performance.hpp" // for PERFORMANCE_INVALID...
#include "migration/performance/rm3d.hpp" // for rm3d, operator<<
......@@ -28,10 +29,10 @@
#include "migration/utils/reqs_sample.hpp" // for reqs_sample_t
#include "samples/perf_event/perf_event.hpp" // for minimum_latency
#include "system_info/system_info.hpp" // for num_of_nodes, pid_f...
#include "tabulate/tabulate.hpp" // for Table, Format, Font...
#include "utils/string.hpp" // for to_string, percentage
#include "utils/types.hpp" // for real_t, node_t
#include "utils/verbose.hpp" // for LVL4, lvl
#include <vector> // for vector
namespace performance {
namespace details {
......@@ -240,7 +241,7 @@ namespace performance {
inline void check_running() {
for (auto & [tid, row] : table_) {
if (!row.running() && system_info::is_running(tid)) { row.running(true); }
if (!row.running() and system_info::is_running(tid)) { row.running(true); }
}
}
......
......@@ -25,34 +25,6 @@ namespace migration::memory {
static constexpr strategy_t DEFAULT_STRATEGY = LMMA;
[[nodiscard]] static auto parse_strategy_file(const char * filename = "strategy_option") -> strategy_t {
std::ifstream file(filename);
if (!file.is_open()) {
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cerr << "Failed to strategy options (file might not exist), using default..." << '\n';
}
return DEFAULT_STRATEGY;
}
int strategy = DEFAULT_STRATEGY;
file >> strategy;
file.close();
switch (strategy) {
case TMMA:
return TMMA;
case LMMA:
return LMMA;
case RMMA:
return RMMA;
default:
return DEFAULT_STRATEGY;
}
}
[[nodiscard]] static auto print_strategy(const strategy_t strategy) -> const char * {
switch (strategy) {
case TMMA:
......
......@@ -60,7 +60,7 @@ namespace migration::memory {
}
}
for (const addr_t i : std::ranges::iota_view(size_t(1), memory_prefetch_size + 1)) {
for (const addr_t i : ranges::views::closed_indices(size_t(1), memory_prefetch_size)) {
const addr_t candidate = initial + i * pagesize;
if (std::cmp_greater_equal(candidate, region_end)) {
......@@ -99,7 +99,7 @@ namespace migration::memory {
// Preallocate memory to save time
pages.reserve(memory_prefetch_size);
for (const addr_t i : std::ranges::iota_view(size_t(1), memory_prefetch_size + 1)) {
for (const addr_t i : ranges::views::closed_indices(size_t(1), memory_prefetch_size)) {
const addr_t candidate = initial + i * memory_info::pagesize;
const auto & page_it = perf_table.find(candidate);
......
......@@ -31,7 +31,7 @@
namespace migration::memory {
[[nodiscard]] inline auto min_ratio_to_mig() noexcept -> real_t {
static constexpr real_t two_thirds = 2.0 / 3.0;
static constexpr auto two_thirds = static_cast<real_t>(2.0 / 3.0);
return std::min(two_thirds, real_t(2) / static_cast<real_t>(numa_max_node() + 1));
}
......@@ -63,7 +63,7 @@ namespace migration::memory {
const auto ratios = info.ratios();
const auto max_ratio = ratios[pref_node];
if (std::cmp_not_equal(pref_node, curr_node) && max_ratio > min_ratio_mig) {
if (std::cmp_not_equal(pref_node, curr_node) and max_ratio > min_ratio_mig) {
pages_to_migrate.insert(mem_page);
const auto pid = info.last_pid();
......@@ -121,7 +121,7 @@ namespace migration::memory {
const auto ratios = info.ratios();
const auto max_ratio = ratios[pref_node];
if (std::cmp_not_equal(pref_node, curr_node) && max_ratio > min_ratio_mig) {
if (std::cmp_not_equal(pref_node, curr_node) and max_ratio > min_ratio_mig) {
pages_to_migrate.insert(mem_page);
const auto pid = info.last_pid();
......
......@@ -28,45 +28,6 @@ namespace migration::thread {
static constexpr strategy_t DEFAULT_STRATEGY = NIMAR;
[[nodiscard]] static auto parse_strategy_file(const char * filename = "strategy_option") -> strategy_t {
std::ifstream file(filename);
if (!file.is_open()) {
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cerr << "Failed to strategy options (file might not exist), using default..." << '\n';
}
return DEFAULT_STRATEGY;
}
int strategy = DEFAULT_STRATEGY;
file >> strategy;
file.close();
switch (strategy) {
case LBMA:
return LBMA;
case CIMAR:
return CIMAR;
case IMAR2:
return IMAR2;
case NIMAR:
return NIMAR;
case RANDOM:
return RANDOM;
case RM3D:
return RM3D;
case Annealing_node:
return Annealing_node;
default:
if (verbose::print_with_lvl(verbose::DEFAULT_LVL)) {
std::cerr << "Strategy not found, using default strategy..." << '\n';
}
return DEFAULT_STRATEGY;
}
}
static auto print_strategies(std::ostream & os, const std::string & prelude = "") -> std::ostream & {
os << prelude << LBMA << ": "
<< "LBMA (Lottery-Based Migration Algorithm)." << '\n';
......
......@@ -71,9 +71,10 @@ namespace migration::thread {
[[nodiscard]] inline auto tickets_pref_node(const pid_t pid, const node_t dst_node) -> tickets_t {
const auto pref_node = perf_table.preferred_node(pid);
tickets_t tickets(TICKETS_PREF_NODE.value() * static_cast<real_t>(system_info::local_distance()) /
static_cast<real_t>(numa_distance(dst_node, pref_node)),
dst_node == pref_node ? TICKETS_PREF_NODE.mask() : tickets_mask_t(0));
tickets_t tickets(
TICKETS_PREF_NODE.value() * static_cast<real_t>(system_info::local_distance()) /
static_cast<real_t>(numa_distance(static_cast<int>(dst_node), static_cast<int>(pref_node))),
dst_node == pref_node ? TICKETS_PREF_NODE.mask() : tickets_mask_t(0));
return tickets;
}
......@@ -121,7 +122,7 @@ namespace migration::thread {
return tickets_t(tickets.value() * (1 + sign * incr), tickets.mask());
}
void mutate_tickets(const migration_cell & migrs, const real_t range = 0.05,
void mutate_tickets(const migration_cell & migrs, const real_t range = static_cast<real_t>(0.05),
const bool print = (verbose::print_with_lvl(verbose::DEFAULT_LVL))) {
const auto mask = migrs.tickets().mask();
......@@ -135,7 +136,7 @@ namespace migration::thread {
<< ". Current: " << current_per << ". Improvement: " << improvement << "%" << '\n';
}
if ((mask & tickets_mask::TICKETS_MEM_CELL_WORSE_MASK) != 0) {
if ((mask & tickets_mask::TICKETS_MEM_CELL_WORSE_MASK) not_eq 0) {
const auto previous_value = TICKETS_MEM_CELL_WORSE;
TICKETS_MEM_CELL_WORSE = mutate_ticket(TICKETS_MEM_CELL_WORSE, range, improvement);
......@@ -145,7 +146,7 @@ namespace migration::thread {
}
}
if ((mask & tickets_mask::TICKETS_MEM_CELL_NO_DATA_MASK) != 0) {
if ((mask & tickets_mask::TICKETS_MEM_CELL_NO_DATA_MASK) not_eq 0) {
const auto previous_value = TICKETS_MEM_CELL_NO_DATA;
TICKETS_MEM_CELL_NO_DATA = mutate_ticket(previous_value, range, improvement);
......@@ -155,7 +156,7 @@ namespace migration::thread {