/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* This file is part of the HiGHS linear optimization suite */ /* */ /* Written and engineered 2008-2021 at the University of Edinburgh */ /* */ /* Available as open-source under the MIT License */ /* */ /* Authors: Julian Hall, Ivet Galabova, Qi Huangfu, Leona Gottwald */ /* and Michael Feldmeier */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef HIGHS_CACHE_ALIGN_H_ #define HIGHS_CACHE_ALIGN_H_ #include #include #include #include namespace highs { struct cache_aligned { static constexpr std::size_t alignment() { return 64; } static void* alloc(std::size_t size) { using std::uintptr_t; uintptr_t ptr = reinterpret_cast(::operator new(size + alignment())); char* aligned_ptr = reinterpret_cast((ptr | (alignment() - 1)) + 1); std::memcpy(aligned_ptr - sizeof(uintptr_t), &ptr, sizeof(uintptr_t)); return reinterpret_cast(aligned_ptr); } static void free(void* aligned_ptr) { using std::uintptr_t; if (aligned_ptr) { void* freeptr; std::memcpy(&freeptr, reinterpret_cast(aligned_ptr) - sizeof(uintptr_t), sizeof(uintptr_t)); ::operator delete(freeptr); } } template struct Deleter { void operator()(T* ptr) const { ptr->~T(); free(ptr); } }; template struct Deleter { void operator()(T* ptr) const { free(ptr); } }; template using unique_ptr = std::unique_ptr>; template using shared_ptr = std::shared_ptr; template static shared_ptr make_shared(Args&&... args) { return shared_ptr(new (alloc(sizeof(T))) T(std::forward(args)...), Deleter()); } template static unique_ptr make_unique(Args&&... args) { return unique_ptr(new (alloc(sizeof(T))) T(std::forward(args)...)); } template static unique_ptr make_unique_array(std::size_t N) { return unique_ptr(static_cast(alloc(sizeof(T) * N))); } }; } // namespace highs #endif