You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by zu...@apache.org on 2017/01/29 02:15:16 UTC

[06/53] [partial] incubator-quickstep git commit: Make the third party directory leaner.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/spinlock.cc
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/spinlock.cc b/third_party/gperftools/src/base/spinlock.cc
deleted file mode 100644
index 2021fec..0000000
--- a/third_party/gperftools/src/base/spinlock.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google 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:
- * 
- *     * 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 Google Inc. 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.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-#include <config.h>
-#include "base/spinlock.h"
-#include "base/synchronization_profiling.h"
-#include "base/spinlock_internal.h"
-#include "base/cycleclock.h"
-#include "base/sysinfo.h"   /* for NumCPUs() */
-
-// NOTE on the Lock-state values:
-//
-//   kSpinLockFree represents the unlocked state
-//   kSpinLockHeld represents the locked state with no waiters
-//
-// Values greater than kSpinLockHeld represent the locked state with waiters,
-// where the value is the time the current lock holder had to
-// wait before obtaining the lock.  The kSpinLockSleeper state is a special
-// "locked with waiters" state that indicates that a sleeper needs to
-// be woken, but the thread that just released the lock didn't wait.
-
-static int adaptive_spin_count = 0;
-
-const base::LinkerInitialized SpinLock::LINKER_INITIALIZED =
-    base::LINKER_INITIALIZED;
-
-namespace {
-struct SpinLock_InitHelper {
-  SpinLock_InitHelper() {
-    // On multi-cpu machines, spin for longer before yielding
-    // the processor or sleeping.  Reduces idle time significantly.
-    if (NumCPUs() > 1) {
-      adaptive_spin_count = 1000;
-    }
-  }
-};
-
-// Hook into global constructor execution:
-// We do not do adaptive spinning before that,
-// but nothing lock-intensive should be going on at that time.
-static SpinLock_InitHelper init_helper;
-
-}  // unnamed namespace
-
-// Monitor the lock to see if its value changes within some time period
-// (adaptive_spin_count loop iterations).  A timestamp indicating
-// when the thread initially started waiting for the lock is passed in via
-// the initial_wait_timestamp value.  The total wait time in cycles for the
-// lock is returned in the wait_cycles parameter.  The last value read
-// from the lock is returned from the method.
-Atomic32 SpinLock::SpinLoop(int64 initial_wait_timestamp,
-                            Atomic32* wait_cycles) {
-  int c = adaptive_spin_count;
-  while (base::subtle::NoBarrier_Load(&lockword_) != kSpinLockFree && --c > 0) {
-  }
-  Atomic32 spin_loop_wait_cycles = CalculateWaitCycles(initial_wait_timestamp);
-  Atomic32 lock_value =
-      base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                           spin_loop_wait_cycles);
-  *wait_cycles = spin_loop_wait_cycles;
-  return lock_value;
-}
-
-void SpinLock::SlowLock() {
-  // The lock was not obtained initially, so this thread needs to wait for
-  // it.  Record the current timestamp in the local variable wait_start_time
-  // so the total wait time can be stored in the lockword once this thread
-  // obtains the lock.
-  int64 wait_start_time = CycleClock::Now();
-  Atomic32 wait_cycles;
-  Atomic32 lock_value = SpinLoop(wait_start_time, &wait_cycles);
-
-  int lock_wait_call_count = 0;
-  while (lock_value != kSpinLockFree) {
-    // If the lock is currently held, but not marked as having a sleeper, mark
-    // it as having a sleeper.
-    if (lock_value == kSpinLockHeld) {
-      // Here, just "mark" that the thread is going to sleep.  Don't store the
-      // lock wait time in the lock as that will cause the current lock
-      // owner to think it experienced contention.
-      lock_value = base::subtle::Acquire_CompareAndSwap(&lockword_,
-                                                        kSpinLockHeld,
-                                                        kSpinLockSleeper);
-      if (lock_value == kSpinLockHeld) {
-        // Successfully transitioned to kSpinLockSleeper.  Pass
-        // kSpinLockSleeper to the SpinLockWait routine to properly indicate
-        // the last lock_value observed.
-        lock_value = kSpinLockSleeper;
-      } else if (lock_value == kSpinLockFree) {
-        // Lock is free again, so try and acquire it before sleeping.  The
-        // new lock state will be the number of cycles this thread waited if
-        // this thread obtains the lock.
-        lock_value = base::subtle::Acquire_CompareAndSwap(&lockword_,
-                                                          kSpinLockFree,
-                                                          wait_cycles);
-        continue;  // skip the delay at the end of the loop
-      }
-    }
-
-    // Wait for an OS specific delay.
-    base::internal::SpinLockDelay(&lockword_, lock_value,
-                                  ++lock_wait_call_count);
-    // Spin again after returning from the wait routine to give this thread
-    // some chance of obtaining the lock.
-    lock_value = SpinLoop(wait_start_time, &wait_cycles);
-  }
-}
-
-// The wait time for contentionz lock profiling must fit into 32 bits.
-// However, the lower 32-bits of the cycle counter wrap around too quickly
-// with high frequency processors, so a right-shift by 7 is performed to
-// quickly divide the cycles by 128.  Using these 32 bits, reduces the
-// granularity of time measurement to 128 cycles, and loses track
-// of wait time for waits greater than 109 seconds on a 5 GHz machine
-// [(2^32 cycles/5 Ghz)*128 = 109.95 seconds]. Waits this long should be
-// very rare and the reduced granularity should not be an issue given
-// processors in the Google fleet operate at a minimum of one billion
-// cycles/sec.
-enum { PROFILE_TIMESTAMP_SHIFT = 7 };
-
-void SpinLock::SlowUnlock(uint64 wait_cycles) {
-  base::internal::SpinLockWake(&lockword_, false);  // wake waiter if necessary
-
-  // Collect contentionz profile info, expanding the wait_cycles back out to
-  // the full value.  If wait_cycles is <= kSpinLockSleeper, then no wait
-  // was actually performed, so don't record the wait time.  Note, that the
-  // CalculateWaitCycles method adds in kSpinLockSleeper cycles
-  // unconditionally to guarantee the wait time is not kSpinLockFree or
-  // kSpinLockHeld.  The adding in of these small number of cycles may
-  // overestimate the contention by a slight amount 50% of the time.  However,
-  // if this code tried to correct for that addition by subtracting out the
-  // kSpinLockSleeper amount that would underestimate the contention slightly
-  // 50% of the time.  Both ways get the wrong answer, so the code
-  // overestimates to be more conservative. Overestimating also makes the code
-  // a little simpler.
-  //
-  if (wait_cycles > kSpinLockSleeper) {
-    base::SubmitSpinLockProfileData(this,
-                                    wait_cycles << PROFILE_TIMESTAMP_SHIFT);
-  }
-}
-
-inline int32 SpinLock::CalculateWaitCycles(int64 wait_start_time) {
-  int32 wait_cycles = ((CycleClock::Now() - wait_start_time) >>
-                       PROFILE_TIMESTAMP_SHIFT);
-  // The number of cycles waiting for the lock is used as both the
-  // wait_cycles and lock value, so it can't be kSpinLockFree or
-  // kSpinLockHeld.  Make sure the value returned is at least
-  // kSpinLockSleeper.
-  wait_cycles |= kSpinLockSleeper;
-  return wait_cycles;
-}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/spinlock.h
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/spinlock.h b/third_party/gperftools/src/base/spinlock.h
deleted file mode 100644
index 033a75e..0000000
--- a/third_party/gperftools/src/base/spinlock.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google 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:
- * 
- *     * 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 Google Inc. 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.
- *
- * ---
- * Author: Sanjay Ghemawat
- */
-
-// SpinLock is async signal safe.
-// If used within a signal handler, all lock holders
-// should block the signal even outside the signal handler.
-
-#ifndef BASE_SPINLOCK_H_
-#define BASE_SPINLOCK_H_
-
-#include <config.h>
-#include "base/atomicops.h"
-#include "base/basictypes.h"
-#include "base/dynamic_annotations.h"
-#include "base/thread_annotations.h"
-
-class LOCKABLE SpinLock {
- public:
-  SpinLock() : lockword_(kSpinLockFree) { }
-
-  // Special constructor for use with static SpinLock objects.  E.g.,
-  //
-  //    static SpinLock lock(base::LINKER_INITIALIZED);
-  //
-  // When intialized using this constructor, we depend on the fact
-  // that the linker has already initialized the memory appropriately.
-  // A SpinLock constructed like this can be freely used from global
-  // initializers without worrying about the order in which global
-  // initializers run.
-  explicit SpinLock(base::LinkerInitialized /*x*/) {
-    // Does nothing; lockword_ is already initialized
-  }
-
-  // Acquire this SpinLock.
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline void Lock() /*EXCLUSIVE_LOCK_FUNCTION()*/ {
-    if (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                             kSpinLockHeld) != kSpinLockFree) {
-      SlowLock();
-    }
-    ANNOTATE_RWLOCK_ACQUIRED(this, 1);
-  }
-
-  // Try to acquire this SpinLock without blocking and return true if the
-  // acquisition was successful.  If the lock was not acquired, false is
-  // returned.  If this SpinLock is free at the time of the call, TryLock
-  // will return true with high probability.
-  inline bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) {
-    bool res =
-        (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
-                                              kSpinLockHeld) == kSpinLockFree);
-    if (res) {
-      ANNOTATE_RWLOCK_ACQUIRED(this, 1);
-    }
-    return res;
-  }
-
-  // Release this SpinLock, which must be held by the calling thread.
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline void Unlock() /*UNLOCK_FUNCTION()*/ {
-    ANNOTATE_RWLOCK_RELEASED(this, 1);
-    uint64 wait_cycles = static_cast<uint64>(
-        base::subtle::Release_AtomicExchange(&lockword_, kSpinLockFree));
-    if (wait_cycles != kSpinLockHeld) {
-      // Collect contentionz profile info, and speed the wakeup of any waiter.
-      // The wait_cycles value indicates how long this thread spent waiting
-      // for the lock.
-      SlowUnlock(wait_cycles);
-    }
-  }
-
-  // Determine if the lock is held.  When the lock is held by the invoking
-  // thread, true will always be returned. Intended to be used as
-  // CHECK(lock.IsHeld()).
-  inline bool IsHeld() const {
-    return base::subtle::NoBarrier_Load(&lockword_) != kSpinLockFree;
-  }
-
-  static const base::LinkerInitialized LINKER_INITIALIZED;  // backwards compat
- private:
-  enum { kSpinLockFree = 0 };
-  enum { kSpinLockHeld = 1 };
-  enum { kSpinLockSleeper = 2 };
-
-  volatile Atomic32 lockword_;
-
-  void SlowLock();
-  void SlowUnlock(uint64 wait_cycles);
-  Atomic32 SpinLoop(int64 initial_wait_timestamp, Atomic32* wait_cycles);
-  inline int32 CalculateWaitCycles(int64 wait_start_time);
-
-  DISALLOW_COPY_AND_ASSIGN(SpinLock);
-};
-
-// Corresponding locker object that arranges to acquire a spinlock for
-// the duration of a C++ scope.
-class SCOPED_LOCKABLE SpinLockHolder {
- private:
-  SpinLock* lock_;
- public:
-  inline explicit SpinLockHolder(SpinLock* l) EXCLUSIVE_LOCK_FUNCTION(l)
-      : lock_(l) {
-    l->Lock();
-  }
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline ~SpinLockHolder() /*UNLOCK_FUNCTION()*/ { lock_->Unlock(); }
-};
-// Catch bug where variable name is omitted, e.g. SpinLockHolder (&lock);
-#define SpinLockHolder(x) COMPILE_ASSERT(0, spin_lock_decl_missing_var_name)
-
-
-#endif  // BASE_SPINLOCK_H_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/spinlock_internal.cc
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/spinlock_internal.cc b/third_party/gperftools/src/base/spinlock_internal.cc
deleted file mode 100644
index e090f9b..0000000
--- a/third_party/gperftools/src/base/spinlock_internal.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2010, Google 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:
- *
- *     * 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 Google Inc. 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.
- */
-
-// The OS-specific header included below must provide two calls:
-// base::internal::SpinLockDelay() and base::internal::SpinLockWake().
-// See spinlock_internal.h for the spec of SpinLockWake().
-
-// void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop)
-// SpinLockDelay() generates an apprproate spin delay on iteration "loop" of a
-// spin loop on location *w, whose previously observed value was "value".
-// SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick,
-// or may wait for a delay that can be truncated by a call to SpinlockWake(w).
-// In all cases, it must return in bounded time even if SpinlockWake() is not
-// called.
-
-#include "base/spinlock_internal.h"
-
-// forward declaration for use by spinlock_*-inl.h
-namespace base { namespace internal { static int SuggestedDelayNS(int loop); }}
-
-#if defined(_WIN32)
-#include "base/spinlock_win32-inl.h"
-#elif defined(__linux__)
-#include "base/spinlock_linux-inl.h"
-#else
-#include "base/spinlock_posix-inl.h"
-#endif
-
-namespace base {
-namespace internal {
-
-// See spinlock_internal.h for spec.
-int32 SpinLockWait(volatile Atomic32 *w, int n,
-                   const SpinLockWaitTransition trans[]) {
-  int32 v;
-  bool done = false;
-  for (int loop = 0; !done; loop++) {
-    v = base::subtle::Acquire_Load(w);
-    int i;
-    for (i = 0; i != n && v != trans[i].from; i++) {
-    }
-    if (i == n) {
-      SpinLockDelay(w, v, loop);     // no matching transition
-    } else if (trans[i].to == v ||   // null transition
-               base::subtle::Acquire_CompareAndSwap(w, v, trans[i].to) == v) {
-      done = trans[i].done;
-    }
-  }
-  return v;
-}
-
-// Return a suggested delay in nanoseconds for iteration number "loop"
-static int SuggestedDelayNS(int loop) {
-  // Weak pseudo-random number generator to get some spread between threads
-  // when many are spinning.
-#ifdef BASE_HAS_ATOMIC64
-  static base::subtle::Atomic64 rand;
-  uint64 r = base::subtle::NoBarrier_Load(&rand);
-  r = 0x5deece66dLL * r + 0xb;   // numbers from nrand48()
-  base::subtle::NoBarrier_Store(&rand, r);
-
-  r <<= 16;   // 48-bit random number now in top 48-bits.
-  if (loop < 0 || loop > 32) {   // limit loop to 0..32
-    loop = 32;
-  }
-  // loop>>3 cannot exceed 4 because loop cannot exceed 32.
-  // Select top 20..24 bits of lower 48 bits,
-  // giving approximately 0ms to 16ms.
-  // Mean is exponential in loop for first 32 iterations, then 8ms.
-  // The futex path multiplies this by 16, since we expect explicit wakeups
-  // almost always on that path.
-  return r >> (44 - (loop >> 3));
-#else
-  static Atomic32 rand;
-  uint32 r = base::subtle::NoBarrier_Load(&rand);
-  r = 0x343fd * r + 0x269ec3;   // numbers from MSVC++
-  base::subtle::NoBarrier_Store(&rand, r);
-
-  r <<= 1;   // 31-bit random number now in top 31-bits.
-  if (loop < 0 || loop > 32) {   // limit loop to 0..32
-    loop = 32;
-  }
-  // loop>>3 cannot exceed 4 because loop cannot exceed 32.
-  // Select top 20..24 bits of lower 31 bits,
-  // giving approximately 0ms to 16ms.
-  // Mean is exponential in loop for first 32 iterations, then 8ms.
-  // The futex path multiplies this by 16, since we expect explicit wakeups
-  // almost always on that path.
-  return r >> (12 - (loop >> 3));
-#endif
-}
-
-} // namespace internal
-} // namespace base

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/spinlock_internal.h
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/spinlock_internal.h b/third_party/gperftools/src/base/spinlock_internal.h
deleted file mode 100644
index 4d3c17f..0000000
--- a/third_party/gperftools/src/base/spinlock_internal.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2010, Google 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:
- *
- *     * 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 Google Inc. 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.
- *
- * ---
- * This file is an internal part spinlock.cc and once.cc
- * It may not be used directly by code outside of //base.
- */
-
-#ifndef BASE_SPINLOCK_INTERNAL_H_
-#define BASE_SPINLOCK_INTERNAL_H_
-
-#include <config.h>
-#include "base/basictypes.h"
-#include "base/atomicops.h"
-
-namespace base {
-namespace internal {
-
-// SpinLockWait() waits until it can perform one of several transitions from
-// "from" to "to".  It returns when it performs a transition where done==true.
-struct SpinLockWaitTransition {
-  int32 from;
-  int32 to;
-  bool done;
-};
-
-// Wait until *w can transition from trans[i].from to trans[i].to for some i
-// satisfying 0<=i<n && trans[i].done, atomically make the transition,
-// then return the old value of *w.   Make any other atomic tranistions
-// where !trans[i].done, but continue waiting.
-int32 SpinLockWait(volatile Atomic32 *w, int n,
-                   const SpinLockWaitTransition trans[]);
-void SpinLockWake(volatile Atomic32 *w, bool all);
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop);
-
-} // namespace internal
-} // namespace base
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/spinlock_linux-inl.h
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/spinlock_linux-inl.h b/third_party/gperftools/src/base/spinlock_linux-inl.h
deleted file mode 100644
index 86d4d04..0000000
--- a/third_party/gperftools/src/base/spinlock_linux-inl.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google 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:
- * 
- *     * 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 Google Inc. 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.
- *
- * ---
- * This file is a Linux-specific part of spinlock_internal.cc
- */
-
-#include <errno.h>
-#include <sched.h>
-#include <time.h>
-#include <limits.h>
-#include "base/linux_syscall_support.h"
-
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-#define FUTEX_PRIVATE_FLAG 128
-
-static bool have_futex;
-static int futex_private_flag = FUTEX_PRIVATE_FLAG;
-
-namespace {
-static struct InitModule {
-  InitModule() {
-    int x = 0;
-    // futexes are ints, so we can use them only when
-    // that's the same size as the lockword_ in SpinLock.
-#ifdef __arm__
-    // ARM linux doesn't support sys_futex1(void*, int, int, struct timespec*);
-    have_futex = 0;
-#else
-    have_futex = (sizeof (Atomic32) == sizeof (int) &&
-                  sys_futex(&x, FUTEX_WAKE, 1, 0) >= 0);
-#endif
-    if (have_futex &&
-        sys_futex(&x, FUTEX_WAKE | futex_private_flag, 1, 0) < 0) {
-      futex_private_flag = 0;
-    }
-  }
-} init_module;
-
-}  // anonymous namespace
-
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  if (loop != 0) {
-    int save_errno = errno;
-    struct timespec tm;
-    tm.tv_sec = 0;
-    if (have_futex) {
-      tm.tv_nsec = base::internal::SuggestedDelayNS(loop);
-    } else {
-      tm.tv_nsec = 2000001;   // above 2ms so linux 2.4 doesn't spin
-    }
-    if (have_futex) {
-      tm.tv_nsec *= 16;  // increase the delay; we expect explicit wakeups
-      sys_futex(reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
-                FUTEX_WAIT | futex_private_flag,
-                value, reinterpret_cast<struct kernel_timespec *>(&tm));
-    } else {
-      nanosleep(&tm, NULL);
-    }
-    errno = save_errno;
-  }
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-  if (have_futex) {
-    sys_futex(reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
-              FUTEX_WAKE | futex_private_flag, all? INT_MAX : 1, 0);
-  }
-}
-
-} // namespace internal
-} // namespace base

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/spinlock_posix-inl.h
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/spinlock_posix-inl.h b/third_party/gperftools/src/base/spinlock_posix-inl.h
deleted file mode 100644
index e73a30f..0000000
--- a/third_party/gperftools/src/base/spinlock_posix-inl.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google 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:
- * 
- *     * 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 Google Inc. 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.
- *
- * ---
- * This file is a Posix-specific part of spinlock_internal.cc
- */
-
-#include <config.h>
-#include <errno.h>
-#ifdef HAVE_SCHED_H
-#include <sched.h>      /* For sched_yield() */
-#endif
-#include <time.h>       /* For nanosleep() */
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  int save_errno = errno;
-  if (loop == 0) {
-  } else if (loop == 1) {
-    sched_yield();
-  } else {
-    struct timespec tm;
-    tm.tv_sec = 0;
-    tm.tv_nsec = base::internal::SuggestedDelayNS(loop);
-    nanosleep(&tm, NULL);
-  }
-  errno = save_errno;
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-}
-
-} // namespace internal
-} // namespace base

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/spinlock_win32-inl.h
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/spinlock_win32-inl.h b/third_party/gperftools/src/base/spinlock_win32-inl.h
deleted file mode 100644
index 956b965..0000000
--- a/third_party/gperftools/src/base/spinlock_win32-inl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2009, Google 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:
- * 
- *     * 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 Google Inc. 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.
- *
- * ---
- * This file is a Win32-specific part of spinlock_internal.cc
- */
-
-
-#include <windows.h>
-
-namespace base {
-namespace internal {
-
-void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
-  if (loop == 0) {
-  } else if (loop == 1) {
-    Sleep(0);
-  } else {
-    Sleep(base::internal::SuggestedDelayNS(loop) / 1000000);
-  }
-}
-
-void SpinLockWake(volatile Atomic32 *w, bool all) {
-}
-
-} // namespace internal
-} // namespace base

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/stl_allocator.h
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/stl_allocator.h b/third_party/gperftools/src/base/stl_allocator.h
deleted file mode 100644
index 2345f46..0000000
--- a/third_party/gperftools/src/base/stl_allocator.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2006, Google 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:
- * 
- *     * 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 Google Inc. 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.
- *
- * ---
- * Author: Maxim Lifantsev
- */
-
-
-#ifndef BASE_STL_ALLOCATOR_H_
-#define BASE_STL_ALLOCATOR_H_
-
-#include <config.h>
-
-#include <stddef.h>   // for ptrdiff_t
-#include <limits>
-
-#include "base/logging.h"
-
-// Generic allocator class for STL objects
-// that uses a given type-less allocator Alloc, which must provide:
-//   static void* Alloc::Allocate(size_t size);
-//   static void Alloc::Free(void* ptr, size_t size);
-//
-// STL_Allocator<T, MyAlloc> provides the same thread-safety
-// guarantees as MyAlloc.
-//
-// Usage example:
-//   set<T, less<T>, STL_Allocator<T, MyAlloc> > my_set;
-// CAVEAT: Parts of the code below are probably specific
-//         to the STL version(s) we are using.
-//         The code is simply lifted from what std::allocator<> provides.
-template <typename T, class Alloc>
-class STL_Allocator {
- public:
-  typedef size_t     size_type;
-  typedef ptrdiff_t  difference_type;
-  typedef T*         pointer;
-  typedef const T*   const_pointer;
-  typedef T&         reference;
-  typedef const T&   const_reference;
-  typedef T          value_type;
-
-  template <class T1> struct rebind {
-    typedef STL_Allocator<T1, Alloc> other;
-  };
-
-  STL_Allocator() { }
-  STL_Allocator(const STL_Allocator&) { }
-  template <class T1> STL_Allocator(const STL_Allocator<T1, Alloc>&) { }
-  ~STL_Allocator() { }
-
-  pointer address(reference x) const { return &x; }
-  const_pointer address(const_reference x) const { return &x; }
-
-  pointer allocate(size_type n, const void* = 0) {
-    RAW_DCHECK((n * sizeof(T)) / sizeof(T) == n, "n is too big to allocate");
-    return static_cast<T*>(Alloc::Allocate(n * sizeof(T)));
-  }
-  void deallocate(pointer p, size_type n) { Alloc::Free(p, n * sizeof(T)); }
-
-  size_type max_size() const { return size_t(-1) / sizeof(T); }
-
-  void construct(pointer p, const T& val) { ::new(p) T(val); }
-  void construct(pointer p) { ::new(p) T(); }
-  void destroy(pointer p) { p->~T(); }
-
-  // There's no state, so these allocators are always equal
-  bool operator==(const STL_Allocator&) const { return true; }
-};
-
-#endif  // BASE_STL_ALLOCATOR_H_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/synchronization_profiling.h
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/synchronization_profiling.h b/third_party/gperftools/src/base/synchronization_profiling.h
deleted file mode 100644
index b495034..0000000
--- a/third_party/gperftools/src/base/synchronization_profiling.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-/* Copyright (c) 2010, Google 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:
- *
- *     * 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 Google Inc. 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.
- *
- * ---
- * Author: Chris Ruemmler
- */
-
-#ifndef BASE_AUXILIARY_SYNCHRONIZATION_PROFILING_H_
-#define BASE_AUXILIARY_SYNCHRONIZATION_PROFILING_H_
-
-#include "base/basictypes.h"
-
-namespace base {
-
-// We can do contention-profiling of SpinLocks, but the code is in
-// mutex.cc, which is not always linked in with spinlock.  Hence we
-// provide a weak definition, which are used if mutex.cc isn't linked in.
-
-// Submit the number of cycles the spinlock spent contending.
-ATTRIBUTE_WEAK extern void SubmitSpinLockProfileData(const void *, int64);
-extern void SubmitSpinLockProfileData(const void *contendedlock,
-                                      int64 wait_cycles) {}
-}
-#endif  // BASE_AUXILIARY_SYNCHRONIZATION_PROFILING_H_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/base/sysinfo.cc
----------------------------------------------------------------------
diff --git a/third_party/gperftools/src/base/sysinfo.cc b/third_party/gperftools/src/base/sysinfo.cc
deleted file mode 100644
index cad751b..0000000
--- a/third_party/gperftools/src/base/sysinfo.cc
+++ /dev/null
@@ -1,1153 +0,0 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
-// Copyright (c) 2006, Google 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:
-// 
-//     * 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 Google Inc. 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.
-
-#include <config.h>
-#if (defined(_WIN32) || defined(__MINGW32__)) && !defined(__CYGWIN__) && !defined(__CYGWIN32)
-# define PLATFORM_WINDOWS 1
-#endif
-
-#include <ctype.h>    // for isspace()
-#include <stdlib.h>   // for getenv()
-#include <stdio.h>    // for snprintf(), sscanf()
-#include <string.h>   // for memmove(), memchr(), etc.
-#include <fcntl.h>    // for open()
-#include <errno.h>    // for errno
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>   // for read()
-#endif
-#if defined __MACH__          // Mac OS X, almost certainly
-#include <mach-o/dyld.h>      // for iterating over dll's in ProcMapsIter
-#include <mach-o/loader.h>    // for iterating over dll's in ProcMapsIter
-#include <sys/types.h>
-#include <sys/sysctl.h>       // how we figure out numcpu's on OS X
-#elif defined __FreeBSD__
-#include <sys/sysctl.h>
-#elif defined __sun__         // Solaris
-#include <procfs.h>           // for, e.g., prmap_t
-#elif defined(PLATFORM_WINDOWS)
-#include <process.h>          // for getpid() (actually, _getpid())
-#include <shlwapi.h>          // for SHGetValueA()
-#include <tlhelp32.h>         // for Module32First()
-#endif
-#include "base/sysinfo.h"
-#include "base/commandlineflags.h"
-#include "base/dynamic_annotations.h"   // for RunningOnValgrind
-#include "base/logging.h"
-#include "base/cycleclock.h"
-
-#ifdef PLATFORM_WINDOWS
-#ifdef MODULEENTRY32
-// In a change from the usual W-A pattern, there is no A variant of
-// MODULEENTRY32.  Tlhelp32.h #defines the W variant, but not the A.
-// In unicode mode, tlhelp32.h #defines MODULEENTRY32 to be
-// MODULEENTRY32W.  These #undefs are the only way I see to get back
-// access to the original, ascii struct (and related functions).
-#undef MODULEENTRY32
-#undef Module32First
-#undef Module32Next
-#undef PMODULEENTRY32
-#undef LPMODULEENTRY32
-#endif  /* MODULEENTRY32 */
-// MinGW doesn't seem to define this, perhaps some windowsen don't either.
-#ifndef TH32CS_SNAPMODULE32
-#define TH32CS_SNAPMODULE32  0
-#endif  /* TH32CS_SNAPMODULE32 */
-#endif  /* PLATFORM_WINDOWS */
-
-// Re-run fn until it doesn't cause EINTR.
-#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)
-
-// open/read/close can set errno, which may be illegal at this
-// time, so prefer making the syscalls directly if we can.
-#ifdef HAVE_SYS_SYSCALL_H
-# include <sys/syscall.h>
-#endif
-#ifdef SYS_open   // solaris 11, at least sometimes, only defines SYS_openat
-# define safeopen(filename, mode)  syscall(SYS_open, filename, mode)
-#else
-# define safeopen(filename, mode)  open(filename, mode)
-#endif
-#ifdef SYS_read
-# define saferead(fd, buffer, size)  syscall(SYS_read, fd, buffer, size)
-#else
-# define saferead(fd, buffer, size)  read(fd, buffer, size)
-#endif
-#ifdef SYS_close
-# define safeclose(fd)  syscall(SYS_close, fd)
-#else
-# define safeclose(fd)  close(fd)
-#endif
-
-// ----------------------------------------------------------------------
-// GetenvBeforeMain()
-// GetUniquePathFromEnv()
-//    Some non-trivial getenv-related functions.
-// ----------------------------------------------------------------------
-
-// It's not safe to call getenv() in the malloc hooks, because they
-// might be called extremely early, before libc is done setting up
-// correctly.  In particular, the thread library may not be done
-// setting up errno.  So instead, we use the built-in __environ array
-// if it exists, and otherwise read /proc/self/environ directly, using
-// system calls to read the file, and thus avoid setting errno.
-// /proc/self/environ has a limit of how much data it exports (around
-// 8K), so it's not an ideal solution.
-const char* GetenvBeforeMain(const char* name) {
-#if defined(HAVE___ENVIRON)   // if we have it, it's declared in unistd.h
-  if (__environ) {            // can exist but be NULL, if statically linked
-    const int namelen = strlen(name);
-    for (char** p = __environ; *p; p++) {
-      if (strlen(*p) < namelen) {
-        continue;
-      }
-      if (!memcmp(*p, name, namelen) && (*p)[namelen] == '=')  // it's a match
-        return *p + namelen+1;                                 // point after =
-    }
-    return NULL;
-  }
-#endif
-#if defined(PLATFORM_WINDOWS)
-  // TODO(mbelshe) - repeated calls to this function will overwrite the
-  // contents of the static buffer.
-  static char envvar_buf[1024];  // enough to hold any envvar we care about
-  if (!GetEnvironmentVariableA(name, envvar_buf, sizeof(envvar_buf)-1))
-    return NULL;
-  return envvar_buf;
-#endif
-  // static is ok because this function should only be called before
-  // main(), when we're single-threaded.
-  static char envbuf[16<<10];
-  if (*envbuf == '\0') {    // haven't read the environ yet
-    int fd = safeopen("/proc/self/environ", O_RDONLY);
-    // The -2 below guarantees the last two bytes of the buffer will be \0\0
-    if (fd == -1 ||           // unable to open the file, fall back onto libc
-        saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file
-      RAW_VLOG(1, "Unable to open /proc/self/environ, falling back "
-               "on getenv(\"%s\"), which may not work", name);
-      if (fd != -1) safeclose(fd);
-      return getenv(name);
-    }
-    safeclose(fd);
-  }
-  const int namelen = strlen(name);
-  const char* p = envbuf;
-  while (*p != '\0') {    // will happen at the \0\0 that terminates the buffer
-    // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
-    const char* endp = (char*)memchr(p, '\0', sizeof(envbuf) - (p - envbuf));
-    if (endp == NULL)            // this entry isn't NUL terminated
-      return NULL;
-    else if (!memcmp(p, name, namelen) && p[namelen] == '=')    // it's a match
-      return p + namelen+1;      // point after =
-    p = endp + 1;
-  }
-  return NULL;                   // env var never found
-}
-
-extern "C" {
-  const char* TCMallocGetenvSafe(const char* name) {
-    return GetenvBeforeMain(name);
-  }
-}
-
-// This takes as an argument an environment-variable name (like
-// CPUPROFILE) whose value is supposed to be a file-path, and sets
-// path to that path, and returns true.  If the env var doesn't exist,
-// or is the empty string, leave path unchanged and returns false.
-// The reason this is non-trivial is that this function handles munged
-// pathnames.  Here's why:
-//
-// If we're a child process of the 'main' process, we can't just use
-// getenv("CPUPROFILE") -- the parent process will be using that path.
-// Instead we append our pid to the pathname.  How do we tell if we're a
-// child process?  Ideally we'd set an environment variable that all
-// our children would inherit.  But -- and this is seemingly a bug in
-// gcc -- if you do a setenv() in a shared libarary in a global
-// constructor, the environment setting is lost by the time main() is
-// called.  The only safe thing we can do in such a situation is to
-// modify the existing envvar.  So we do a hack: in the parent, we set
-// the high bit of the 1st char of CPUPROFILE.  In the child, we
-// notice the high bit is set and append the pid().  This works
-// assuming cpuprofile filenames don't normally have the high bit set
-// in their first character!  If that assumption is violated, we'll
-// still get a profile, but one with an unexpected name.
-// TODO(csilvers): set an envvar instead when we can do it reliably.
-bool GetUniquePathFromEnv(const char* env_name, char* path) {
-  char* envval = getenv(env_name);
-  if (envval == NULL || *envval == '\0')
-    return false;
-  if (envval[0] & 128) {                  // high bit is set
-    snprintf(path, PATH_MAX, "%c%s_%u",   // add pid and clear high bit
-             envval[0] & 127, envval+1, (unsigned int)(getpid()));
-  } else {
-    snprintf(path, PATH_MAX, "%s", envval);
-    envval[0] |= 128;                     // set high bit for kids to see
-  }
-  return true;
-}
-
-// ----------------------------------------------------------------------
-// CyclesPerSecond()
-// NumCPUs()
-//    It's important this not call malloc! -- they may be called at
-//    global-construct time, before we've set up all our proper malloc
-//    hooks and such.
-// ----------------------------------------------------------------------
-
-static double cpuinfo_cycles_per_second = 1.0;  // 0.0 might be dangerous
-static int cpuinfo_num_cpus = 1;  // Conservative guess
-
-void SleepForMilliseconds(int milliseconds) {
-#ifdef PLATFORM_WINDOWS
-  _sleep(milliseconds);   // Windows's _sleep takes milliseconds argument
-#else
-  // Sleep for a few milliseconds
-  struct timespec sleep_time;
-  sleep_time.tv_sec = milliseconds / 1000;
-  sleep_time.tv_nsec = (milliseconds % 1000) * 1000000;
-  while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR)
-    ;  // Ignore signals and wait for the full interval to elapse.
-#endif
-}
-
-// Helper function estimates cycles/sec by observing cycles elapsed during
-// sleep(). Using small sleep time decreases accuracy significantly.
-static int64 EstimateCyclesPerSecond(const int estimate_time_ms) {
-  assert(estimate_time_ms > 0);
-  if (estimate_time_ms <= 0)
-    return 1;
-  double multiplier = 1000.0 / (double)estimate_time_ms;  // scale by this much
-
-  const int64 start_ticks = CycleClock::Now();
-  SleepForMilliseconds(estimate_time_ms);
-  const int64 guess = int64(multiplier * (CycleClock::Now() - start_ticks));
-  return guess;
-}
-
-// ReadIntFromFile is only called on linux and cygwin platforms.
-#if defined(__linux__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-// Helper function for reading an int from a file. Returns true if successful
-// and the memory location pointed to by value is set to the value read.
-static bool ReadIntFromFile(const char *file, int *value) {
-  bool ret = false;
-  int fd = open(file, O_RDONLY);
-  if (fd != -1) {
-    char line[1024];
-    char* err;
-    memset(line, '\0', sizeof(line));
-    read(fd, line, sizeof(line) - 1);
-    const int temp_value = strtol(line, &err, 10);
-    if (line[0] != '\0' && (*err == '\n' || *err == '\0')) {
-      *value = temp_value;
-      ret = true;
-    }
-    close(fd);
-  }
-  return ret;
-}
-#endif
-
-// WARNING: logging calls back to InitializeSystemInfo() so it must
-// not invoke any logging code.  Also, InitializeSystemInfo() can be
-// called before main() -- in fact it *must* be since already_called
-// isn't protected -- before malloc hooks are properly set up, so
-// we make an effort not to call any routines which might allocate
-// memory.
-
-static void InitializeSystemInfo() {
-  static bool already_called = false;   // safe if we run before threads
-  if (already_called)  return;
-  already_called = true;
-
-  bool saw_mhz = false;
-
-  if (RunningOnValgrind()) {
-    // Valgrind may slow the progress of time artificially (--scale-time=N
-    // option). We thus can't rely on CPU Mhz info stored in /sys or /proc
-    // files. Thus, actually measure the cps.
-    cpuinfo_cycles_per_second = EstimateCyclesPerSecond(100);
-    saw_mhz = true;
-  }
-
-#if defined(__linux__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-  char line[1024];
-  char* err;
-  int freq;
-
-  // If the kernel is exporting the tsc frequency use that. There are issues
-  // where cpuinfo_max_freq cannot be relied on because the BIOS may be
-  // exporintg an invalid p-state (on x86) or p-states may be used to put the
-  // processor in a new mode (turbo mode). Essentially, those frequencies
-  // cannot always be relied upon. The same reasons apply to /proc/cpuinfo as
-  // well.
-  if (!saw_mhz &&
-      ReadIntFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", &freq)) {
-      // The value is in kHz (as the file name suggests).  For example, on a
-      // 2GHz warpstation, the file contains the value "2000000".
-      cpuinfo_cycles_per_second = freq * 1000.0;
-      saw_mhz = true;
-  }
-
-  // If CPU scaling is in effect, we want to use the *maximum* frequency,
-  // not whatever CPU speed some random processor happens to be using now.
-  if (!saw_mhz &&
-      ReadIntFromFile("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq",
-                      &freq)) {
-    // The value is in kHz.  For example, on a 2GHz machine, the file
-    // contains the value "2000000".
-    cpuinfo_cycles_per_second = freq * 1000.0;
-    saw_mhz = true;
-  }
-
-  // Read /proc/cpuinfo for other values, and if there is no cpuinfo_max_freq.
-  const char* pname = "/proc/cpuinfo";
-  int fd = open(pname, O_RDONLY);
-  if (fd == -1) {
-    perror(pname);
-    if (!saw_mhz) {
-      cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000);
-    }
-    return;          // TODO: use generic tester instead?
-  }
-
-  double bogo_clock = 1.0;
-  bool saw_bogo = false;
-  int num_cpus = 0;
-  line[0] = line[1] = '\0';
-  int chars_read = 0;
-  do {   // we'll exit when the last read didn't read anything
-    // Move the next line to the beginning of the buffer
-    const int oldlinelen = strlen(line);
-    if (sizeof(line) == oldlinelen + 1)    // oldlinelen took up entire line
-      line[0] = '\0';
-    else                                   // still other lines left to save
-      memmove(line, line + oldlinelen+1, sizeof(line) - (oldlinelen+1));
-    // Terminate the new line, reading more if we can't find the newline
-    char* newline = strchr(line, '\n');
-    if (newline == NULL) {
-      const int linelen = strlen(line);
-      const int bytes_to_read = sizeof(line)-1 - linelen;
-      assert(bytes_to_read > 0);  // because the memmove recovered >=1 bytes
-      chars_read = read(fd, line + linelen, bytes_to_read);
-      line[linelen + chars_read] = '\0';
-      newline = strchr(line, '\n');
-    }
-    if (newline != NULL)
-      *newline = '\0';
-
-#if defined(__powerpc__) || defined(__ppc__)
-    // PowerPC cpus report the frequency in "clock" line
-    if (strncasecmp(line, "clock", sizeof("clock")-1) == 0) {
-      const char* freqstr = strchr(line, ':');
-      if (freqstr) {
-	// PowerPC frequencies are only reported as MHz (check 'show_cpuinfo'
-	// function at arch/powerpc/kernel/setup-common.c)
-	char *endp = strstr(line, "MHz");
-	if (endp) {
-	  *endp = 0;
-	  cpuinfo_cycles_per_second = strtod(freqstr+1, &err) * 1000000.0;
-          if (freqstr[1] != '\0' && *err == '\0' && cpuinfo_cycles_per_second > 0)
-            saw_mhz = true;
-	}
-      }
-#else
-    // When parsing the "cpu MHz" and "bogomips" (fallback) entries, we only
-    // accept postive values. Some environments (virtual machines) report zero,
-    // which would cause infinite looping in WallTime_Init.
-    if (!saw_mhz && strncasecmp(line, "cpu MHz", sizeof("cpu MHz")-1) == 0) {
-      const char* freqstr = strchr(line, ':');
-      if (freqstr) {
-        cpuinfo_cycles_per_second = strtod(freqstr+1, &err) * 1000000.0;
-        if (freqstr[1] != '\0' && *err == '\0' && cpuinfo_cycles_per_second > 0)
-          saw_mhz = true;
-      }
-    } else if (strncasecmp(line, "bogomips", sizeof("bogomips")-1) == 0) {
-      const char* freqstr = strchr(line, ':');
-      if (freqstr) {
-        bogo_clock = strtod(freqstr+1, &err) * 1000000.0;
-        if (freqstr[1] != '\0' && *err == '\0' && bogo_clock > 0)
-          saw_bogo = true;
-      }
-#endif
-    } else if (strncasecmp(line, "processor", sizeof("processor")-1) == 0) {
-      num_cpus++;  // count up every time we see an "processor :" entry
-    }
-  } while (chars_read > 0);
-  close(fd);
-
-  if (!saw_mhz) {
-    if (saw_bogo) {
-      // If we didn't find anything better, we'll use bogomips, but
-      // we're not happy about it.
-      cpuinfo_cycles_per_second = bogo_clock;
-    } else {
-      // If we don't even have bogomips, we'll use the slow estimation.
-      cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000);
-    }
-  }
-  if (cpuinfo_cycles_per_second == 0.0) {
-    cpuinfo_cycles_per_second = 1.0;   // maybe unnecessary, but safe
-  }
-  if (num_cpus > 0) {
-    cpuinfo_num_cpus = num_cpus;
-  }
-
-#elif defined __FreeBSD__
-  // For this sysctl to work, the machine must be configured without
-  // SMP, APIC, or APM support.  hz should be 64-bit in freebsd 7.0
-  // and later.  Before that, it's a 32-bit quantity (and gives the
-  // wrong answer on machines faster than 2^32 Hz).  See
-  //  http://lists.freebsd.org/pipermail/freebsd-i386/2004-November/001846.html
-  // But also compare FreeBSD 7.0:
-  //  http://fxr.watson.org/fxr/source/i386/i386/tsc.c?v=RELENG70#L223
-  //  231         error = sysctl_handle_quad(oidp, &freq, 0, req);
-  // To FreeBSD 6.3 (it's the same in 6-STABLE):
-  //  http://fxr.watson.org/fxr/source/i386/i386/tsc.c?v=RELENG6#L131
-  //  139         error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
-#if __FreeBSD__ >= 7
-  uint64_t hz = 0;
-#else
-  unsigned int hz = 0;
-#endif
-  size_t sz = sizeof(hz);
-  const char *sysctl_path = "machdep.tsc_freq";
-  if ( sysctlbyname(sysctl_path, &hz, &sz, NULL, 0) != 0 ) {
-    fprintf(stderr, "Unable to determine clock rate from sysctl: %s: %s\n",
-            sysctl_path, strerror(errno));
-    cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000);
-  } else {
-    cpuinfo_cycles_per_second = hz;
-  }
-  // TODO(csilvers): also figure out cpuinfo_num_cpus
-
-#elif defined(PLATFORM_WINDOWS)
-# pragma comment(lib, "shlwapi.lib")  // for SHGetValue()
-  // In NT, read MHz from the registry. If we fail to do so or we're in win9x
-  // then make a crude estimate.
-  OSVERSIONINFO os;
-  os.dwOSVersionInfoSize = sizeof(os);
-  DWORD data, data_size = sizeof(data);
-  if (GetVersionEx(&os) &&
-      os.dwPlatformId == VER_PLATFORM_WIN32_NT &&
-      SUCCEEDED(SHGetValueA(HKEY_LOCAL_MACHINE,
-                         "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
-                           "~MHz", NULL, &data, &data_size)))
-    cpuinfo_cycles_per_second = (int64)data * (int64)(1000 * 1000); // was mhz
-  else
-    cpuinfo_cycles_per_second = EstimateCyclesPerSecond(500); // TODO <500?
-
-  // Get the number of processors.
-  SYSTEM_INFO info;
-  GetSystemInfo(&info);
-  cpuinfo_num_cpus = info.dwNumberOfProcessors;
-
-#elif defined(__MACH__) && defined(__APPLE__)
-  // returning "mach time units" per second. the current number of elapsed
-  // mach time units can be found by calling uint64 mach_absolute_time();
-  // while not as precise as actual CPU cycles, it is accurate in the face
-  // of CPU frequency scaling and multi-cpu/core machines.
-  // Our mac users have these types of machines, and accuracy
-  // (i.e. correctness) trumps precision.
-  // See cycleclock.h: CycleClock::Now(), which returns number of mach time
-  // units on Mac OS X.
-  mach_timebase_info_data_t timebase_info;
-  mach_timebase_info(&timebase_info);
-  double mach_time_units_per_nanosecond =
-      static_cast<double>(timebase_info.denom) /
-      static_cast<double>(timebase_info.numer);
-  cpuinfo_cycles_per_second = mach_time_units_per_nanosecond * 1e9;
-
-  int num_cpus = 0;
-  size_t size = sizeof(num_cpus);
-  int numcpus_name[] = { CTL_HW, HW_NCPU };
-  if (::sysctl(numcpus_name, arraysize(numcpus_name), &num_cpus, &size, 0, 0)
-      == 0
-      && (size == sizeof(num_cpus)))
-    cpuinfo_num_cpus = num_cpus;
-
-#else
-  // Generic cycles per second counter
-  cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000);
-#endif
-}
-
-double CyclesPerSecond(void) {
-  InitializeSystemInfo();
-  return cpuinfo_cycles_per_second;
-}
-
-int NumCPUs(void) {
-  InitializeSystemInfo();
-  return cpuinfo_num_cpus;
-}
-
-// ----------------------------------------------------------------------
-// HasPosixThreads()
-//      Return true if we're running POSIX (e.g., NPTL on Linux)
-//      threads, as opposed to a non-POSIX thread library.  The thing
-//      that we care about is whether a thread's pid is the same as
-//      the thread that spawned it.  If so, this function returns
-//      true.
-// ----------------------------------------------------------------------
-bool HasPosixThreads() {
-#if defined(__linux__)
-#ifndef _CS_GNU_LIBPTHREAD_VERSION
-#define _CS_GNU_LIBPTHREAD_VERSION 3
-#endif
-  char buf[32];
-  //  We assume that, if confstr() doesn't know about this name, then
-  //  the same glibc is providing LinuxThreads.
-  if (confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof(buf)) == 0)
-    return false;
-  return strncmp(buf, "NPTL", 4) == 0;
-#elif defined(PLATFORM_WINDOWS) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-  return false;
-#else  // other OS
-  return true;      //  Assume that everything else has Posix
-#endif  // else OS_LINUX
-}
-
-// ----------------------------------------------------------------------
-
-#if defined __linux__ || defined __FreeBSD__ || defined __sun__ || defined __CYGWIN__ || defined __CYGWIN32__
-static void ConstructFilename(const char* spec, pid_t pid,
-                              char* buf, int buf_size) {
-  CHECK_LT(snprintf(buf, buf_size,
-                    spec,
-                    static_cast<int>(pid ? pid : getpid())), buf_size);
-}
-#endif
-
-// A templatized helper function instantiated for Mach (OS X) only.
-// It can handle finding info for both 32 bits and 64 bits.
-// Returns true if it successfully handled the hdr, false else.
-#ifdef __MACH__          // Mac OS X, almost certainly
-template<uint32_t kMagic, uint32_t kLCSegment,
-         typename MachHeader, typename SegmentCommand>
-static bool NextExtMachHelper(const mach_header* hdr,
-                              int current_image, int current_load_cmd,
-                              uint64 *start, uint64 *end, char **flags,
-                              uint64 *offset, int64 *inode, char **filename,
-                              uint64 *file_mapping, uint64 *file_pages,
-                              uint64 *anon_mapping, uint64 *anon_pages,
-                              dev_t *dev) {
-  static char kDefaultPerms[5] = "r-xp";
-  if (hdr->magic != kMagic)
-    return false;
-  const char* lc = (const char *)hdr + sizeof(MachHeader);
-  // TODO(csilvers): make this not-quadradic (increment and hold state)
-  for (int j = 0; j < current_load_cmd; j++)  // advance to *our* load_cmd
-    lc += ((const load_command *)lc)->cmdsize;
-  if (((const load_command *)lc)->cmd == kLCSegment) {
-    const intptr_t dlloff = _dyld_get_image_vmaddr_slide(current_image);
-    const SegmentCommand* sc = (const SegmentCommand *)lc;
-    if (start) *start = sc->vmaddr + dlloff;
-    if (end) *end = sc->vmaddr + sc->vmsize + dlloff;
-    if (flags) *flags = kDefaultPerms;  // can we do better?
-    if (offset) *offset = sc->fileoff;
-    if (inode) *inode = 0;
-    if (filename)
-      *filename = const_cast<char*>(_dyld_get_image_name(current_image));
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;   // could we use sc->filesize?
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-
-  return false;
-}
-#endif
-
-// Finds |c| in |text|, and assign '\0' at the found position.
-// The original character at the modified position should be |c|.
-// A pointer to the modified position is stored in |endptr|.
-// |endptr| should not be NULL.
-static bool ExtractUntilChar(char *text, int c, char **endptr) {
-  CHECK_NE(text, NULL);
-  CHECK_NE(endptr, NULL);
-  char *found;
-  found = strchr(text, c);
-  if (found == NULL) {
-    *endptr = NULL;
-    return false;
-  }
-
-  *endptr = found;
-  *found = '\0';
-  return true;
-}
-
-// Increments |*text_pointer| while it points a whitespace character.
-// It is to follow sscanf's whilespace handling.
-static void SkipWhileWhitespace(char **text_pointer, int c) {
-  if (isspace(c)) {
-    while (isspace(**text_pointer) && isspace(*((*text_pointer) + 1))) {
-      ++(*text_pointer);
-    }
-  }
-}
-
-template<class T>
-static T StringToInteger(char *text, char **endptr, int base) {
-  assert(false);
-  return T();
-}
-
-template<>
-int StringToInteger<int>(char *text, char **endptr, int base) {
-  return strtol(text, endptr, base);
-}
-
-template<>
-int64 StringToInteger<int64>(char *text, char **endptr, int base) {
-  return strtoll(text, endptr, base);
-}
-
-template<>
-uint64 StringToInteger<uint64>(char *text, char **endptr, int base) {
-  return strtoull(text, endptr, base);
-}
-
-template<typename T>
-static T StringToIntegerUntilChar(
-    char *text, int base, int c, char **endptr_result) {
-  CHECK_NE(endptr_result, NULL);
-  *endptr_result = NULL;
-
-  char *endptr_extract;
-  if (!ExtractUntilChar(text, c, &endptr_extract))
-    return 0;
-
-  T result;
-  char *endptr_strto;
-  result = StringToInteger<T>(text, &endptr_strto, base);
-  *endptr_extract = c;
-
-  if (endptr_extract != endptr_strto)
-    return 0;
-
-  *endptr_result = endptr_extract;
-  SkipWhileWhitespace(endptr_result, c);
-
-  return result;
-}
-
-static char *CopyStringUntilChar(
-    char *text, unsigned out_len, int c, char *out) {
-  char *endptr;
-  if (!ExtractUntilChar(text, c, &endptr))
-    return NULL;
-
-  strncpy(out, text, out_len);
-  out[out_len-1] = '\0';
-  *endptr = c;
-
-  SkipWhileWhitespace(&endptr, c);
-  return endptr;
-}
-
-template<typename T>
-static bool StringToIntegerUntilCharWithCheck(
-    T *outptr, char *text, int base, int c, char **endptr) {
-  *outptr = StringToIntegerUntilChar<T>(*endptr, base, c, endptr);
-  if (*endptr == NULL || **endptr == '\0') return false;
-  ++(*endptr);
-  return true;
-}
-
-static bool ParseProcMapsLine(char *text, uint64 *start, uint64 *end,
-                              char *flags, uint64 *offset,
-                              int *major, int *minor, int64 *inode,
-                              unsigned *filename_offset) {
-#if defined(__linux__)
-  /*
-   * It's similar to:
-   * sscanf(text, "%"SCNx64"-%"SCNx64" %4s %"SCNx64" %x:%x %"SCNd64" %n",
-   *        start, end, flags, offset, major, minor, inode, filename_offset)
-   */
-  char *endptr = text;
-  if (endptr == NULL || *endptr == '\0')  return false;
-
-  if (!StringToIntegerUntilCharWithCheck(start, endptr, 16, '-', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(end, endptr, 16, ' ', &endptr))
-    return false;
-
-  endptr = CopyStringUntilChar(endptr, 5, ' ', flags);
-  if (endptr == NULL || *endptr == '\0')  return false;
-  ++endptr;
-
-  if (!StringToIntegerUntilCharWithCheck(offset, endptr, 16, ' ', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(major, endptr, 16, ':', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(minor, endptr, 16, ' ', &endptr))
-    return false;
-
-  if (!StringToIntegerUntilCharWithCheck(inode, endptr, 10, ' ', &endptr))
-    return false;
-
-  *filename_offset = (endptr - text);
-  return true;
-#else
-  return false;
-#endif
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid) {
-  Init(pid, NULL, false);
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer) {
-  Init(pid, buffer, false);
-}
-
-ProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer,
-                                   bool use_maps_backing) {
-  Init(pid, buffer, use_maps_backing);
-}
-
-void ProcMapsIterator::Init(pid_t pid, Buffer *buffer,
-                            bool use_maps_backing) {
-  pid_ = pid;
-  using_maps_backing_ = use_maps_backing;
-  dynamic_buffer_ = NULL;
-  if (!buffer) {
-    // If the user didn't pass in any buffer storage, allocate it
-    // now. This is the normal case; the signal handler passes in a
-    // static buffer.
-    buffer = dynamic_buffer_ = new Buffer;
-  } else {
-    dynamic_buffer_ = NULL;
-  }
-
-  ibuf_ = buffer->buf_;
-
-  stext_ = etext_ = nextline_ = ibuf_;
-  ebuf_ = ibuf_ + Buffer::kBufSize - 1;
-  nextline_ = ibuf_;
-
-#if defined(__linux__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-  if (use_maps_backing) {  // don't bother with clever "self" stuff in this case
-    ConstructFilename("/proc/%d/maps_backing", pid, ibuf_, Buffer::kBufSize);
-  } else if (pid == 0) {
-    // We have to kludge a bit to deal with the args ConstructFilename
-    // expects.  The 1 is never used -- it's only impt. that it's not 0.
-    ConstructFilename("/proc/self/maps", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/maps", pid, ibuf_, Buffer::kBufSize);
-  }
-  // No error logging since this can be called from the crash dump
-  // handler at awkward moments. Users should call Valid() before
-  // using.
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__FreeBSD__)
-  // We don't support maps_backing on freebsd
-  if (pid == 0) {
-    ConstructFilename("/proc/curproc/map", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/map", pid, ibuf_, Buffer::kBufSize);
-  }
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__sun__)
-  if (pid == 0) {
-    ConstructFilename("/proc/self/map", 1, ibuf_, Buffer::kBufSize);
-  } else {
-    ConstructFilename("/proc/%d/map", pid, ibuf_, Buffer::kBufSize);
-  }
-  NO_INTR(fd_ = open(ibuf_, O_RDONLY));
-#elif defined(__MACH__)
-  current_image_ = _dyld_image_count();   // count down from the top
-  current_load_cmd_ = -1;
-#elif defined(PLATFORM_WINDOWS)
-  snapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE |
-                                       TH32CS_SNAPMODULE32,
-                                       GetCurrentProcessId());
-  memset(&module_, 0, sizeof(module_));
-#else
-  fd_ = -1;   // so Valid() is always false
-#endif
-
-}
-
-ProcMapsIterator::~ProcMapsIterator() {
-#if defined(PLATFORM_WINDOWS)
-  if (snapshot_ != INVALID_HANDLE_VALUE) CloseHandle(snapshot_);
-#elif defined(__MACH__)
-  // no cleanup necessary!
-#else
-  if (fd_ >= 0) NO_INTR(close(fd_));
-#endif
-  delete dynamic_buffer_;
-}
-
-bool ProcMapsIterator::Valid() const {
-#if defined(PLATFORM_WINDOWS)
-  return snapshot_ != INVALID_HANDLE_VALUE;
-#elif defined(__MACH__)
-  return 1;
-#else
-  return fd_ != -1;
-#endif
-}
-
-bool ProcMapsIterator::Next(uint64 *start, uint64 *end, char **flags,
-                            uint64 *offset, int64 *inode, char **filename) {
-  return NextExt(start, end, flags, offset, inode, filename, NULL, NULL,
-                 NULL, NULL, NULL);
-}
-
-// This has too many arguments.  It should really be building
-// a map object and returning it.  The problem is that this is called
-// when the memory allocator state is undefined, hence the arguments.
-bool ProcMapsIterator::NextExt(uint64 *start, uint64 *end, char **flags,
-                               uint64 *offset, int64 *inode, char **filename,
-                               uint64 *file_mapping, uint64 *file_pages,
-                               uint64 *anon_mapping, uint64 *anon_pages,
-                               dev_t *dev) {
-
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-  do {
-    // Advance to the start of the next line
-    stext_ = nextline_;
-
-    // See if we have a complete line in the buffer already
-    nextline_ = static_cast<char *>(memchr (stext_, '\n', etext_ - stext_));
-    if (!nextline_) {
-      // Shift/fill the buffer so we do have a line
-      int count = etext_ - stext_;
-
-      // Move the current text to the start of the buffer
-      memmove(ibuf_, stext_, count);
-      stext_ = ibuf_;
-      etext_ = ibuf_ + count;
-
-      int nread = 0;            // fill up buffer with text
-      while (etext_ < ebuf_) {
-        NO_INTR(nread = read(fd_, etext_, ebuf_ - etext_));
-        if (nread > 0)
-          etext_ += nread;
-        else
-          break;
-      }
-
-      // Zero out remaining characters in buffer at EOF to avoid returning
-      // garbage from subsequent calls.
-      if (etext_ != ebuf_ && nread == 0) {
-        memset(etext_, 0, ebuf_ - etext_);
-      }
-      *etext_ = '\n';   // sentinel; safe because ibuf extends 1 char beyond ebuf
-      nextline_ = static_cast<char *>(memchr (stext_, '\n', etext_ + 1 - stext_));
-    }
-    *nextline_ = 0;                // turn newline into nul
-    nextline_ += ((nextline_ < etext_)? 1 : 0);  // skip nul if not end of text
-    // stext_ now points at a nul-terminated line
-    uint64 tmpstart, tmpend, tmpoffset;
-    int64 tmpinode;
-    int major, minor;
-    unsigned filename_offset = 0;
-#if defined(__linux__)
-    // for now, assume all linuxes have the same format
-    if (!ParseProcMapsLine(
-        stext_,
-        start ? start : &tmpstart,
-        end ? end : &tmpend,
-        flags_,
-        offset ? offset : &tmpoffset,
-        &major, &minor,
-        inode ? inode : &tmpinode, &filename_offset)) continue;
-#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
-    // cygwin is like linux, except the third field is the "entry point"
-    // rather than the offset (see format_process_maps at
-    // http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/fhandler_process.cc?rev=1.89&content-type=text/x-cvsweb-markup&cvsroot=src
-    // Offset is always be 0 on cygwin: cygwin implements an mmap
-    // by loading the whole file and then calling NtMapViewOfSection.
-    // Cygwin also seems to set its flags kinda randomly; use windows default.
-    char tmpflags[5];
-    if (offset)
-      *offset = 0;
-    strcpy(flags_, "r-xp");
-    if (sscanf(stext_, "%llx-%llx %4s %llx %x:%x %lld %n",
-               start ? start : &tmpstart,
-               end ? end : &tmpend,
-               tmpflags,
-               &tmpoffset,
-               &major, &minor,
-               inode ? inode : &tmpinode, &filename_offset) != 7) continue;
-#elif defined(__FreeBSD__)
-    // For the format, see http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/fs/procfs/procfs_map.c?rev=1.31&content-type=text/x-cvsweb-markup
-    tmpstart = tmpend = tmpoffset = 0;
-    tmpinode = 0;
-    major = minor = 0;   // can't get this info in freebsd
-    if (inode)
-      *inode = 0;        // nor this
-    if (offset)
-      *offset = 0;       // seems like this should be in there, but maybe not
-    // start end resident privateresident obj(?) prot refcnt shadowcnt
-    // flags copy_on_write needs_copy type filename:
-    // 0x8048000 0x804a000 2 0 0xc104ce70 r-x 1 0 0x0 COW NC vnode /bin/cat
-    if (sscanf(stext_, "0x%" SCNx64 " 0x%" SCNx64 " %*d %*d %*p %3s %*d %*d 0x%*x %*s %*s %*s %n",
-               start ? start : &tmpstart,
-               end ? end : &tmpend,
-               flags_,
-               &filename_offset) != 3) continue;
-#endif
-
-    // Depending on the Linux kernel being used, there may or may not be a space
-    // after the inode if there is no filename.  sscanf will in such situations
-    // nondeterministically either fill in filename_offset or not (the results
-    // differ on multiple calls in the same run even with identical arguments).
-    // We don't want to wander off somewhere beyond the end of the string.
-    size_t stext_length = strlen(stext_);
-    if (filename_offset == 0 || filename_offset > stext_length)
-      filename_offset = stext_length;
-
-    // We found an entry
-    if (flags) *flags = flags_;
-    if (filename) *filename = stext_ + filename_offset;
-    if (dev) *dev = minor | (major << 8);
-
-    if (using_maps_backing_) {
-      // Extract and parse physical page backing info.
-      char *backing_ptr = stext_ + filename_offset +
-          strlen(stext_+filename_offset);
-
-      // find the second '('
-      int paren_count = 0;
-      while (--backing_ptr > stext_) {
-        if (*backing_ptr == '(') {
-          ++paren_count;
-          if (paren_count >= 2) {
-            uint64 tmp_file_mapping;
-            uint64 tmp_file_pages;
-            uint64 tmp_anon_mapping;
-            uint64 tmp_anon_pages;
-
-            sscanf(backing_ptr+1, "F %" SCNx64 " %" SCNd64 ") (A %" SCNx64 " %" SCNd64 ")",
-                   file_mapping ? file_mapping : &tmp_file_mapping,
-                   file_pages ? file_pages : &tmp_file_pages,
-                   anon_mapping ? anon_mapping : &tmp_anon_mapping,
-                   anon_pages ? anon_pages : &tmp_anon_pages);
-            // null terminate the file name (there is a space
-            // before the first (.
-            backing_ptr[-1] = 0;
-            break;
-          }
-        }
-      }
-    }
-
-    return true;
-  } while (etext_ > ibuf_);
-#elif defined(__sun__)
-  // This is based on MA_READ == 4, MA_WRITE == 2, MA_EXEC == 1
-  static char kPerms[8][4] = { "---", "--x", "-w-", "-wx",
-                               "r--", "r-x", "rw-", "rwx" };
-  COMPILE_ASSERT(MA_READ == 4, solaris_ma_read_must_equal_4);
-  COMPILE_ASSERT(MA_WRITE == 2, solaris_ma_write_must_equal_2);
-  COMPILE_ASSERT(MA_EXEC == 1, solaris_ma_exec_must_equal_1);
-  Buffer object_path;
-  int nread = 0;            // fill up buffer with text
-  NO_INTR(nread = read(fd_, ibuf_, sizeof(prmap_t)));
-  if (nread == sizeof(prmap_t)) {
-    long inode_from_mapname = 0;
-    prmap_t* mapinfo = reinterpret_cast<prmap_t*>(ibuf_);
-    // Best-effort attempt to get the inode from the filename.  I think the
-    // two middle ints are major and minor device numbers, but I'm not sure.
-    sscanf(mapinfo->pr_mapname, "ufs.%*d.%*d.%ld", &inode_from_mapname);
-
-    if (pid_ == 0) {
-      CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,
-                        "/proc/self/path/%s", mapinfo->pr_mapname),
-               Buffer::kBufSize);
-    } else {
-      CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,
-                        "/proc/%d/path/%s",
-                        static_cast<int>(pid_), mapinfo->pr_mapname),
-               Buffer::kBufSize);
-    }
-    ssize_t len = readlink(object_path.buf_, current_filename_, PATH_MAX);
-    CHECK_LT(len, PATH_MAX);
-    if (len < 0)
-      len = 0;
-    current_filename_[len] = '\0';
-
-    if (start) *start = mapinfo->pr_vaddr;
-    if (end) *end = mapinfo->pr_vaddr + mapinfo->pr_size;
-    if (flags) *flags = kPerms[mapinfo->pr_mflags & 7];
-    if (offset) *offset = mapinfo->pr_offset;
-    if (inode) *inode = inode_from_mapname;
-    if (filename) *filename = current_filename_;
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-#elif defined(__MACH__)
-  // We return a separate entry for each segment in the DLL. (TODO(csilvers):
-  // can we do better?)  A DLL ("image") has load-commands, some of which
-  // talk about segment boundaries.
-  // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/minivoicemail/dlfcn.c?revision=53912
-  for (; current_image_ >= 0; current_image_--) {
-    const mach_header* hdr = _dyld_get_image_header(current_image_);
-    if (!hdr) continue;
-    if (current_load_cmd_ < 0)   // set up for this image
-      current_load_cmd_ = hdr->ncmds;  // again, go from the top down
-
-    // We start with the next load command (we've already looked at this one).
-    for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) {
-#ifdef MH_MAGIC_64
-      if (NextExtMachHelper<MH_MAGIC_64, LC_SEGMENT_64,
-                            struct mach_header_64, struct segment_command_64>(
-                                hdr, current_image_, current_load_cmd_,
-                                start, end, flags, offset, inode, filename,
-                                file_mapping, file_pages, anon_mapping,
-                                anon_pages, dev)) {
-        return true;
-      }
-#endif
-      if (NextExtMachHelper<MH_MAGIC, LC_SEGMENT,
-                            struct mach_header, struct segment_command>(
-                                hdr, current_image_, current_load_cmd_,
-                                start, end, flags, offset, inode, filename,
-                                file_mapping, file_pages, anon_mapping,
-                                anon_pages, dev)) {
-        return true;
-      }
-    }
-    // If we get here, no more load_cmd's in this image talk about
-    // segments.  Go on to the next image.
-  }
-#elif defined(PLATFORM_WINDOWS)
-  static char kDefaultPerms[5] = "r-xp";
-  BOOL ok;
-  if (module_.dwSize == 0) {  // only possible before first call
-    module_.dwSize = sizeof(module_);
-    ok = Module32First(snapshot_, &module_);
-  } else {
-    ok = Module32Next(snapshot_, &module_);
-  }
-  if (ok) {
-    uint64 base_addr = reinterpret_cast<DWORD_PTR>(module_.modBaseAddr);
-    if (start) *start = base_addr;
-    if (end) *end = base_addr + module_.modBaseSize;
-    if (flags) *flags = kDefaultPerms;
-    if (offset) *offset = 0;
-    if (inode) *inode = 0;
-    if (filename) *filename = module_.szExePath;
-    if (file_mapping) *file_mapping = 0;
-    if (file_pages) *file_pages = 0;
-    if (anon_mapping) *anon_mapping = 0;
-    if (anon_pages) *anon_pages = 0;
-    if (dev) *dev = 0;
-    return true;
-  }
-#endif
-
-  // We didn't find anything
-  return false;
-}
-
-int ProcMapsIterator::FormatLine(char* buffer, int bufsize,
-                                 uint64 start, uint64 end, const char *flags,
-                                 uint64 offset, int64 inode,
-                                 const char *filename, dev_t dev) {
-  // We assume 'flags' looks like 'rwxp' or 'rwx'.
-  char r = (flags && flags[0] == 'r') ? 'r' : '-';
-  char w = (flags && flags[0] && flags[1] == 'w') ? 'w' : '-';
-  char x = (flags && flags[0] && flags[1] && flags[2] == 'x') ? 'x' : '-';
-  // p always seems set on linux, so we set the default to 'p', not '-'
-  char p = (flags && flags[0] && flags[1] && flags[2] && flags[3] != 'p')
-      ? '-' : 'p';
-
-  const int rc = snprintf(buffer, bufsize,
-                          "%08" PRIx64 "-%08" PRIx64 " %c%c%c%c %08" PRIx64 " %02x:%02x %-11" PRId64 " %s\n",
-                          start, end, r,w,x,p, offset,
-                          static_cast<int>(dev/256), static_cast<int>(dev%256),
-                          inode, filename);
-  return (rc < 0 || rc >= bufsize) ? 0 : rc;
-}
-
-namespace tcmalloc {
-
-// Helper to add the list of mapped shared libraries to a profile.
-// Fill formatted "/proc/self/maps" contents into buffer 'buf' of size 'size'
-// and return the actual size occupied in 'buf'.  We fill wrote_all to true
-// if we successfully wrote all proc lines to buf, false else.
-// We do not provision for 0-terminating 'buf'.
-int FillProcSelfMaps(char buf[], int size, bool* wrote_all) {
-  ProcMapsIterator::Buffer iterbuf;
-  ProcMapsIterator it(0, &iterbuf);   // 0 means "current pid"
-
-  uint64 start, end, offset;
-  int64 inode;
-  char *flags, *filename;
-  int bytes_written = 0;
-  *wrote_all = true;
-  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
-    const int line_length = it.FormatLine(buf + bytes_written,
-                                          size - bytes_written,
-                                          start, end, flags, offset,
-                                          inode, filename, 0);
-    if (line_length == 0)
-      *wrote_all = false;     // failed to write this line out
-    else
-      bytes_written += line_length;
-
-  }
-  return bytes_written;
-}
-
-// Dump the same data as FillProcSelfMaps reads to fd.
-// It seems easier to repeat parts of FillProcSelfMaps here than to
-// reuse it via a call.
-void DumpProcSelfMaps(RawFD fd) {
-  ProcMapsIterator::Buffer iterbuf;
-  ProcMapsIterator it(0, &iterbuf);   // 0 means "current pid"
-
-  uint64 start, end, offset;
-  int64 inode;
-  char *flags, *filename;
-  ProcMapsIterator::Buffer linebuf;
-  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {
-    int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),
-                                start, end, flags, offset, inode, filename,
-                                0);
-    RawWrite(fd, linebuf.buf_, written);
-  }
-}
-
-}  // namespace tcmalloc