diff --git a/src/mx/memory/fixed_size_allocator.h b/src/mx/memory/fixed_size_allocator.h index e4cfff1..8a4154c 100644 --- a/src/mx/memory/fixed_size_allocator.h +++ b/src/mx/memory/fixed_size_allocator.h @@ -296,7 +296,7 @@ public: } } - for (const auto core_id : core_set) + for (auto core_id = 0; core_id < system::topology::count_cores(); ++core_id) { const auto node_id = system::topology::node_id(core_id); _core_heaps[core_id] = CoreHeap{&_processor_heaps[node_id]}; diff --git a/src/mx/system/environment.cpp b/src/mx/system/environment.cpp new file mode 100644 index 0000000..7e379d0 --- /dev/null +++ b/src/mx/system/environment.cpp @@ -0,0 +1,14 @@ +#include "environment.h" +#include + +using namespace mx::system; + +void Environment::set_cores(mx::util::core_set *core_set) +{ + system::Environment::get_instance()._coreset = core_set; +} + +mx::util::core_set &Environment::cores() +{ + return *Environment::get_instance()._coreset; +} \ No newline at end of file diff --git a/src/mx/system/environment.h b/src/mx/system/environment.h index 024f09c..4f7547e 100644 --- a/src/mx/system/environment.h +++ b/src/mx/system/environment.h @@ -6,6 +6,9 @@ #include #include +namespace mx::util { + class core_set; +} namespace mx::system { /** * Encapsulates functionality of the (Linux) system. @@ -18,6 +21,7 @@ private: * @details The application's environment grants access to core services of EalánOS, such as thread creation and memory allocation. */ Libc::Env *_env; + util::core_set *_coreset; public: Environment() = default; @@ -36,6 +40,17 @@ public: */ void setenv(Libc::Env *env) { _env = env; } + /** + * @brief Set core set to be used by memory allocators and scheduler + * @param core_set the core_set to use + */ + static void set_cores(util::core_set *core_set); + + /** + * @brief returns the core set representing the physical environment MxTasking is running in + */ + static util::core_set &cores(); + /** * @brief Get the instance object * @@ -90,7 +105,7 @@ public: * @return Topology::Numa_region const& the corresponding node object */ static Topology::Numa_region node(std::uint8_t numa_id) { return topo().node_at_id(numa_id); } - + /** * @return True, if NUMA balancing is enabled by the system. */ diff --git a/src/mx/tasking/runtime.h b/src/mx/tasking/runtime.h index 07e6bdf..444011e 100644 --- a/src/mx/tasking/runtime.h +++ b/src/mx/tasking/runtime.h @@ -73,7 +73,7 @@ public: { _task_allocator.reset(new ( memory::GlobalHeap::allocate_cache_line_aligned(sizeof(memory::fixed::Allocator))) - memory::fixed::Allocator(core_set)); + memory::fixed::Allocator(system::Environment::cores())); } // Create a new scheduler. diff --git a/src/mx/util/bits.h b/src/mx/util/bits.h new file mode 100644 index 0000000..95065e2 --- /dev/null +++ b/src/mx/util/bits.h @@ -0,0 +1,14 @@ +#pragma once +#include + +namespace mx::util { +inline long int bit_scan_forward(std::uint64_t val) +{ + if (!val) + return -1; + + asm volatile("bsf %1, %0" : "=r"(val) : "rm"(val)); + + return val; +} +} \ No newline at end of file diff --git a/src/mx/util/core_set.cpp b/src/mx/util/core_set.cpp index 10efa4a..6bbb998 100644 --- a/src/mx/util/core_set.cpp +++ b/src/mx/util/core_set.cpp @@ -43,6 +43,21 @@ core_set core_set::build(std::uint16_t cores, const Order order) return core_set; } +core_set core_set::build(std::uint64_t *core_mask, std::uint16_t count) +{ + core_set core_set; + for (int c = 0; c < count; ++count) + { + std::bitset mask{core_mask[c]}; + long core = 0; + + while ((core = util::bit_scan_forward(mask.to_ulong())) != -1) { + mask.reset(core); + core_set.emplace_back(core); + } + } +} + namespace mx::util { std::ostream &operator<<(std::ostream &stream, const core_set &core_set) { diff --git a/src/mx/util/core_set.h b/src/mx/util/core_set.h index 99ded80..1189d89 100644 --- a/src/mx/util/core_set.h +++ b/src/mx/util/core_set.h @@ -8,6 +8,7 @@ #include #include #include +#include namespace mx::util { /** @@ -91,6 +92,8 @@ public: */ static core_set build(std::uint16_t cores, Order order = Ascending); + static core_set build(std::uint64_t *core_mask, std::uint16_t count); + bool operator==(const core_set &other) const noexcept { return _core_identifier == other._core_identifier && _size == other._size && _numa_nodes == other._numa_nodes;