diff --git a/include/nvsl/numa.hh b/include/nvsl/numa.hh index df1c164..53721b5 100644 --- a/include/nvsl/numa.hh +++ b/include/nvsl/numa.hh @@ -11,6 +11,10 @@ #include "numa.h" #include +#ifndef MPOL_MF_MOVE_ALL +#define MPOL_MF_MOVE_ALL (1<<2) +#endif + static inline int numa_node_of_page(void *page) { int result; const auto _ = @@ -20,8 +24,10 @@ static inline int numa_node_of_page(void *page) { return result; } -static inline void move_region_to_node(int node, void *start, size_t size, +static inline bool move_region_to_node(int node, void *start, size_t size, size_t page_size = 4096) { + bool result = true; + const auto page_cnt = size / page_size; int *nodes = new int[page_cnt]; int *status = new int[page_cnt]; @@ -39,6 +45,8 @@ static inline void move_region_to_node(int node, void *start, size_t size, std::cerr << "perror: " << strerror(errno) << std::endl; std::cerr << "Warning: first page might not be on the target node. "; std::cerr << "Expected: " << node << ", got: " << status[0] << std::endl; + + result = false; } for (auto i = 0UL; i < page_cnt; i++) { @@ -47,6 +55,8 @@ static inline void move_region_to_node(int node, void *start, size_t size, std::cerr << "Expected: " << node << ", got: " << status[i] << std::endl; std::cerr << "Not checking further pages." << std::endl; + result = false; + break; } } @@ -54,4 +64,6 @@ static inline void move_region_to_node(int node, void *start, size_t size, delete[] nodes; delete[] status; delete[] pages; + + return result; } diff --git a/include/nvsl/pmemops/declarations.hh b/include/nvsl/pmemops/declarations.hh index c34f590..d7e1e81 100644 --- a/include/nvsl/pmemops/declarations.hh +++ b/include/nvsl/pmemops/declarations.hh @@ -56,6 +56,9 @@ namespace nvsl { /** @brief Clwb on a single addr, to flush a range use flush() */ void clwb(void *addr) const; + /** @brief Clflush on single addr, to evict a range, use evict() */ + void clflush(void *addr) const; + public: void flush(void *base, size_t size) const; void persist(void *base, size_t size) const; @@ -64,6 +67,7 @@ namespace nvsl { void memmove(void *dest, void *src, size_t size) const; void memset(void *base, char c, size_t size) const; void streaming_wr(void *dest, const void *src, size_t bytes) const; + void evict(void *base, size_t size) const; }; class PMemOpsMsync : public PMemOps { diff --git a/include/nvsl/pmemops/pmemops_clwb.hh b/include/nvsl/pmemops/pmemops_clwb.hh index 8fe1058..b2a4640 100644 --- a/include/nvsl/pmemops/pmemops_clwb.hh +++ b/include/nvsl/pmemops/pmemops_clwb.hh @@ -152,6 +152,10 @@ inline void nvsl::PMemOpsClwb::clwb(void *addr) const { _mm_clwb(addr); } +inline void nvsl::PMemOpsClwb::clflush(void *addr) const { + _mm_clflush(addr); +} + inline void nvsl::PMemOpsClwb::flush(void *base, size_t size) const { uintptr_t uptr; @@ -170,6 +174,20 @@ inline void nvsl::PMemOpsClwb::flush(void *base, size_t size) const { } } +/** @brief Evict the given range from the cache */ +inline void nvsl::PMemOpsClwb::evict(void *base, size_t size) const { + uintptr_t uptr; + + /* + * Loop through cache-line-size (typically 64B) aligned chunks + * covering the given range. + */ + for (uptr = (uintptr_t)base & ~(CL_SIZE - 1); uptr < (uintptr_t)base + size; + uptr += CL_SIZE) { + this->clflush((void *)uptr); + } +} + inline void nvsl::PMemOpsClwb::drain() const { #ifdef SFENCE_AVAIL _mm_sfence();