Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-28599

Test MarkThreadTemporarilyIdle with free list initialization

    • Fully Compatible
    • v3.4
    • Platforms 2017-08-21, Platforms 2017-09-11, Platforms 2017-10-02, Platforms 2017-10-23, Platforms 2017-11-13
    • 0

      Unable to find source-code formatter for language: diff. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      diff --git a/src/mongo/util/SConscript b/src/mongo/util/SConscript
      index 17335ef..5d163c7 100644
      --- a/src/mongo/util/SConscript
      +++ b/src/mongo/util/SConscript
      @@ -249,6 +249,7 @@ if env['MONGO_ALLOCATOR'] == 'tcmalloc':
               tcmspEnv.Append(
                   CPPDEFINES=[
                       'MONGO_HAVE_GPERFTOOLS_GET_THREAD_CACHE_SIZE',
      +                'MONGO_HAVE_GPERFTOOLS_MARK_THREAD_TEMPORARILY_IDLE',
                       'MONGO_HAVE_GPERFTOOLS_SIZE_CLASS_STATS'
                   ]
               )
      diff --git a/src/mongo/util/tcmalloc_server_status_section.cpp b/src/mongo/util/tcmalloc_server_status_section.cpp
      index cc2d672..8365ad0 100644
      --- a/src/mongo/util/tcmalloc_server_status_section.cpp
      +++ b/src/mongo/util/tcmalloc_server_status_section.cpp
      @@ -79,8 +79,12 @@ void threadStateChange() {
           // terrible runaway if we're not careful.
           stdx::lock_guard<stdx::mutex> lk(tcmallocCleanupLock);
       #endif
      +#if MONGO_HAVE_GPERFTOOLS_MARK_THREAD_TEMPORARILY_IDLE
      +    MallocExtension::instance()->MarkThreadTemporarilyIdle();
      +#else
           MallocExtension::instance()->MarkThreadIdle();
           MallocExtension::instance()->MarkThreadBusy();
      +#endif
       }
       
       // Register threadStateChange callback
      diff --git a/src/third_party/gperftools-2.2/src/gperftools/malloc_extension.h b/src/third_party/gperftools-2.2/src/gperftools/malloc_extension.h
      index 06138f8..fba567f 100644
      --- a/src/third_party/gperftools-2.2/src/gperftools/malloc_extension.h
      +++ b/src/third_party/gperftools-2.2/src/gperftools/malloc_extension.h
      @@ -242,9 +242,16 @@ class PERFTOOLS_DLL_DECL MallocExtension {
         virtual void MarkThreadBusy();
       
         // Gets the size of this thread's cache in bytes.
      -  // MONGODB ADDITION
      +  // MONGODB ADDITIONS
         virtual size_t GetThreadCacheSize();
       
      +  // Like MarkThreadIdle, but does not destroy the internal data
      +  // structures of the thread cache. When the thread resumes, it wil
      +  // have an empty cache but will not need to pay to reconstruct the
      +  // cache data structures.
      +  virtual void MarkThreadTemporarilyIdle();
      +  // END MONGODB ADDITIONS
      + 
         // Gets the system allocator used by the malloc extension instance. Returns
         // NULL for malloc implementations that do not support pluggable system
         // allocators.
      diff --git a/src/third_party/gperftools-2.2/src/gperftools/malloc_extension_c.h b/src/third_party/gperftools-2.2/src/gperftools/malloc_extension_c.h
      index 72a0a7c..5c64dae3 100644
      --- a/src/third_party/gperftools-2.2/src/gperftools/malloc_extension_c.h
      +++ b/src/third_party/gperftools-2.2/src/gperftools/malloc_extension_c.h
      @@ -79,6 +79,8 @@ PERFTOOLS_DLL_DECL void MallocExtension_ReleaseToSystem(size_t num_bytes);
       PERFTOOLS_DLL_DECL void MallocExtension_ReleaseFreeMemory(void);
       PERFTOOLS_DLL_DECL size_t MallocExtension_GetEstimatedAllocatedSize(size_t size);
       PERFTOOLS_DLL_DECL size_t MallocExtension_GetAllocatedSize(const void* p);
      +PERFTOOLS_DLL_DECL size_t MallocExtension_GetThreadCacheSize(void);
      +PERFTOOLS_DLL_DECL void MallocExtension_MarkThreadTemporarilyIdle(void);
       
       /*
        * NOTE: These enum values MUST be kept in sync with the version in
      diff --git a/src/third_party/gperftools-2.2/src/malloc_extension.cc b/src/third_party/gperftools-2.2/src/malloc_extension.cc
      index 6fdb043..48872b8 100644
      --- a/src/third_party/gperftools-2.2/src/malloc_extension.cc
      +++ b/src/third_party/gperftools-2.2/src/malloc_extension.cc
      @@ -198,6 +198,10 @@ void MallocExtension::GetFreeListSizes(
         v->clear();
       }
       
      +void MallocExtension::MarkThreadTemporarilyIdle() {
      +  // Default implementation does nothing
      +}
      +
       // The current malloc extension object.
       
       static MallocExtension* current_instance;
      @@ -381,6 +385,8 @@ C_SHIM(ReleaseFreeMemory, void, (void), ());
       C_SHIM(ReleaseToSystem, void, (size_t num_bytes), (num_bytes));
       C_SHIM(GetEstimatedAllocatedSize, size_t, (size_t size), (size));
       C_SHIM(GetAllocatedSize, size_t, (const void* p), (p));
      +C_SHIM(GetThreadCacheSize, size_t, (void), ());
      +C_SHIM(MarkThreadTemporarilyIdle, void, (void), ());
       
       // Can't use the shim here because of the need to translate the enums.
       extern "C"
      diff --git a/src/third_party/gperftools-2.2/src/tcmalloc.cc b/src/third_party/gperftools-2.2/src/tcmalloc.cc
      index 0bc8baa..e7d54c5 100644
      --- a/src/third_party/gperftools-2.2/src/tcmalloc.cc
      +++ b/src/third_party/gperftools-2.2/src/tcmalloc.cc
      @@ -619,6 +619,10 @@ class TCMallocImplementation : public MallocExtension {
           return DumpHeapGrowthStackTraces();
         }
       
      +  virtual void MarkThreadTemporarilyIdle() {
      +    ThreadCache::BecomeTemporarilyIdle();
      +  }
      +
         virtual void Ranges(void* arg, RangeFunction func) {
           IterateOverRanges(arg, func);
         }
      diff --git a/src/third_party/gperftools-2.2/src/tests/markidle_unittest.cc b/src/third_party/gperftools-2.2/src/tests/markidle_unittest.cc
      index 827609f..7e59e51 100644
      --- a/src/third_party/gperftools-2.2/src/tests/markidle_unittest.cc
      +++ b/src/third_party/gperftools-2.2/src/tests/markidle_unittest.cc
      @@ -98,11 +98,28 @@ static void TestIdleUsage() {
         VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
       }
       
      +static void TestTemporarilyIdleUsage() {
      +  const size_t original = MallocExtension::instance()->GetThreadCacheSize();
      +
      +  TestAllocation();
      +  const size_t post_allocation = MallocExtension::instance()->GetThreadCacheSize();
      +  CHECK_GT(post_allocation, original);
      +
      +  MallocExtension::instance()->MarkThreadIdle();
      +  const size_t post_idle = MallocExtension::instance()->GetThreadCacheSize();
      +  CHECK_EQ(post_idle, 0);
      +
      +  // Log after testing because logging can allocate heap memory.
      +  VLOG(0, "Original usage: %" PRIuS "\n", original);
      +  VLOG(0, "Post allocation: %" PRIuS "\n", post_allocation);
      +  VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
      +}
      +
       int main(int argc, char** argv) {
         RunThread(&TestIdleUsage);
         RunThread(&TestAllocation);
         RunThread(&MultipleIdleCalls);
      -  RunThread(&MultipleIdleNonIdlePhases);
      +  RunThread(&TestTemporarilyIdleUsage);
       
         printf("PASS\n");
         return 0;
      diff --git a/src/third_party/gperftools-2.2/src/thread_cache.cc b/src/third_party/gperftools-2.2/src/thread_cache.cc
      index b98fbee..7a8b8c0 100644
      --- a/src/third_party/gperftools-2.2/src/thread_cache.cc
      +++ b/src/third_party/gperftools-2.2/src/thread_cache.cc
      @@ -437,6 +437,17 @@ void ThreadCache::BecomeIdle() {
         DeleteCache(heap);
       }
       
      +void ThreadCache::BecomeTemporarilyIdle() {
      +  ThreadCache* heap = GetCacheIfPresent();
      +  if (heap) {
      +    heap->Cleanup();
      +    /* init state of free lists */
      +    for (size_t cl = 0; cl < kNumClasses; ++cl) {
      +      heap->list_[cl].Init();
      +    }
      +  }
      +}
      +
       void ThreadCache::DestroyThreadCache(void* ptr) {
         // Note that "ptr" cannot be NULL since pthread promises not
         // to invoke the destructor on NULL values, but for safety,
      diff --git a/src/third_party/gperftools-2.2/src/thread_cache.h b/src/third_party/gperftools-2.2/src/thread_cache.h
      index 5f0dc12..7d5c2dc 100644
      --- a/src/third_party/gperftools-2.2/src/thread_cache.h
      +++ b/src/third_party/gperftools-2.2/src/thread_cache.h
      @@ -116,6 +116,7 @@ class ThreadCache {
         static ThreadCache* GetCacheWhichMustBePresent();
         static ThreadCache* CreateCacheIfNecessary();
         static void         BecomeIdle();
      +  static void         BecomeTemporarilyIdle();
         static size_t       MinSizeForSlowPath();
         static void         SetMinSizeForSlowPath(size_t size);
       
      

            Assignee:
            mark.benvenuto@mongodb.com Mark Benvenuto
            Reporter:
            ramon.fernandez@mongodb.com Ramon Fernandez Marina
            Votes:
            0 Vote for this issue
            Watchers:
            18 Start watching this issue

              Created:
              Updated:
              Resolved: