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

Test MarkThreadTemporarilyIdle with free list initialization

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 3.6.0-rc3
    • Component/s: Internal Code
    • Labels:
    • Backwards Compatibility:
      Fully Compatible
    • Backport Requested:
      v3.4
    • Sprint:
      Platforms 2017-08-21, Platforms 2017-09-11, Platforms 2017-10-02, Platforms 2017-10-23, Platforms 2017-11-13
    • Linked BF Score:
      0

      Description

      1
      diff --git a/src/mongo/util/SConscript b/src/mongo/util/SConscript
      2
      index 17335ef..5d163c7 100644
      3
      --- a/src/mongo/util/SConscript
      4
      +++ b/src/mongo/util/SConscript
      5
      @@ -249,6 +249,7 @@ if env['MONGO_ALLOCATOR'] == 'tcmalloc':
      6
               tcmspEnv.Append(
      7
                   CPPDEFINES=[
      8
                       'MONGO_HAVE_GPERFTOOLS_GET_THREAD_CACHE_SIZE',
      9
      +                'MONGO_HAVE_GPERFTOOLS_MARK_THREAD_TEMPORARILY_IDLE',
      10
                       'MONGO_HAVE_GPERFTOOLS_SIZE_CLASS_STATS'
      11
                   ]
      12
               )
      13
      diff --git a/src/mongo/util/tcmalloc_server_status_section.cpp b/src/mongo/util/tcmalloc_server_status_section.cpp
      14
      index cc2d672..8365ad0 100644
      15
      --- a/src/mongo/util/tcmalloc_server_status_section.cpp
      16
      +++ b/src/mongo/util/tcmalloc_server_status_section.cpp
      17
      @@ -79,8 +79,12 @@ void threadStateChange() {
      18
           // terrible runaway if we're not careful.
      19
           stdx::lock_guard<stdx::mutex> lk(tcmallocCleanupLock);
      20
       #endif
      21
      +#if MONGO_HAVE_GPERFTOOLS_MARK_THREAD_TEMPORARILY_IDLE
      22
      +    MallocExtension::instance()->MarkThreadTemporarilyIdle();
      23
      +#else
      24
           MallocExtension::instance()->MarkThreadIdle();
      25
           MallocExtension::instance()->MarkThreadBusy();
      26
      +#endif
      27
       }
      28
       
      29
       // Register threadStateChange callback
      30
      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
      31
      index 06138f8..fba567f 100644
      32
      --- a/src/third_party/gperftools-2.2/src/gperftools/malloc_extension.h
      33
      +++ b/src/third_party/gperftools-2.2/src/gperftools/malloc_extension.h
      34
      @@ -242,9 +242,16 @@ class PERFTOOLS_DLL_DECL MallocExtension {
      35
         virtual void MarkThreadBusy();
      36
       
      37
         // Gets the size of this thread's cache in bytes.
      38
      -  // MONGODB ADDITION
      39
      +  // MONGODB ADDITIONS
      40
         virtual size_t GetThreadCacheSize();
      41
       
      42
      +  // Like MarkThreadIdle, but does not destroy the internal data
      43
      +  // structures of the thread cache. When the thread resumes, it wil
      44
      +  // have an empty cache but will not need to pay to reconstruct the
      45
      +  // cache data structures.
      46
      +  virtual void MarkThreadTemporarilyIdle();
      47
      +  // END MONGODB ADDITIONS
      48
      + 
      49
         // Gets the system allocator used by the malloc extension instance. Returns
      50
         // NULL for malloc implementations that do not support pluggable system
      51
         // allocators.
      52
      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
      53
      index 72a0a7c..5c64dae3 100644
      54
      --- a/src/third_party/gperftools-2.2/src/gperftools/malloc_extension_c.h
      55
      +++ b/src/third_party/gperftools-2.2/src/gperftools/malloc_extension_c.h
      56
      @@ -79,6 +79,8 @@ PERFTOOLS_DLL_DECL void MallocExtension_ReleaseToSystem(size_t num_bytes);
      57
       PERFTOOLS_DLL_DECL void MallocExtension_ReleaseFreeMemory(void);
      58
       PERFTOOLS_DLL_DECL size_t MallocExtension_GetEstimatedAllocatedSize(size_t size);
      59
       PERFTOOLS_DLL_DECL size_t MallocExtension_GetAllocatedSize(const void* p);
      60
      +PERFTOOLS_DLL_DECL size_t MallocExtension_GetThreadCacheSize(void);
      61
      +PERFTOOLS_DLL_DECL void MallocExtension_MarkThreadTemporarilyIdle(void);
      62
       
      63
       /*
      64
        * NOTE: These enum values MUST be kept in sync with the version in
      65
      diff --git a/src/third_party/gperftools-2.2/src/malloc_extension.cc b/src/third_party/gperftools-2.2/src/malloc_extension.cc
      66
      index 6fdb043..48872b8 100644
      67
      --- a/src/third_party/gperftools-2.2/src/malloc_extension.cc
      68
      +++ b/src/third_party/gperftools-2.2/src/malloc_extension.cc
      69
      @@ -198,6 +198,10 @@ void MallocExtension::GetFreeListSizes(
      70
         v->clear();
      71
       }
      72
       
      73
      +void MallocExtension::MarkThreadTemporarilyIdle() {
      74
      +  // Default implementation does nothing
      75
      +}
      76
      +
      77
       // The current malloc extension object.
      78
       
      79
       static MallocExtension* current_instance;
      80
      @@ -381,6 +385,8 @@ C_SHIM(ReleaseFreeMemory, void, (void), ());
      81
       C_SHIM(ReleaseToSystem, void, (size_t num_bytes), (num_bytes));
      82
       C_SHIM(GetEstimatedAllocatedSize, size_t, (size_t size), (size));
      83
       C_SHIM(GetAllocatedSize, size_t, (const void* p), (p));
      84
      +C_SHIM(GetThreadCacheSize, size_t, (void), ());
      85
      +C_SHIM(MarkThreadTemporarilyIdle, void, (void), ());
      86
       
      87
       // Can't use the shim here because of the need to translate the enums.
      88
       extern "C"
      89
      diff --git a/src/third_party/gperftools-2.2/src/tcmalloc.cc b/src/third_party/gperftools-2.2/src/tcmalloc.cc
      90
      index 0bc8baa..e7d54c5 100644
      91
      --- a/src/third_party/gperftools-2.2/src/tcmalloc.cc
      92
      +++ b/src/third_party/gperftools-2.2/src/tcmalloc.cc
      93
      @@ -619,6 +619,10 @@ class TCMallocImplementation : public MallocExtension {
      94
           return DumpHeapGrowthStackTraces();
      95
         }
      96
       
      97
      +  virtual void MarkThreadTemporarilyIdle() {
      98
      +    ThreadCache::BecomeTemporarilyIdle();
      99
      +  }
      100
      +
      101
         virtual void Ranges(void* arg, RangeFunction func) {
      102
           IterateOverRanges(arg, func);
      103
         }
      104
      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
      105
      index 827609f..7e59e51 100644
      106
      --- a/src/third_party/gperftools-2.2/src/tests/markidle_unittest.cc
      107
      +++ b/src/third_party/gperftools-2.2/src/tests/markidle_unittest.cc
      108
      @@ -98,11 +98,28 @@ static void TestIdleUsage() {
      109
         VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
      110
       }
      111
       
      112
      +static void TestTemporarilyIdleUsage() {
      113
      +  const size_t original = MallocExtension::instance()->GetThreadCacheSize();
      114
      +
      115
      +  TestAllocation();
      116
      +  const size_t post_allocation = MallocExtension::instance()->GetThreadCacheSize();
      117
      +  CHECK_GT(post_allocation, original);
      118
      +
      119
      +  MallocExtension::instance()->MarkThreadIdle();
      120
      +  const size_t post_idle = MallocExtension::instance()->GetThreadCacheSize();
      121
      +  CHECK_EQ(post_idle, 0);
      122
      +
      123
      +  // Log after testing because logging can allocate heap memory.
      124
      +  VLOG(0, "Original usage: %" PRIuS "\n", original);
      125
      +  VLOG(0, "Post allocation: %" PRIuS "\n", post_allocation);
      126
      +  VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
      127
      +}
      128
      +
      129
       int main(int argc, char** argv) {
      130
         RunThread(&TestIdleUsage);
      131
         RunThread(&TestAllocation);
      132
         RunThread(&MultipleIdleCalls);
      133
      -  RunThread(&MultipleIdleNonIdlePhases);
      134
      +  RunThread(&TestTemporarilyIdleUsage);
      135
       
      136
         printf("PASS\n");
      137
         return 0;
      138
      diff --git a/src/third_party/gperftools-2.2/src/thread_cache.cc b/src/third_party/gperftools-2.2/src/thread_cache.cc
      139
      index b98fbee..7a8b8c0 100644
      140
      --- a/src/third_party/gperftools-2.2/src/thread_cache.cc
      141
      +++ b/src/third_party/gperftools-2.2/src/thread_cache.cc
      142
      @@ -437,6 +437,17 @@ void ThreadCache::BecomeIdle() {
      143
         DeleteCache(heap);
      144
       }
      145
       
      146
      +void ThreadCache::BecomeTemporarilyIdle() {
      147
      +  ThreadCache* heap = GetCacheIfPresent();
      148
      +  if (heap) {
      149
      +    heap->Cleanup();
      150
      +    /* init state of free lists */
      151
      +    for (size_t cl = 0; cl < kNumClasses; ++cl) {
      152
      +      heap->list_[cl].Init();
      153
      +    }
      154
      +  }
      155
      +}
      156
      +
      157
       void ThreadCache::DestroyThreadCache(void* ptr) {
      158
         // Note that "ptr" cannot be NULL since pthread promises not
      159
         // to invoke the destructor on NULL values, but for safety,
      160
      diff --git a/src/third_party/gperftools-2.2/src/thread_cache.h b/src/third_party/gperftools-2.2/src/thread_cache.h
      161
      index 5f0dc12..7d5c2dc 100644
      162
      --- a/src/third_party/gperftools-2.2/src/thread_cache.h
      163
      +++ b/src/third_party/gperftools-2.2/src/thread_cache.h
      164
      @@ -116,6 +116,7 @@ class ThreadCache {
      165
         static ThreadCache* GetCacheWhichMustBePresent();
      166
         static ThreadCache* CreateCacheIfNecessary();
      167
         static void         BecomeIdle();
      168
      +  static void         BecomeTemporarilyIdle();
      169
         static size_t       MinSizeForSlowPath();
      170
         static void         SetMinSizeForSlowPath(size_t size);
      171
       
      

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                Created:
                Updated:
                Resolved: