| Index: third_party/tcmalloc/chromium/src/thread_cache.cc
|
| ===================================================================
|
| --- third_party/tcmalloc/chromium/src/thread_cache.cc (revision 126022)
|
| +++ third_party/tcmalloc/chromium/src/thread_cache.cc (working copy)
|
| @@ -32,7 +32,6 @@
|
|
|
| #include <config.h>
|
| #include "thread_cache.h"
|
| -#include <errno.h>
|
| #include <string.h> // for memcpy
|
| #include <algorithm> // for max, min
|
| #include "base/commandlineflags.h" // for SpinLockHolder
|
| @@ -47,9 +46,8 @@
|
| EnvToInt64("TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES",
|
| kDefaultOverallThreadCacheSize),
|
| "Bound on the total amount of bytes allocated to "
|
| - "thread caches. This bound is not strict, so it is possible "
|
| - "for the cache to go over this bound in certain circumstances. "
|
| - "Maximum value of this flag is capped to 1 GB.");
|
| + "thread caches. This bound is not strict, so it is possible "
|
| + "for the cache to go over this bound in certain circumstances. ");
|
|
|
| namespace tcmalloc {
|
|
|
| @@ -74,21 +72,16 @@
|
|
|
| #if defined(HAVE_TLS)
|
| bool kernel_supports_tls = false; // be conservative
|
| -# if defined(_WIN32) // windows has supported TLS since winnt, I think.
|
| +# if !HAVE_DECL_UNAME // if too old for uname, probably too old for TLS
|
| void CheckIfKernelSupportsTLS() {
|
| - kernel_supports_tls = true;
|
| - }
|
| -# elif !HAVE_DECL_UNAME // if too old for uname, probably too old for TLS
|
| - void CheckIfKernelSupportsTLS() {
|
| kernel_supports_tls = false;
|
| }
|
| # else
|
| # include <sys/utsname.h> // DECL_UNAME checked for <sys/utsname.h> too
|
| void CheckIfKernelSupportsTLS() {
|
| struct utsname buf;
|
| - if (uname(&buf) < 0) { // should be impossible
|
| - Log(kLog, __FILE__, __LINE__,
|
| - "uname failed assuming no TLS support (errno)", errno);
|
| + if (uname(&buf) != 0) { // should be impossible
|
| + MESSAGE("uname failed assuming no TLS support (errno=%d)\n", errno);
|
| kernel_supports_tls = false;
|
| } else if (strcasecmp(buf.sysname, "linux") == 0) {
|
| // The linux case: the first kernel to support TLS was 2.6.0
|
| @@ -100,10 +93,6 @@
|
| kernel_supports_tls = false;
|
| else
|
| kernel_supports_tls = true;
|
| - } else if (strcasecmp(buf.sysname, "CYGWIN_NT-6.1-WOW64") == 0) {
|
| - // In my testing, this version of cygwin, at least, would hang
|
| - // when using TLS.
|
| - kernel_supports_tls = false;
|
| } else { // some other kernel, we'll be optimisitic
|
| kernel_supports_tls = true;
|
| }
|
| @@ -270,6 +259,10 @@
|
| }
|
|
|
| IncreaseCacheLimit();
|
| +
|
| +// int64 finish = CycleClock::Now();
|
| +// CycleTimer ct;
|
| +// MESSAGE("GC: %.0f ns\n", ct.CyclesToUsec(finish-start)*1000.0);
|
| }
|
|
|
| void ThreadCache::IncreaseCacheLimit() {
|
| @@ -329,18 +322,6 @@
|
| ASSERT(!tsd_inited_);
|
| perftools_pthread_key_create(&heap_key_, DestroyThreadCache);
|
| tsd_inited_ = true;
|
| -
|
| -#ifdef PTHREADS_CRASHES_IF_RUN_TOO_EARLY
|
| - // We may have used a fake pthread_t for the main thread. Fix it.
|
| - pthread_t zero;
|
| - memset(&zero, 0, sizeof(zero));
|
| - SpinLockHolder h(Static::pageheap_lock());
|
| - for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
|
| - if (h->tid_ == zero) {
|
| - h->tid_ = pthread_self();
|
| - }
|
| - }
|
| -#endif
|
| }
|
|
|
| ThreadCache* ThreadCache::CreateCacheIfNecessary() {
|
| @@ -348,23 +329,17 @@
|
| ThreadCache* heap = NULL;
|
| {
|
| SpinLockHolder h(Static::pageheap_lock());
|
| - // On some old glibc's, and on freebsd's libc (as of freebsd 8.1),
|
| - // calling pthread routines (even pthread_self) too early could
|
| - // cause a segfault. Since we can call pthreads quite early, we
|
| - // have to protect against that in such situations by making a
|
| - // 'fake' pthread. This is not ideal since it doesn't work well
|
| - // when linking tcmalloc statically with apps that create threads
|
| - // before main, so we only do it if we have to.
|
| -#ifdef PTHREADS_CRASHES_IF_RUN_TOO_EARLY
|
| - pthread_t me;
|
| - if (!tsd_inited_) {
|
| - memset(&me, 0, sizeof(me));
|
| - } else {
|
| - me = pthread_self();
|
| - }
|
| -#else
|
| + // On very old libc's, this call may crash if it happens too
|
| + // early. No libc using NPTL should be affected. If there
|
| + // is a crash here, we could use code (on linux, at least)
|
| + // to detect NPTL vs LinuxThreads:
|
| + // http://www.redhat.com/archives/phil-list/2003-April/msg00038.html
|
| + // If we detect not-NPTL, we could execute the old code from
|
| + // http://google-perftools.googlecode.com/svn/tags/google-perftools-1.7/src/thread_cache.cc
|
| + // that avoids calling pthread_self too early. The problem with
|
| + // that code is it caused a race condition when tcmalloc is linked
|
| + // in statically and other libraries spawn threads before main.
|
| const pthread_t me = pthread_self();
|
| -#endif
|
|
|
| // This may be a recursive malloc call from pthread_setspecific()
|
| // In that case, the heap for this thread has already been created
|
| @@ -487,8 +462,32 @@
|
| }
|
| unclaimed_cache_space_ = overall_thread_cache_size_ - claimed;
|
| per_thread_cache_size_ = space;
|
| + // TCMalloc_MESSAGE(__FILE__, __LINE__, "Threads %d => cache size %8d\n", n, int(space));
|
| }
|
|
|
| +void ThreadCache::Print(TCMalloc_Printer* out) const {
|
| + for (int cl = 0; cl < kNumClasses; ++cl) {
|
| + out->printf(" %5" PRIuS " : %4" PRIuS " len; %4d lo; %4"PRIuS
|
| + " max; %4"PRIuS" overages;\n",
|
| + Static::sizemap()->ByteSizeForClass(cl),
|
| + list_[cl].length(),
|
| + list_[cl].lowwatermark(),
|
| + list_[cl].max_length(),
|
| + list_[cl].length_overages());
|
| + }
|
| +}
|
| +
|
| +void ThreadCache::PrintThreads(TCMalloc_Printer* out) {
|
| + size_t actual_limit = 0;
|
| + for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
|
| + h->Print(out);
|
| + actual_limit += h->max_size_;
|
| + }
|
| + out->printf("ThreadCache overall: %"PRIuS ", unclaimed: %"PRIuS
|
| + ", actual: %"PRIuS"\n",
|
| + overall_thread_cache_size_, unclaimed_cache_space_, actual_limit);
|
| +}
|
| +
|
| void ThreadCache::GetThreadStats(uint64_t* total_bytes, uint64_t* class_count) {
|
| for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {
|
| *total_bytes += h->Size();
|
|
|