kudu-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [kudu] branch master updated: KUDU-2605: replace nvml with memkind
Date Sun, 26 May 2019 18:12:54 GMT
This is an automated email from the ASF dual-hosted git repository.

adar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new 946e2bc  KUDU-2605: replace nvml with memkind
946e2bc is described below

commit 946e2bc05419e3a552fed5a9d28e83861ff1eea1
Author: yeyuqiang <yuqiang.ye@intel.com>
AuthorDate: Tue May 21 04:53:36 2019 +0800

    KUDU-2605: replace nvml with memkind
    
    The current nvm cache based on PMDK, formerly know as NVML. For volatile
    memory usage(libvmem), PMDK will not have a long-term maintenance. Since
    persistent memory support has been integrated into libmemkind, memkind is
    the recommended choice for any new volatile usages, since it combines
    support for multiple types of volatile memory into a single, convenient API.
    
    Change-Id: I08855c62bc42b9e6f7a4b3bfa27a708ed2c133f5
    Reviewed-on: http://gerrit.cloudera.org:8080/13188
    Reviewed-by: Adar Dembo <adar@cloudera.com>
    Tested-by: Adar Dembo <adar@cloudera.com>
---
 CMakeLists.txt                                     |  34 ++---
 .../{FindPmem.cmake => FindMemkind.cmake}          |  35 ++----
 cmake_modules/{FindPmem.cmake => FindNuma.cmake}   |  37 ++----
 src/kudu/cfile/block_cache.cc                      |   4 +-
 src/kudu/cfile/cfile-test.cc                       |   6 +-
 src/kudu/util/CMakeLists.txt                       |  10 +-
 src/kudu/util/cache-test.cc                        |  24 ++--
 src/kudu/util/cache.cc                             |   2 +-
 src/kudu/util/cache.h                              |   2 +-
 src/kudu/util/nvm_cache.cc                         | 138 ++++++++++++---------
 thirdparty/LICENSE.txt                             |  66 +++++-----
 thirdparty/build-definitions.sh                    |  86 +++++++++----
 thirdparty/build-thirdparty.sh                     |  19 ++-
 thirdparty/download-thirdparty.sh                  |  14 ++-
 thirdparty/vars.sh                                 |  11 +-
 15 files changed, 264 insertions(+), 224 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f054809..d53f81e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1139,24 +1139,28 @@ if (NOT "${KUDU_USE_ASAN}" AND
   set(KUDU_TCMALLOC_AVAILABLE 1)
 endif()
 
-# Required pmem libraries
+# Required memkind libraries
 if (NOT APPLE)
-find_package(Pmem REQUIRED)
-include_directories(${PMEM_INCLUDE_DIR})
-ADD_THIRDPARTY_LIB(vmem
-  STATIC_LIB "${VMEM_STATIC_LIB}"
-  SHARED_LIB "${VMEM_SHARED_LIB}")
-ADD_THIRDPARTY_LIB(pmem
-  STATIC_LIB "${PMEM_STATIC_LIB}"
-  SHARED_LIB "${PMEM_SHARED_LIB}")
-ADD_THIRDPARTY_LIB(pmemobj
-  STATIC_LIB "${PMEMOBJ_STATIC_LIB}"
-  SHARED_LIB "${PMEMOBJ_SHARED_LIB}")
+  find_package(Memkind REQUIRED)
+  include_directories(${MEMKIND_INCLUDE_DIR})
+  ADD_THIRDPARTY_LIB(memkind
+    STATIC_LIB "${MEMKIND_STATIC_LIB}"
+    SHARED_LIB "${MEMKIND_SHARED_LIB}"
+    DEPS numa)
 endif()
 
-if (EXISTS ${VMEM_SHARED_LIB})
-  set(HAVE_LIB_VMEM 1)
-  add_definitions(-DHAVE_LIB_VMEM=1)
+if (EXISTS ${MEMKIND_SHARED_LIB})
+  set(HAVE_LIB_MEMKIND 1)
+  add_definitions(-DHAVE_LIB_MEMKIND=1)
+endif()
+
+## libnuma
+if (NOT APPLE)
+  find_package(Numa REQUIRED)
+  include_directories(${NUMA_INCLUDE_DIR})
+  ADD_THIRDPARTY_LIB(numa
+    STATIC_LIB "${NUMA_STATIC_LIB}"
+    SHARED_LIB "${NUMA_SHARED_LIB}")
 endif()
 
 ## curl
diff --git a/cmake_modules/FindPmem.cmake b/cmake_modules/FindMemkind.cmake
similarity index 52%
copy from cmake_modules/FindPmem.cmake
copy to cmake_modules/FindMemkind.cmake
index a628e2f..7e4cd02 100644
--- a/cmake_modules/FindPmem.cmake
+++ b/cmake_modules/FindMemkind.cmake
@@ -15,39 +15,24 @@
 # specific language governing permissions and limitations
 # under the License.
 
-# - Find Required PMEM libraries (libvmem, libpmem, libpmemobj)
+# - Find required memkind libraries
 # This module defines
-#  PMEM_INCLUDE_DIR, directory containing headers
-#  XXX_STATIC_LIBS, path to *.a
-#  XXX_SHARED_LIBS, path to *.so shared library
-#  PMEM_FOUND, whether PMEM libraries have been found
+#  MEMKIND_INCLUDE_DIR, directory containing headers
+#  MEMKIND_STATIC_LIB, path to *.a
+#  MEMKIND_SHARED_LIB, path to *.so shared library
 
-find_path(PMEM_INCLUDE_DIR libpmem.h
+find_path(MEMKIND_INCLUDE_DIR memkind.h
   NO_CMAKE_SYSTEM_PATH
   NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(VMEM_SHARED_LIB vmem
+find_library(MEMKIND_SHARED_LIB memkind
   NO_CMAKE_SYSTEM_PATH
   NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(VMEM_STATIC_LIB libvmem.a
-  NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(PMEM_SHARED_LIB pmem
-  NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(PMEM_STATIC_LIB libpmem.a
-  NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(PMEMOBJ_SHARED_LIB pmemobj
-  NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(PMEMOBJ_STATIC_LIB libpmemobj.a
+find_library(MEMKIND_STATIC_LIB libmemkind.a
   NO_CMAKE_SYSTEM_PATH
   NO_SYSTEM_ENVIRONMENT_PATH)
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(PMEM REQUIRED_VARS
-  VMEM_SHARED_LIB VMEM_STATIC_LIB
-  PMEM_SHARED_LIB PMEM_STATIC_LIB
-  PMEMOBJ_SHARED_LIB PMEMOBJ_STATIC_LIB
-  PMEM_INCLUDE_DIR
+find_package_handle_standard_args(MEMKIND REQUIRED_VARS
+  MEMKIND_SHARED_LIB MEMKIND_STATIC_LIB
+  MEMKIND_INCLUDE_DIR
 )
diff --git a/cmake_modules/FindPmem.cmake b/cmake_modules/FindNuma.cmake
similarity index 51%
rename from cmake_modules/FindPmem.cmake
rename to cmake_modules/FindNuma.cmake
index a628e2f..2167b28 100644
--- a/cmake_modules/FindPmem.cmake
+++ b/cmake_modules/FindNuma.cmake
@@ -15,39 +15,24 @@
 # specific language governing permissions and limitations
 # under the License.
 
-# - Find Required PMEM libraries (libvmem, libpmem, libpmemobj)
+# - Find required numa libraries
 # This module defines
-#  PMEM_INCLUDE_DIR, directory containing headers
-#  XXX_STATIC_LIBS, path to *.a
-#  XXX_SHARED_LIBS, path to *.so shared library
-#  PMEM_FOUND, whether PMEM libraries have been found
+#  NUMA_INCLUDE_DIR, directory containing headers
+#  NUMA_STATIC_LIB, path to *.a
+#  NUMA_SHARED_LIB, path to *.so shared library
 
-find_path(PMEM_INCLUDE_DIR libpmem.h
+find_path(NUMA_INCLUDE_DIR numa.h
   NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(VMEM_SHARED_LIB vmem
-  NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(VMEM_STATIC_LIB libvmem.a
-  NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(PMEM_SHARED_LIB pmem
-  NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(PMEM_STATIC_LIB libpmem.a
-  NO_CMAKE_SYSTEM_PATH
-  NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(PMEMOBJ_SHARED_LIB pmemobj
+NO_SYSTEM_ENVIRONMENT_PATH)
+find_library(NUMA_SHARED_LIB numa
   NO_CMAKE_SYSTEM_PATH
   NO_SYSTEM_ENVIRONMENT_PATH)
-find_library(PMEMOBJ_STATIC_LIB libpmemobj.a
+find_library(NUMA_STATIC_LIB libnuma.a
   NO_CMAKE_SYSTEM_PATH
   NO_SYSTEM_ENVIRONMENT_PATH)
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(PMEM REQUIRED_VARS
-  VMEM_SHARED_LIB VMEM_STATIC_LIB
-  PMEM_SHARED_LIB PMEM_STATIC_LIB
-  PMEMOBJ_SHARED_LIB PMEMOBJ_STATIC_LIB
-  PMEM_INCLUDE_DIR
+find_package_handle_standard_args(NUMA REQUIRED_VARS
+  NUMA_SHARED_LIB NUMA_STATIC_LIB
+  NUMA_INCLUDE_DIR
 )
diff --git a/src/kudu/cfile/block_cache.cc b/src/kudu/cfile/block_cache.cc
index 9865776..ff17524 100644
--- a/src/kudu/cfile/block_cache.cc
+++ b/src/kudu/cfile/block_cache.cc
@@ -76,12 +76,12 @@ Cache* CreateCache(int64_t capacity) {
       return NewCache<Cache::EvictionPolicy::LRU, Cache::MemoryType::DRAM>(
           capacity, "block_cache");
     case Cache::MemoryType::NVM:
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
       return NewCache<Cache::EvictionPolicy::LRU, Cache::MemoryType::NVM>(
           capacity, "block_cache");
 #else
       LOG(FATAL) << "cache of NVM memory type is not supported";
-#endif // #if defined(HAVE_LIB_VMEM) ... #else ...
+#endif // #if defined(HAVE_LIB_MEMKIND) ... #else ...
     default:
       LOG(FATAL) << "unsupported LRU cache memory type: " << mem_type;
       return nullptr;
diff --git a/src/kudu/cfile/cfile-test.cc b/src/kudu/cfile/cfile-test.cc
index 84f5144..e5c4d51 100644
--- a/src/kudu/cfile/cfile-test.cc
+++ b/src/kudu/cfile/cfile-test.cc
@@ -402,7 +402,7 @@ class TestCFileBothCacheMemoryTypes :
     public ::testing::WithParamInterface<Cache::MemoryType> {
  public:
   void SetUp() OVERRIDE {
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
     // The NVM cache can run using any directory as its path -- it doesn't have
     // a lot of practical use outside of an actual NVM device, but for testing
     // purposes, we'll point it at our test dir, unless otherwise specified.
@@ -415,7 +415,7 @@ class TestCFileBothCacheMemoryTypes :
       case Cache::MemoryType::DRAM:
         FLAGS_block_cache_type = "DRAM";
         break;
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
       case Cache::MemoryType::NVM:
         FLAGS_block_cache_type = "NVM";
         break;
@@ -1039,7 +1039,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestCacheKeysAreStable) {
   }
 }
 
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
 // Inject failures in nvm allocation and ensure that we can still read a file.
 TEST_P(TestCFileBothCacheMemoryTypes, TestNvmAllocationFailure) {
   if (GetParam() != Cache::MemoryType::NVM) return;
diff --git a/src/kudu/util/CMakeLists.txt b/src/kudu/util/CMakeLists.txt
index 47334c6..a820114 100644
--- a/src/kudu/util/CMakeLists.txt
+++ b/src/kudu/util/CMakeLists.txt
@@ -239,7 +239,7 @@ set(UTIL_SRCS
 # optimized regardless of the default optimization options.
 set_source_files_properties(memory/overwrite.cc PROPERTIES COMPILE_FLAGS "-O3")
 
-if(HAVE_LIB_VMEM)
+if(HAVE_LIB_MEMKIND)
   set(UTIL_SRCS
     ${UTIL_SRCS}
     nvm_cache.cc)
@@ -269,10 +269,10 @@ if(NOT APPLE)
     rt)
 endif()
 
-if(HAVE_LIB_VMEM)
+if(HAVE_LIB_MEMKIND)
   set(UTIL_LIBS
     ${UTIL_LIBS}
-    vmem)
+    memkind)
 endif()
 
 # We use MallocExtension, but not in the exported version of the library.
@@ -340,9 +340,9 @@ target_link_libraries(kudu_test_util
   gmock
   kudu_util)
 
-if(HAVE_LIB_VMEM)
+if(HAVE_LIB_MEMKIND)
   target_link_libraries(kudu_test_util
-    vmem)
+    memkind)
 endif()
 
 #######################################
diff --git a/src/kudu/util/cache-test.cc b/src/kudu/util/cache-test.cc
index df106ec..66c78e9 100644
--- a/src/kudu/util/cache-test.cc
+++ b/src/kudu/util/cache-test.cc
@@ -30,9 +30,9 @@
 #include "kudu/util/test_util.h"
 
 DECLARE_bool(cache_force_single_shard);
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
 DECLARE_string(nvm_cache_path);
-#endif // #if defined(HAVE_LIB_VMEM)
+#endif // #if defined(HAVE_LIB_MEMKIND)
 
 DECLARE_double(cache_memtracker_approximation_ratio);
 
@@ -111,12 +111,12 @@ class CacheBaseTest : public KuduTest,
     FLAGS_cache_force_single_shard =
         (sharding_policy == ShardingPolicy::SingleShard);
 
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
     if (google::GetCommandLineFlagInfoOrDie("nvm_cache_path").is_default) {
       FLAGS_nvm_cache_path = GetTestPath("nvm-cache");
       ASSERT_OK(Env::Default()->CreateDir(FLAGS_nvm_cache_path));
     }
-#endif // #if defined(HAVE_LIB_VMEM)
+#endif // #if defined(HAVE_LIB_MEMKIND)
 
     switch (eviction_policy) {
       case Cache::EvictionPolicy::FIFO:
@@ -136,13 +136,13 @@ class CacheBaseTest : public KuduTest,
                                                            "cache_test"));
             break;
           case Cache::MemoryType::NVM:
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
             cache_.reset(NewCache<Cache::EvictionPolicy::LRU,
                                   Cache::MemoryType::NVM>(cache_size(),
                                                           "cache_test"));
 #else
             FAIL() << "cache of NVM memory type is not supported";
-#endif // #if defined(HAVE_LIB_VMEM) ... #else ...
+#endif // #if defined(HAVE_LIB_MEMKIND) ... #else ...
             break;
           default:
             FAIL() << mem_type << ": unrecognized cache memory type";
@@ -182,7 +182,7 @@ class CacheTest :
                                                ShardingPolicy>> {
  public:
   CacheTest()
-      : CacheBaseTest(14 * 1024 * 1024) {
+      : CacheBaseTest(16 * 1024 * 1024) {
   }
 
   void SetUp() override {
@@ -193,7 +193,7 @@ class CacheTest :
   }
 };
 
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
 INSTANTIATE_TEST_CASE_P(
     CacheTypes, CacheTest,
     ::testing::Values(
@@ -223,7 +223,7 @@ INSTANTIATE_TEST_CASE_P(
                                          Cache::EvictionPolicy::LRU),
                        ::testing::Values(ShardingPolicy::MultiShard,
                                          ShardingPolicy::SingleShard)));
-#endif // #if defined(HAVE_LIB_VMEM) ... #else ...
+#endif // #if defined(HAVE_LIB_MEMKIND) ... #else ...
 
 TEST_P(CacheTest, TrackMemory) {
   if (mem_tracker_) {
@@ -495,7 +495,7 @@ class LRUCacheTest :
                                                ShardingPolicy>> {
  public:
   LRUCacheTest()
-      : CacheBaseTest(14 * 1024 * 1024) {
+      : CacheBaseTest(16 * 1024 * 1024) {
   }
 
   void SetUp() override {
@@ -506,7 +506,7 @@ class LRUCacheTest :
   }
 };
 
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
 INSTANTIATE_TEST_CASE_P(
     CacheTypes, LRUCacheTest,
     ::testing::Combine(::testing::Values(Cache::MemoryType::DRAM,
@@ -519,7 +519,7 @@ INSTANTIATE_TEST_CASE_P(
     ::testing::Combine(::testing::Values(Cache::MemoryType::DRAM),
                        ::testing::Values(ShardingPolicy::MultiShard,
                                          ShardingPolicy::SingleShard)));
-#endif // #if defined(HAVE_LIB_VMEM) ... #else ...
+#endif // #if defined(HAVE_LIB_MEMKIND) ... #else ...
 
 TEST_P(LRUCacheTest, EvictionPolicy) {
   static constexpr int kNumElems = 1000;
diff --git a/src/kudu/util/cache.cc b/src/kudu/util/cache.cc
index 1c0378c..5fced3c 100644
--- a/src/kudu/util/cache.cc
+++ b/src/kudu/util/cache.cc
@@ -697,7 +697,7 @@ Cache* NewCache<Cache::EvictionPolicy::LRU,
   return new ShardedCache<Cache::EvictionPolicy::LRU>(capacity, id);
 }
 
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
 template<>
 Cache* NewCache<Cache::EvictionPolicy::LRU,
                 Cache::MemoryType::NVM>(size_t capacity, const std::string& id) {
diff --git a/src/kudu/util/cache.h b/src/kudu/util/cache.h
index 6c90b0f..11535c8 100644
--- a/src/kudu/util/cache.h
+++ b/src/kudu/util/cache.h
@@ -357,7 +357,7 @@ template<>
 Cache* NewCache<Cache::EvictionPolicy::LRU,
                 Cache::MemoryType::DRAM>(size_t capacity, const std::string& id);
 
-#if defined(HAVE_LIB_VMEM)
+#if defined(HAVE_LIB_MEMKIND)
 // Create a new LRU cache with a fixed size capacity. This implementation
 // of Cache uses the least-recently-used eviction policy and stored in NVM.
 template<>
diff --git a/src/kudu/util/nvm_cache.cc b/src/kudu/util/nvm_cache.cc
index 4d3497b..cde012c 100644
--- a/src/kudu/util/nvm_cache.cc
+++ b/src/kudu/util/nvm_cache.cc
@@ -5,10 +5,9 @@
 //   found in the LICENSE file.
 //
 // ------------------------------------------------------------
-// This file implements a cache based on the NVML library (http://pmem.io),
-// specifically its "libvmem" component. This library makes it easy to program
-// against persistent memory hardware by exposing an API which parallels
-// malloc/free, but allocates from persistent memory instead of DRAM.
+// This file implements a cache based on the MEMKIND library (http://memkind.github.io/memkind/)
+// This library makes it easy to program against persistent memory hardware by exposing an
API
+// which parallels malloc/free, but allocates from persistent memory instead of DRAM.
 //
 // We use this API to implement a cache which treats persistent memory or
 // non-volatile memory as if it were a larger cheaper bank of volatile memory. We
@@ -30,11 +29,13 @@
 #include <vector>
 
 #include <gflags/gflags.h>
+#include <gflags/gflags_declare.h>
 #include <glog/logging.h>
-#include <libvmem.h>
+#include <memkind.h>
 
 #include "kudu/gutil/atomic_refcount.h"
 #include "kudu/gutil/atomicops.h"
+#include "kudu/gutil/bits.h"
 #include "kudu/gutil/dynamic_annotations.h"
 #include "kudu/gutil/gscoped_ptr.h"
 #include "kudu/gutil/hash/city.h"
@@ -42,6 +43,7 @@
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/ref_counted.h"
 #include "kudu/gutil/stl_util.h"
+#include "kudu/gutil/sysinfo.h"
 #include "kudu/util/cache.h"
 #include "kudu/util/cache_metrics.h"
 #include "kudu/util/flag_tags.h"
@@ -49,7 +51,12 @@
 #include "kudu/util/metrics.h"
 #include "kudu/util/slice.h"
 
-DEFINE_string(nvm_cache_path, "/vmem",
+struct memkind;
+
+// Useful in tests that require accurate cache capacity accounting.
+DECLARE_bool(cache_force_single_shard);
+
+DEFINE_string(nvm_cache_path, "/pmem",
               "The path at which the NVM cache will try to allocate its memory. "
               "This can be a tmpfs or ramfs for testing purposes.");
 TAG_FLAG(nvm_cache_path, experimental);
@@ -62,7 +69,7 @@ TAG_FLAG(nvm_cache_allocation_retry_count, advanced);
 TAG_FLAG(nvm_cache_allocation_retry_count, experimental);
 
 DEFINE_bool(nvm_cache_simulate_allocation_failure, false,
-            "If true, the NVM cache will inject failures in calls to vmem_malloc "
+            "If true, the NVM cache will inject failures in calls to memkind_malloc "
             "for testing.");
 TAG_FLAG(nvm_cache_simulate_allocation_failure, unsafe);
 
@@ -112,7 +119,7 @@ struct LRUHandle {
 // 4.4.3's builtin hashtable.
 class HandleTable {
  public:
-  HandleTable() : length_(0), elems_(0), list_(NULL) { Resize(); }
+  HandleTable() : length_(0), elems_(0), list_(nullptr) { Resize(); }
   ~HandleTable() { delete[] list_; }
 
   LRUHandle* Lookup(const Slice& key, uint32_t hash) {
@@ -122,9 +129,9 @@ class HandleTable {
   LRUHandle* Insert(LRUHandle* h) {
     LRUHandle** ptr = FindPointer(h->key(), h->hash);
     LRUHandle* old = *ptr;
-    h->next_hash = (old == NULL ? NULL : old->next_hash);
+    h->next_hash = (old == nullptr ? nullptr : old->next_hash);
     *ptr = h;
-    if (old == NULL) {
+    if (old == nullptr) {
       ++elems_;
       if (elems_ > length_) {
         // Since each cache entry is fairly large, we aim for a small
@@ -138,7 +145,7 @@ class HandleTable {
   LRUHandle* Remove(const Slice& key, uint32_t hash) {
     LRUHandle** ptr = FindPointer(key, hash);
     LRUHandle* result = *ptr;
-    if (result != NULL) {
+    if (result != nullptr) {
       *ptr = result->next_hash;
       --elems_;
     }
@@ -157,7 +164,7 @@ class HandleTable {
   // pointer to the trailing slot in the corresponding linked list.
   LRUHandle** FindPointer(const Slice& key, uint32_t hash) {
     LRUHandle** ptr = &list_[hash & (length_ - 1)];
-    while (*ptr != NULL &&
+    while (*ptr != nullptr &&
            ((*ptr)->hash != hash || key != (*ptr)->key())) {
       ptr = &(*ptr)->next_hash;
     }
@@ -174,7 +181,7 @@ class HandleTable {
     uint32_t count = 0;
     for (uint32_t i = 0; i < length_; i++) {
       LRUHandle* h = list_[i];
-      while (h != NULL) {
+      while (h != nullptr) {
         LRUHandle* next = h->next_hash;
         uint32_t hash = h->hash;
         LRUHandle** ptr = &new_list[hash & (new_length - 1)];
@@ -194,7 +201,7 @@ class HandleTable {
 // A single shard of sharded cache.
 class NvmLRUCache {
  public:
-  explicit NvmLRUCache(VMEM *vmp);
+  explicit NvmLRUCache(memkind *vmp);
   ~NvmLRUCache();
 
   // Separate from constructor so caller can easily make an array of LRUCache
@@ -202,7 +209,7 @@ class NvmLRUCache {
 
   void SetMetrics(CacheMetrics* metrics) { metrics_ = metrics; }
 
-  Cache::Handle* Insert(LRUHandle* h, Cache::EvictionCallback* eviction_callback);
+  Cache::Handle* Insert(LRUHandle* e, Cache::EvictionCallback* eviction_callback);
 
   // Like Cache::Lookup, but with an extra "hash" parameter.
   Cache::Handle* Lookup(const Slice& key, uint32_t hash, bool caching);
@@ -227,8 +234,8 @@ class NvmLRUCache {
   // as its head.
   void FreeLRUEntries(LRUHandle* to_free_head);
 
-  // Wrapper around vmem_malloc which injects failures based on a flag.
-  void* VmemMalloc(size_t size);
+  // Wrapper around memkind_malloc which injects failures based on a flag.
+  void* MemkindMalloc(size_t size);
 
   // Initialized before use.
   size_t capacity_;
@@ -243,15 +250,15 @@ class NvmLRUCache {
 
   HandleTable table_;
 
-  VMEM* vmp_;
+  memkind* vmp_;
 
   CacheMetrics* metrics_;
 };
 
-NvmLRUCache::NvmLRUCache(VMEM* vmp)
+NvmLRUCache::NvmLRUCache(memkind* vmp)
   : usage_(0),
   vmp_(vmp),
-  metrics_(NULL) {
+  metrics_(nullptr) {
   // Make empty circular linked list
   lru_.next = &lru_;
   lru_.prev = &lru_;
@@ -268,11 +275,11 @@ NvmLRUCache::~NvmLRUCache() {
   }
 }
 
-void* NvmLRUCache::VmemMalloc(size_t size) {
+void* NvmLRUCache::MemkindMalloc(size_t size) {
   if (PREDICT_FALSE(FLAGS_nvm_cache_simulate_allocation_failure)) {
-    return NULL;
+    return nullptr;
   }
-  return vmem_malloc(vmp_, size);
+  return memkind_malloc(vmp_, size);
 }
 
 bool NvmLRUCache::Unref(LRUHandle* e) {
@@ -289,7 +296,7 @@ void NvmLRUCache::FreeEntry(LRUHandle* e) {
     metrics_->cache_usage->DecrementBy(e->charge);
     metrics_->evictions->Increment();
   }
-  vmem_free(vmp_, e);
+  memkind_free(vmp_, e);
 }
 
 // Allocate nvm memory. Try until successful or FLAGS_nvm_cache_allocation_retry_count
@@ -300,21 +307,21 @@ void *NvmLRUCache::AllocateAndRetry(size_t size) {
   // a fixed size to allocate from. If we cannot allocate the size
   // that was asked for, we will remove entries from the cache and
   // retry up to the configured number of retries. If this fails, we
-  // return NULL, which will cause the caller to not insert anything
+  // return nullptr, which will cause the caller to not insert anything
   // into the cache.
-  LRUHandle *to_remove_head = NULL;
-  tmp = VmemMalloc(size);
+  LRUHandle *to_remove_head = nullptr;
+  tmp = MemkindMalloc(size);
 
-  if (tmp == NULL) {
+  if (tmp == nullptr) {
     std::unique_lock<MutexType> l(mutex_);
 
     int retries_remaining = FLAGS_nvm_cache_allocation_retry_count;
-    while (tmp == NULL && retries_remaining-- > 0 && lru_.next != &lru_)
{
+    while (tmp == nullptr && retries_remaining-- > 0 && lru_.next != &lru_)
{
       EvictOldestUnlocked(&to_remove_head);
 
       // Unlock while allocating memory.
       l.unlock();
-      tmp = VmemMalloc(size);
+      tmp = MemkindMalloc(size);
       l.lock();
     }
   }
@@ -345,7 +352,7 @@ Cache::Handle* NvmLRUCache::Lookup(const Slice& key, uint32_t hash,
bool caching
   {
     std::lock_guard<MutexType> l(mutex_);
     e = table_.Lookup(key, hash);
-    if (e != NULL) {
+    if (e != nullptr) {
       // If an entry exists, remove the old entry from the cache
       // and re-add to the end of the linked list.
       base::RefCountInc(&e->refs);
@@ -357,7 +364,7 @@ Cache::Handle* NvmLRUCache::Lookup(const Slice& key, uint32_t hash,
bool caching
   // Do the metrics outside of the lock.
   if (metrics_) {
     metrics_->lookups->Increment();
-    bool was_hit = (e != NULL);
+    bool was_hit = (e != nullptr);
     if (was_hit) {
       if (caching) {
         metrics_->cache_hits_caching->Increment();
@@ -395,7 +402,7 @@ void NvmLRUCache::EvictOldestUnlocked(LRUHandle** to_remove_head) {
 }
 
 void NvmLRUCache::FreeLRUEntries(LRUHandle* to_free_head) {
-  while (to_free_head != NULL) {
+  while (to_free_head != nullptr) {
     LRUHandle* next = to_free_head->next;
     FreeEntry(to_free_head);
     to_free_head = next;
@@ -405,7 +412,7 @@ void NvmLRUCache::FreeLRUEntries(LRUHandle* to_free_head) {
 Cache::Handle* NvmLRUCache::Insert(LRUHandle* e,
                                    Cache::EvictionCallback* eviction_callback) {
   DCHECK(e);
-  LRUHandle* to_remove_head = NULL;
+  LRUHandle* to_remove_head = nullptr;
 
   e->refs = 2;  // One from LRUCache, one for the returned handle
   e->eviction_callback = eviction_callback;
@@ -420,7 +427,7 @@ Cache::Handle* NvmLRUCache::Insert(LRUHandle* e,
     NvmLRU_Append(e);
 
     LRUHandle* old = table_.Insert(e);
-    if (old != NULL) {
+    if (old != nullptr) {
       NvmLRU_Remove(old);
       if (Unref(old)) {
         old->next = to_remove_head;
@@ -446,13 +453,13 @@ void NvmLRUCache::Erase(const Slice& key, uint32_t hash) {
   {
     std::lock_guard<MutexType> l(mutex_);
     e = table_.Remove(key, hash);
-    if (e != NULL) {
+    if (e != nullptr) {
       NvmLRU_Remove(e);
       last_reference = Unref(e);
     }
   }
   // mutex not held here
-  // last_reference will only be true if e != NULL
+  // last_reference will only be true if e != nullptr
   if (last_reference) {
     FreeEntry(e);
   }
@@ -496,30 +503,44 @@ size_t NvmLRUCache::Invalidate(const Cache::InvalidationControl&
ctl) {
   return invalid_entry_count;
 }
 
-constexpr const int kNumShardBits = 4;
-constexpr const int kNumShards = 1 << kNumShardBits;
+// Determine the number of bits of the hash that should be used to determine
+// the cache shard. This, in turn, determines the number of shards.
+int DetermineShardBits() {
+  int bits = PREDICT_FALSE(FLAGS_cache_force_single_shard) ?
+      0 : Bits::Log2Ceiling(base::NumCPUs());
+  VLOG(1) << "Will use " << (1 << bits) << " shards for LRU cache.";
+  return bits;
+}
 
 class ShardedLRUCache : public Cache {
  private:
   unique_ptr<CacheMetrics> metrics_;
   vector<NvmLRUCache*> shards_;
-  VMEM* vmp_;
+
+  // Number of bits of hash used to determine the shard.
+  const int shard_bits_;
+
+  memkind* vmp_;
 
   static inline uint32_t HashSlice(const Slice& s) {
     return util_hash::CityHash64(
       reinterpret_cast<const char *>(s.data()), s.size());
   }
 
-  static uint32_t Shard(uint32_t hash) {
-    return hash >> (32 - kNumShardBits);
+  uint32_t Shard(uint32_t hash) {
+    // Widen to uint64 before shifting, or else on a single CPU,
+    // we would try to shift a uint32_t by 32 bits, which is undefined.
+    return static_cast<uint64_t>(hash) >> (32 - shard_bits_);
   }
 
  public:
-  explicit ShardedLRUCache(size_t capacity, const string& /*id*/, VMEM* vmp)
-        : vmp_(vmp) {
+  explicit ShardedLRUCache(size_t capacity, const string& /*id*/, memkind* vmp)
+        : vmp_(vmp),
+          shard_bits_(DetermineShardBits()) {
 
-    const size_t per_shard = (capacity + (kNumShards - 1)) / kNumShards;
-    for (int s = 0; s < kNumShards; s++) {
+    int num_shards = 1 << shard_bits_;
+    const size_t per_shard = (capacity + (num_shards - 1)) / num_shards;
+    for (int s = 0; s < num_shards; s++) {
       gscoped_ptr<NvmLRUCache> shard(new NvmLRUCache(vmp_));
       shard->SetCapacity(per_shard);
       shards_.push_back(shard.release());
@@ -530,8 +551,8 @@ class ShardedLRUCache : public Cache {
     STLDeleteElements(&shards_);
     // Per the note at the top of this file, our cache is entirely volatile.
     // Hence, when the cache is destructed, we delete the underlying
-    // VMEM pool.
-    vmem_delete(vmp_);
+    // memkind pool.
+    memkind_destroy_kind(vmp_);
   }
 
   virtual UniqueHandle Insert(UniquePendingHandle handle,
@@ -573,7 +594,7 @@ class ShardedLRUCache : public Cache {
     DCHECK_GE(key_len, 0);
     DCHECK_GE(val_len, 0);
 
-    // Try allocating from each of the shards -- if vmem is tight,
+    // Try allocating from each of the shards -- if memkind is tight,
     // this can cause eviction, so we might have better luck in different
     // shards.
     for (NvmLRUCache* cache : shards_) {
@@ -587,7 +608,7 @@ class ShardedLRUCache : public Cache {
         handle->val_length = val_len;
         handle->key_length = key_len;
         handle->charge = (charge == kAutomaticCharge) ?
-            vmem_malloc_usable_size(vmp_, buf) : charge;
+            memkind_malloc_usable_size(vmp_, buf) : charge;
         handle->hash = HashSlice(key);
         memcpy(handle->kv_data, key.data(), key.size());
         return ph;
@@ -598,7 +619,7 @@ class ShardedLRUCache : public Cache {
   }
 
   virtual void Free(PendingHandle* ph) OVERRIDE {
-    vmem_free(vmp_, ph);
+    memkind_free(vmp_, ph);
   }
 
   size_t Invalidate(const InvalidationControl& ctl) override {
@@ -613,18 +634,19 @@ class ShardedLRUCache : public Cache {
 } // end anonymous namespace
 
 Cache* NewLRUNvmCache(size_t capacity, const std::string& id) {
-  // vmem_create() will fail if the capacity is too small, but with
+  // memkind_create_pmem() will fail if the capacity is too small, but with
   // an inscrutable error. So, we'll check ourselves.
-  CHECK_GE(capacity, VMEM_MIN_POOL)
+  CHECK_GE(capacity, MEMKIND_PMEM_MIN_SIZE)
     << "configured capacity " << capacity << " bytes is less than "
-    << "the minimum capacity for an NVM cache: " << VMEM_MIN_POOL;
+    << "the minimum capacity for an NVM cache: " << MEMKIND_PMEM_MIN_SIZE;
 
-  VMEM* vmp = vmem_create(FLAGS_nvm_cache_path.c_str(), capacity);
+  memkind* vmp;
+  int err = memkind_create_pmem(FLAGS_nvm_cache_path.c_str(), capacity, &vmp);
   // If we cannot create the cache pool we should not retry.
-  PLOG_IF(FATAL, vmp == NULL) << "Could not initialize NVM cache library in path "
-                              << FLAGS_nvm_cache_path.c_str();
+  PLOG_IF(FATAL, err) << "Could not initialize NVM cache library in path "
+                           << FLAGS_nvm_cache_path.c_str();
 
   return new ShardedLRUCache(capacity, id, vmp);
 }
 
-}  // namespace kudu
+} // namespace kudu
diff --git a/thirdparty/LICENSE.txt b/thirdparty/LICENSE.txt
index 6477bae..bc2dab0 100644
--- a/thirdparty/LICENSE.txt
+++ b/thirdparty/LICENSE.txt
@@ -539,55 +539,45 @@ Source: http://savannah.nongnu.org/projects/libunwind/
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 --------------------------------------------------------------------------------
-thirdparty/nvml-*/: BSD 3-clause license
-libraries: libvmem
-Source: https://github.com/pmem/nvml
+thirdparty/memkind-*/
+libraries: libmemkind
+Source: https://github.com/memkind/memkind
 
-  Copyright (c) 2014-2015, Intel Corporation
+  Unless otherwise specified, files in the memkind source distribution are
+  subject to the following license:
 
   Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-      * Redistributions of source code must retain the above copyright
-        notice, this list of conditions and the following disclaimer.
+  modification, are permitted provided that the following conditions are met:
 
+      * Redistributions of source code must retain the above copyright notice,
+        this list of conditions and the following disclaimer.
       * Redistributions in binary form must reproduce the above copyright
-        notice, this list of conditions and the following disclaimer in
-        the documentation and/or other materials provided with the
-        distribution.
-
-      * Neither the name of Intel Corporation nor the names of its
-        contributors may be used to endorse or promote products derived
-        from this software without specific prior written permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+      * Neither the name of Intel Corporation nor the names of its contributors
+        may be used to endorse or promote products derived from this software
+        without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+memkind bundles jemalloc which is licensed under the BSD 2-clause license:
 
-  Everything in this source tree is covered by the previous license
-  with the following exceptions:
-
-  * src/jemalloc has its own (somewhat similar) license contained in
-    src/jemalloc/COPYING.
-
-  * utils/cstyle (used only during development) licensed under CDDL.
-
-nvml bundles jemalloc which is licensed under the BSD 2-clause license:
+  Unless otherwise specified, files in the jemalloc source distribution are
+  subject to the following license:
 
-  Copyright (C) 2002-2014 Jason Evans <jasone@canonware.com>.
+  Copyright (C) 2002-2017 Jason Evans <jasone@canonware.com>.
   All rights reserved.
   Copyright (C) 2007-2012 Mozilla Foundation.  All rights reserved.
-  Copyright (C) 2009-2014 Facebook, Inc.  All rights reserved.
+  Copyright (C) 2009-2017 Facebook, Inc.  All rights reserved.
 
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
diff --git a/thirdparty/build-definitions.sh b/thirdparty/build-definitions.sh
index 609b7b4..4df64f6 100644
--- a/thirdparty/build-definitions.sh
+++ b/thirdparty/build-definitions.sh
@@ -747,36 +747,70 @@ build_trace_viewer() {
   cp -a $TRACE_VIEWER_SOURCE/tracing.* $TP_DIR/../www/
 }
 
-build_nvml() {
-  NVML_BDIR=$TP_BUILD_DIR/$NVML_NAME$MODE_SUFFIX
-  mkdir -p $NVML_BDIR
-  pushd $NVML_BDIR
+build_numactl() {
+  local BUILD_TYPE=$1
+
+  NUMACTL_BDIR=$TP_BUILD_DIR/$NUMACTL_NAME$MODE_SUFFIX
+  mkdir -p $NUMACTL_BDIR
+  pushd $NUMACTL_BDIR
+
+  # Setting -fsanitize=thread only in CFLAGS does not work for compiling numactl,
+  # We also need to set it in LDFLAGS.
+  case $BUILD_TYPE in
+    "normal")
+      ;;
+    "tsan")
+      SANITIZER_THREAD_OPTION="-fsanitize=thread -L$PREFIX/lib -Wl,-rpath=$PREFIX/lib"
+      ;;
+    *)
+      echo "Unknown build type: $BUILD_TYPE"
+      exit 1
+      ;;
+  esac
+
+  CFLAGS="$EXTRA_CFLAGS" \
+    LDFLAGS="$EXTRA_LDFLAGS $SANITIZER_THREAD_OPTION" \
+    CPPFLAGS="$EXTRA_CPPFLAGS" \
+    LIBS="$EXTRA_LIBS" \
+  $NUMACTL_SOURCE/configure --prefix=$PREFIX
+
+  make -j$PARALLEL $EXTRA_MAKEFLAGS install
+  popd
+}
+
+build_memkind() {
+  MEMKIND_BDIR=$TP_BUILD_DIR/$MEMKIND_NAME$MODE_SUFFIX
+  mkdir -p $MEMKIND_BDIR
+  pushd $MEMKIND_BDIR
 
   # It doesn't appear possible to isolate source and build directories, so just
   # prepopulate the latter using the former.
-  rsync -av --delete $NVML_SOURCE/ .
-  cd src/
+  rsync -av --delete $MEMKIND_SOURCE/ .
+
+  # We separate the build steps from build.sh in memkind source code
+  # since we need to avoid building the tests code with thread sanitizer
+  export JE_PREFIX=jemk_
+
+  # jemalloc is built in memkind and need to be compiled firstly. Here we disable c++
+  # integration to prevent new and delete operator implementations from exported in kudu
client
+  $MEMKIND_BDIR/build_jemalloc.sh --disable-cxx --prefix=$PREFIX
+
+  $MEMKIND_BDIR/autogen.sh
+  CFLAGS="$EXTRA_CFLAGS -O2" \
+    CPPFLAGS="$EXTRA_CPPFLAGS -I$PREFIX/include" \
+    LDFLAGS="$EXTRA_LDFLAGS -L$PREFIX/lib -Wl,-rpath=$PREFIX/lib" \
+    LIBS="$EXTRA_LIBS" \
+    $MEMKIND_BDIR/configure --prefix=$PREFIX
+
+  # Building unit tests and memkind examples in memkind with clang will prevent some
+  # header files from being included which will lead to failures. So we do a minimal
+  # installation here.
+  make -j$PARALLEL $EXTRA_MAKEFLAGS static_lib install-exec install-data
+  # install jemalloc header files
+  cd $MEMKIND_BDIR/jemalloc/obj && make -j$PARALLEL $EXTRA_MAKEFLAGS install_include
+
+  unset JE_PREFIX
 
-  # The embedded jemalloc build doesn't pick up the EXTRA_CFLAGS environment
-  # variable, so we have to stick our flags into this config file.
-  if ! grep -q -e "$EXTRA_CFLAGS" jemalloc/jemalloc.cfg ; then
-    perl -p -i -e "s,(EXTRA_CFLAGS=\"),\$1$EXTRA_CFLAGS ," jemalloc/jemalloc.cfg
-  fi
-  for LIB in libvmem libpmem libpmemobj; do
-    # Disable -Werror; it prevents jemalloc from building via clang.
-    #
-    # Add PREFIX/lib to the rpath; libpmemobj depends on libpmem at runtime.
-    EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-error" \
-      EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-rpath,$PREFIX/lib" \
-      make -j$PARALLEL $EXTRA_MAKEFLAGS DEBUG=0 $LIB
-
-    # NVML doesn't allow configuring PREFIX -- it always installs into
-    # DESTDIR/usr/lib. Additionally, the 'install' target builds all of
-    # the NVML libraries, even though we only need the three libraries above.
-    # So, we manually install the built artifacts.
-    cp -a $NVML_BDIR/src/include/$LIB.h $PREFIX/include
-    cp -a $NVML_BDIR/src/nondebug/$LIB.{so*,a} $PREFIX/lib
-  done
   popd
 }
 
diff --git a/thirdparty/build-thirdparty.sh b/thirdparty/build-thirdparty.sh
index 0c2d451..169300d 100755
--- a/thirdparty/build-thirdparty.sh
+++ b/thirdparty/build-thirdparty.sh
@@ -90,7 +90,8 @@ else
       "libunwind")    F_LIBUNWIND=1 ;;
       "llvm")         F_LLVM=1 ;;
       "trace-viewer") F_TRACE_VIEWER=1 ;;
-      "nvml")         F_NVML=1 ;;
+      "numactl")      F_NUMACTL=1 ;;
+      "memkind")      F_MEMKIND=1 ;;
       "boost")        F_BOOST=1 ;;
       "breakpad")     F_BREAKPAD=1 ;;
       "sparsehash")   F_SPARSEHASH=1 ;;
@@ -306,8 +307,12 @@ if [ -n "$F_UNINSTRUMENTED" -o -n "$F_CURL" ]; then
   build_curl
 fi
 
-if [ -n "$OS_LINUX" ] && [ -n "$F_UNINSTRUMENTED" -o -n "$F_NVML" ]; then
-  build_nvml
+if [ -n "$OS_LINUX" ] && [ -n "$F_UNINSTRUMENTED" -o -n "$F_NUMACTL" ]; then
+  build_numactl normal
+fi
+
+if [ -n "$OS_LINUX" ] && [ -n "$F_UNINSTRUMENTED" -o -n "$F_MEMKIND" ]; then
+  build_memkind
 fi
 
 restore_env
@@ -461,8 +466,12 @@ if [ -n "$F_TSAN" -o -n "$F_CURL" ]; then
   build_curl
 fi
 
-if [ -n "$OS_LINUX" ] && [ -n "$F_TSAN" -o -n "$F_NVML" ]; then
-  build_nvml
+if [ -n "$OS_LINUX" ] && [ -n "$F_TSAN" -o -n "$F_NUMACTL" ]; then
+  build_numactl tsan
+fi
+
+if [ -n "$OS_LINUX" ] && [ -n "$F_TSAN" -o -n "$F_MEMKIND" ]; then
+  build_memkind
 fi
 
 restore_env
diff --git a/thirdparty/download-thirdparty.sh b/thirdparty/download-thirdparty.sh
index 7eeccdf..d4213ff 100755
--- a/thirdparty/download-thirdparty.sh
+++ b/thirdparty/download-thirdparty.sh
@@ -349,11 +349,17 @@ fetch_and_patch \
  $TRACE_VIEWER_SOURCE \
  $TRACE_VIEWER_PATCHLEVEL
 
-NVML_PATCHLEVEL=0
+NUMACTL_PATCHLEVEL=0
 fetch_and_patch \
- nvml-${NVML_VERSION}.tar.gz \
- $NVML_SOURCE \
- $NVML_PATCHLEVEL
+ numactl-${NUMACTL_VERSION}.tar.gz \
+ $NUMACTL_SOURCE \
+ $NUMACTL_PATCHLEVEL
+
+MEMKIND_PATCHLEVEL=0
+fetch_and_patch \
+ memkind-${MEMKIND_VERSION}.tar.gz \
+ $MEMKIND_SOURCE \
+ $MEMKIND_PATCHLEVEL
 
 BOOST_PATCHLEVEL=1
 fetch_and_patch \
diff --git a/thirdparty/vars.sh b/thirdparty/vars.sh
index 8f2651e..a291e36 100644
--- a/thirdparty/vars.sh
+++ b/thirdparty/vars.sh
@@ -166,9 +166,14 @@ TRACE_VIEWER_VERSION=21d76f8350fea2da2aa25cb6fd512703497d0c11
 TRACE_VIEWER_NAME=kudu-trace-viewer-$TRACE_VIEWER_VERSION
 TRACE_VIEWER_SOURCE=$TP_SOURCE_DIR/$TRACE_VIEWER_NAME
 
-NVML_VERSION=1.1
-NVML_NAME=nvml-$NVML_VERSION
-NVML_SOURCE=$TP_SOURCE_DIR/$NVML_NAME
+# numactl 2.0.12 is required to build memkind library.
+NUMACTL_VERSION=2.0.12
+NUMACTL_NAME=numactl-$NUMACTL_VERSION
+NUMACTL_SOURCE=$TP_SOURCE_DIR/$NUMACTL_NAME
+
+MEMKIND_VERSION=1.9.0
+MEMKIND_NAME=memkind-$MEMKIND_VERSION
+MEMKIND_SOURCE=$TP_SOURCE_DIR/$MEMKIND_NAME
 
 BOOST_VERSION=1_61_0
 BOOST_NAME=boost_$BOOST_VERSION


Mime
View raw message