[Avida-SVN] r3476 - in branches/tcmalloc-1.4: Avida.xcodeproj source/platform/tcmalloc-1.4
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Wed Oct 14 11:14:30 PDT 2009
Author: brysonda
Date: 2009-10-14 14:14:29 -0400 (Wed, 14 Oct 2009)
New Revision: 3476
Removed:
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/logging.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/logging.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/maybe_threads.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/maybe_threads.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/memfs_malloc.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/symbolize.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/symbolize.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/vdso_support.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/vdso_support.h
Modified:
branches/tcmalloc-1.4/Avida.xcodeproj/project.pbxproj
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/atomicops-internals-x86.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/malloc_extension.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sysinfo.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sysinfo.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/system-alloc.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/tcmalloc.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.h
Log:
Strip more unused code from tcmalloc-1.4.
Modified: branches/tcmalloc-1.4/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/tcmalloc-1.4/Avida.xcodeproj/project.pbxproj 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/Avida.xcodeproj/project.pbxproj 2009-10-14 18:14:29 UTC (rev 3476)
@@ -49,21 +49,16 @@
702246DE107FCA900079CD25 /* common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246B9107FCA590079CD25 /* common.cc */; };
702246DF107FCA900079CD25 /* internal_logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246BB107FCA590079CD25 /* internal_logging.cc */; };
702246E0107FCA900079CD25 /* malloc_extension.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246BE107FCA590079CD25 /* malloc_extension.cc */; };
- 702246E2107FCA900079CD25 /* maybe_threads.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246C1107FCA590079CD25 /* maybe_threads.cc */; };
- 702246E3107FCA900079CD25 /* memfs_malloc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246C3107FCA590079CD25 /* memfs_malloc.cc */; };
702246E4107FCA900079CD25 /* page_heap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246C6107FCA590079CD25 /* page_heap.cc */; };
702246E6107FCA900079CD25 /* span.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246CB107FCA590079CD25 /* span.cc */; };
702246E7107FCA900079CD25 /* spinlock.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246CD107FCA590079CD25 /* spinlock.cc */; };
702246E9107FCA900079CD25 /* static_vars.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246D1107FCA590079CD25 /* static_vars.cc */; };
- 702246EA107FCA900079CD25 /* symbolize.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246D3107FCA590079CD25 /* symbolize.cc */; };
702246EB107FCA900079CD25 /* system-alloc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246D5107FCA590079CD25 /* system-alloc.cc */; };
702246EC107FCA900079CD25 /* tcmalloc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246D8107FCA590079CD25 /* tcmalloc.cc */; settings = {COMPILER_FLAGS = "-fexceptions"; }; };
702246ED107FCA900079CD25 /* thread_cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246D9107FCA590079CD25 /* thread_cache.cc */; };
7022476010861BD30079CD25 /* dynamic_annotations.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7022475E10861BD30079CD25 /* dynamic_annotations.cc */; };
7022479E108620E40079CD25 /* sysinfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7022479C108620E40079CD25 /* sysinfo.cc */; };
702247F2108625920079CD25 /* libtcmalloc-1.4.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7022469D107FC4F10079CD25 /* libtcmalloc-1.4.a */; };
- 7022480E108627DC0079CD25 /* vdso_support.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7022480D108627DC0079CD25 /* vdso_support.cc */; };
- 70224818108628640079CD25 /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70224817108628640079CD25 /* logging.cc */; };
7023EC3A0C0A431B00362B9C /* avida.cc in Sources */ = {isa = PBXBuildFile; fileRef = DCC3109C0762539E008F7A48 /* avida.cc */; };
7023EC3B0C0A431B00362B9C /* cActionLibrary.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708051BA0A1F66B400CBB8B6 /* cActionLibrary.cc */; };
7023EC3C0C0A431B00362B9C /* cAnalyze.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70422A1C091B141000A5E67F /* cAnalyze.cc */; };
@@ -493,9 +488,6 @@
702246BC107FCA590079CD25 /* internal_logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal_logging.h; sourceTree = "<group>"; };
702246BD107FCA590079CD25 /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linked_list.h; sourceTree = "<group>"; };
702246BE107FCA590079CD25 /* malloc_extension.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = malloc_extension.cc; sourceTree = "<group>"; };
- 702246C1107FCA590079CD25 /* maybe_threads.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = maybe_threads.cc; sourceTree = "<group>"; };
- 702246C2107FCA590079CD25 /* maybe_threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = maybe_threads.h; sourceTree = "<group>"; };
- 702246C3107FCA590079CD25 /* memfs_malloc.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memfs_malloc.cc; sourceTree = "<group>"; };
702246C4107FCA590079CD25 /* packed-cache-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "packed-cache-inl.h"; sourceTree = "<group>"; };
702246C5107FCA590079CD25 /* page_heap_allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = page_heap_allocator.h; sourceTree = "<group>"; };
702246C6107FCA590079CD25 /* page_heap.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = page_heap.cc; sourceTree = "<group>"; };
@@ -507,8 +499,6 @@
702246CE107FCA590079CD25 /* spinlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spinlock.h; sourceTree = "<group>"; };
702246D1107FCA590079CD25 /* static_vars.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = static_vars.cc; sourceTree = "<group>"; };
702246D2107FCA590079CD25 /* static_vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = static_vars.h; sourceTree = "<group>"; };
- 702246D3107FCA590079CD25 /* symbolize.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = symbolize.cc; sourceTree = "<group>"; };
- 702246D4107FCA590079CD25 /* symbolize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = symbolize.h; sourceTree = "<group>"; };
702246D5107FCA590079CD25 /* system-alloc.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "system-alloc.cc"; sourceTree = "<group>"; };
702246D6107FCA590079CD25 /* system-alloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "system-alloc.h"; sourceTree = "<group>"; };
702246D7107FCA590079CD25 /* tcmalloc_guard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcmalloc_guard.h; sourceTree = "<group>"; };
@@ -521,7 +511,6 @@
7022477A10861D390079CD25 /* tcmalloc-platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "tcmalloc-platform.h"; sourceTree = "<group>"; };
7022479C108620E40079CD25 /* sysinfo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sysinfo.cc; sourceTree = "<group>"; };
7022479D108620E40079CD25 /* sysinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysinfo.h; sourceTree = "<group>"; };
- 702247A4108621060079CD25 /* logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logging.h; sourceTree = "<group>"; };
702247AD108621660079CD25 /* malloc_extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = malloc_extension.h; sourceTree = "<group>"; };
702247D51086236F0079CD25 /* cycleclock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cycleclock.h; sourceTree = "<group>"; };
702247D61086236F0079CD25 /* spinlock_linux-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "spinlock_linux-inl.h"; sourceTree = "<group>"; };
@@ -529,9 +518,6 @@
702247D81086236F0079CD25 /* spinlock_win32-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "spinlock_win32-inl.h"; sourceTree = "<group>"; };
702247DA108623920079CD25 /* linux_syscall_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linux_syscall_support.h; sourceTree = "<group>"; };
702247E3108624160079CD25 /* tcmalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcmalloc.h; sourceTree = "<group>"; };
- 7022480D108627DC0079CD25 /* vdso_support.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdso_support.cc; sourceTree = "<group>"; };
- 7022480F108627E60079CD25 /* vdso_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vdso_support.h; sourceTree = "<group>"; };
- 70224817108628640079CD25 /* logging.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logging.cc; sourceTree = "<group>"; };
7023EC330C0A426900362B9C /* libavida-core.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libavida-core.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7027621909D73E5900741717 /* cOrgSourceMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cOrgSourceMessage.h; sourceTree = "<group>"; };
7027621A09D73E7700741717 /* cOrgSinkMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cOrgSinkMessage.h; sourceTree = "<group>"; };
@@ -1163,9 +1149,6 @@
70224698107FC4BB0079CD25 /* tcmalloc-1.4 */ = {
isa = PBXGroup;
children = (
- 70224817108628640079CD25 /* logging.cc */,
- 7022480F108627E60079CD25 /* vdso_support.h */,
- 7022480D108627DC0079CD25 /* vdso_support.cc */,
702247E3108624160079CD25 /* tcmalloc.h */,
702247DA108623920079CD25 /* linux_syscall_support.h */,
702247D51086236F0079CD25 /* cycleclock.h */,
@@ -1173,7 +1156,6 @@
702247D71086236F0079CD25 /* spinlock_posix-inl.h */,
702247D81086236F0079CD25 /* spinlock_win32-inl.h */,
702247AD108621660079CD25 /* malloc_extension.h */,
- 702247A4108621060079CD25 /* logging.h */,
7022479C108620E40079CD25 /* sysinfo.cc */,
7022479D108620E40079CD25 /* sysinfo.h */,
7022477A10861D390079CD25 /* tcmalloc-platform.h */,
@@ -1196,9 +1178,6 @@
702246BC107FCA590079CD25 /* internal_logging.h */,
702246BD107FCA590079CD25 /* linked_list.h */,
702246BE107FCA590079CD25 /* malloc_extension.cc */,
- 702246C1107FCA590079CD25 /* maybe_threads.cc */,
- 702246C2107FCA590079CD25 /* maybe_threads.h */,
- 702246C3107FCA590079CD25 /* memfs_malloc.cc */,
702246C4107FCA590079CD25 /* packed-cache-inl.h */,
702246C5107FCA590079CD25 /* page_heap_allocator.h */,
702246C6107FCA590079CD25 /* page_heap.cc */,
@@ -1210,8 +1189,6 @@
702246CE107FCA590079CD25 /* spinlock.h */,
702246D1107FCA590079CD25 /* static_vars.cc */,
702246D2107FCA590079CD25 /* static_vars.h */,
- 702246D3107FCA590079CD25 /* symbolize.cc */,
- 702246D4107FCA590079CD25 /* symbolize.h */,
702246D5107FCA590079CD25 /* system-alloc.cc */,
702246D6107FCA590079CD25 /* system-alloc.h */,
702246D7107FCA590079CD25 /* tcmalloc_guard.h */,
@@ -2250,20 +2227,15 @@
702246DE107FCA900079CD25 /* common.cc in Sources */,
702246DF107FCA900079CD25 /* internal_logging.cc in Sources */,
702246E0107FCA900079CD25 /* malloc_extension.cc in Sources */,
- 702246E2107FCA900079CD25 /* maybe_threads.cc in Sources */,
- 702246E3107FCA900079CD25 /* memfs_malloc.cc in Sources */,
702246E4107FCA900079CD25 /* page_heap.cc in Sources */,
702246E6107FCA900079CD25 /* span.cc in Sources */,
702246E7107FCA900079CD25 /* spinlock.cc in Sources */,
702246E9107FCA900079CD25 /* static_vars.cc in Sources */,
- 702246EA107FCA900079CD25 /* symbolize.cc in Sources */,
702246EB107FCA900079CD25 /* system-alloc.cc in Sources */,
702246EC107FCA900079CD25 /* tcmalloc.cc in Sources */,
702246ED107FCA900079CD25 /* thread_cache.cc in Sources */,
7022476010861BD30079CD25 /* dynamic_annotations.cc in Sources */,
7022479E108620E40079CD25 /* sysinfo.cc in Sources */,
- 7022480E108627DC0079CD25 /* vdso_support.cc in Sources */,
- 70224818108628640079CD25 /* logging.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/atomicops-internals-x86.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/atomicops-internals-x86.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/atomicops-internals-x86.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -34,7 +34,6 @@
#include "atomicops.h"
#include "basictypes.h"
-#include "logging.h"
#include <string.h>
// This file only makes sense with atomicops-internals-x86.h -- it
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/logging.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/logging.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/logging.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,108 +0,0 @@
-// Copyright (c) 2007, 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 just provides storage for FLAGS_verbose.
-
-#include "tcmalloc-platform.h"
-
-#include "logging.h"
-#include "commandlineflags.h"
-
-DEFINE_int32(verbose, EnvToInt("PERFTOOLS_VERBOSE", 0),
- "Set to numbers >0 for more verbose output, or <0 for less. "
- "--verbose == -4 means we log fatal errors only.");
-
-
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-
-// While windows does have a POSIX-compatible API
-// (_open/_write/_close), it acquires memory. Using this lower-level
-// windows API is the closest we can get to being "raw".
-RawFD RawOpenForWriting(const char* filename) {
- // CreateFile allocates memory if file_name isn't absolute, so if
- // that ever becomes a problem then we ought to compute the absolute
- // path on its behalf (perhaps the ntdll/kernel function isn't aware
- // of the working directory?)
- RawFD fd = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, 0, NULL);
- if (fd != kIllegalRawFD && GetLastError() == ERROR_ALREADY_EXISTS)
- SetEndOfFile(fd); // truncate the existing file
- return fd;
-}
-
-void RawWrite(RawFD handle, const char* buf, size_t len) {
- while (len > 0) {
- DWORD wrote;
- BOOL ok = WriteFile(handle, buf, len, &wrote, NULL);
- // We do not use an asynchronous file handle, so ok==false means an error
- if (!ok) break;
- buf += wrote;
- len -= wrote;
- }
-}
-
-void RawClose(RawFD handle) {
- CloseHandle(handle);
-}
-
-#else // _WIN32 || __CYGWIN__ || __CYGWIN32__
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-// Re-run fn until it doesn't cause EINTR.
-#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
-
-RawFD RawOpenForWriting(const char* filename) {
- return open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0664);
-}
-
-void RawWrite(RawFD fd, const char* buf, size_t len) {
- while (len > 0) {
- ssize_t r;
- NO_INTR(r = write(fd, buf, len));
- if (r <= 0) break;
- buf += r;
- len -= r;
- }
-}
-
-void RawClose(RawFD fd) {
- NO_INTR(close(fd));
-}
-
-#endif // _WIN32 || __CYGWIN__ || __CYGWIN32__
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/logging.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/logging.h 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/logging.h 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,237 +0,0 @@
-// Copyright (c) 2005, 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 contains #include information about logging-related stuff.
-// Pretty much everybody needs to #include this file so that they can
-// log various happenings.
-//
-#ifndef _LOGGING_H_
-#define _LOGGING_H_
-
-#include "tcmalloc-platform.h"
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> // for write()
-#endif
-#include <string.h> // for strlen(), strcmp()
-#include <assert.h>
-#include <errno.h> // for errno
-#include "commandlineflags.h"
-
-// On some systems (like freebsd), we can't call write() at all in a
-// global constructor, perhaps because errno hasn't been set up.
-// Calling the write syscall is safer (it doesn't set errno), so we
-// prefer that. Note we don't care about errno for logging: we just
-// do logging on a best-effort basis.
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#define WRITE_TO_STDERR(buf, len) syscall(SYS_write, STDERR_FILENO, buf, len)
-#else
-#define WRITE_TO_STDERR(buf, len) write(STDERR_FILENO, buf, len)
-#endif
-
-
-// We log all messages at this log-level and below.
-// INFO == -1, WARNING == -2, ERROR == -3, FATAL == -4
-DECLARE_int32(verbose);
-
-// CHECK dies with a fatal error if condition is not true. It is *not*
-// controlled by NDEBUG, so the check will be executed regardless of
-// compilation mode. Therefore, it is safe to do things like:
-// CHECK(fp->Write(x) == 4)
-// Note we use write instead of printf/puts to avoid the risk we'll
-// call malloc().
-#define CHECK(condition) \
- do { \
- if (!(condition)) { \
- WRITE_TO_STDERR("Check failed: " #condition "\n", \
- sizeof("Check failed: " #condition "\n")-1); \
- exit(1); \
- } \
- } while (0)
-
-// This takes a message to print. The name is historical.
-#define RAW_CHECK(condition, message) \
- do { \
- if (!(condition)) { \
- WRITE_TO_STDERR("Check failed: " #condition ": " message "\n", \
- sizeof("Check failed: " #condition ": " message "\n")-1);\
- exit(1); \
- } \
- } while (0)
-
-// This is like RAW_CHECK, but only in debug-mode
-#ifdef NDEBUG
-enum { DEBUG_MODE = 0 };
-#define RAW_DCHECK(condition, message)
-#else
-enum { DEBUG_MODE = 1 };
-#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
-#endif
-
-// This prints errno as well. Note we use write instead of printf/puts to
-// avoid the risk we'll call malloc().
-#define PCHECK(condition) \
- do { \
- if (!(condition)) { \
- const int err_no = errno; \
- WRITE_TO_STDERR("Check failed: " #condition ": ", \
- sizeof("Check failed: " #condition ": ")-1); \
- WRITE_TO_STDERR(strerror(err_no), strlen(strerror(err_no))); \
- WRITE_TO_STDERR("\n", sizeof("\n")-1); \
- exit(1); \
- } \
- } while (0)
-
-// Helper macro for binary operators; prints the two values on error
-// Don't use this macro directly in your code, use CHECK_EQ et al below
-
-// WARNING: These don't compile correctly if one of the arguments is a pointer
-// and the other is NULL. To work around this, simply static_cast NULL to the
-// type of the desired pointer.
-
-// TODO(jandrews): Also print the values in case of failure. Requires some
-// sort of type-sensitive ToString() function.
-#define CHECK_OP(op, val1, val2) \
- do { \
- if (!((val1) op (val2))) { \
- fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \
- exit(1); \
- } \
- } while (0)
-
-#define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
-#define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
-#define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
-#define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
-#define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
-#define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
-
-// A synonym for CHECK_* that is used in some unittests.
-#define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
-#define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
-#define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
-#define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
-#define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
-#define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
-// As are these variants.
-#define EXPECT_TRUE(cond) CHECK(cond)
-#define EXPECT_FALSE(cond) CHECK(!(cond))
-#define EXPECT_STREQ(a, b) CHECK(strcmp(a, b) == 0)
-
-// Used for (libc) functions that return -1 and set errno
-#define CHECK_ERR(invocation) PCHECK((invocation) != -1)
-
-// A few more checks that only happen in debug mode
-#ifdef NDEBUG
-#define DCHECK_EQ(val1, val2)
-#define DCHECK_NE(val1, val2)
-#define DCHECK_LE(val1, val2)
-#define DCHECK_LT(val1, val2)
-#define DCHECK_GE(val1, val2)
-#define DCHECK_GT(val1, val2)
-#else
-#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
-#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
-#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
-#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
-#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
-#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
-#endif
-
-
-#ifdef ERROR
-#undef ERROR // may conflict with ERROR macro on windows
-#endif
-enum LogSeverity {INFO = -1, WARNING = -2, ERROR = -3, FATAL = -4};
-
-// NOTE: we add a newline to the end of the output if it's not there already
-inline void LogPrintf(int severity, const char* pat, va_list ap) {
- // We write directly to the stderr file descriptor and avoid FILE
- // buffering because that may invoke malloc()
- char buf[600];
- vsnprintf(buf, sizeof(buf)-1, pat, ap);
- if (buf[0] != '\0' && buf[strlen(buf)-1] != '\n') {
- assert(strlen(buf)+1 < sizeof(buf));
- strcat(buf, "\n");
- }
- WRITE_TO_STDERR(buf, strlen(buf));
- if ((severity) == FATAL)
- abort(); // LOG(FATAL) indicates a big problem, so don't run atexit() calls
-}
-
-// Note that since the order of global constructors is unspecified,
-// global code that calls RAW_LOG may execute before FLAGS_verbose is set.
-// Such code will run with verbosity == 0 no matter what.
-#define VLOG_IS_ON(severity) (FLAGS_verbose >= severity)
-
-// In a better world, we'd use __VA_ARGS__, but VC++ 7 doesn't support it.
-#define LOG_PRINTF(severity, pat) do { \
- if (VLOG_IS_ON(severity)) { \
- va_list ap; \
- va_start(ap, pat); \
- LogPrintf(severity, pat, ap); \
- va_end(ap); \
- } \
-} while (0)
-
-// RAW_LOG is the main function; some synonyms are used in unittests.
-inline void RAW_LOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }
-inline void RAW_VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }
-inline void LOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }
-inline void VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }
-inline void LOG_IF(int lvl, bool cond, const char* pat, ...) {
- if (cond) LOG_PRINTF(lvl, pat);
-}
-
-// This isn't technically logging, but it's also IO and also is an
-// attempt to be "raw" -- that is, to not use any higher-level libc
-// routines that might allocate memory or (ideally) try to allocate
-// locks. We use an opaque file handle (not necessarily an int)
-// to allow even more low-level stuff in the future.
-// Like other "raw" routines, these functions are best effort, and
-// thus don't return error codes (except RawOpenForWriting()).
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-#include <windows.h>
-typedef HANDLE RawFD;
-const RawFD kIllegalRawFD = INVALID_HANDLE_VALUE;
-#else
-typedef int RawFD;
-const RawFD kIllegalRawFD = -1; // what open returns if it fails
-#endif // defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)
-
-RawFD RawOpenForWriting(const char* filename); // uses default permissions
-void RawWrite(RawFD fd, const char* buf, size_t len);
-void RawClose(RawFD fd);
-
-#endif // _LOGGING_H_
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/malloc_extension.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/malloc_extension.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/malloc_extension.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -49,7 +49,6 @@
#include "heap-checker.h"
#endif
#include "malloc_extension.h"
-#include "maybe_threads.h"
using STL_NAMESPACE::string;
@@ -176,12 +175,12 @@
}
MallocExtension* MallocExtension::instance() {
- perftools_pthread_once(&module_init, InitModule);
+ pthread_once(&module_init, InitModule);
return current_instance;
}
void MallocExtension::Register(MallocExtension* implementation) {
- perftools_pthread_once(&module_init, InitModule);
+ pthread_once(&module_init, InitModule);
// When running under valgrind, our custom malloc is replaced with
// valgrind's one and malloc extensions will not work.
if (!RunningOnValgrind()) {
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/maybe_threads.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/maybe_threads.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/maybe_threads.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,113 +0,0 @@
-// Copyright (c) 2005, 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: Paul Menage <opensource at google.com>
-//
-// Some wrappers for pthread functions so that we can be LD_PRELOADed
-// against non-pthreads apps.
-//
-// This module will behave very strangely if some pthreads functions
-// exist and others don't.
-
-#include "tcmalloc-platform.h"
-#include <assert.h>
-#include <string.h> // for memcmp
-// We don't actually need strings. But including this header seems to
-// stop the compiler trying to short-circuit our pthreads existence
-// tests and claiming that the address of a function is always
-// non-zero. I have no idea why ...
-#include <string>
-#include "maybe_threads.h"
-#include "basictypes.h"
-
-// __THROW is defined in glibc systems. It means, counter-intuitively,
-// "This function will never throw an exception." It's an optional
-// optimization tool, but we may need to use it to match glibc prototypes.
-#ifndef __THROW // I guess we're not on a glibc system
-# define __THROW // __THROW is just an optimization, so ok to make it ""
-#endif
-
-// These are the methods we're going to conditionally include.
-extern "C" {
- int pthread_key_create (pthread_key_t*, void (*)(void*))
- __THROW ATTRIBUTE_WEAK;
- void *pthread_getspecific(pthread_key_t)
- __THROW ATTRIBUTE_WEAK;
- int pthread_setspecific(pthread_key_t, const void*)
- __THROW ATTRIBUTE_WEAK;
- int pthread_once(pthread_once_t *, void (*)(void))
- __THROW ATTRIBUTE_WEAK;
-}
-
-#define MAX_PERTHREAD_VALS 16
-static void *perftools_pthread_specific_vals[MAX_PERTHREAD_VALS];
-static int next_key;
-
-int perftools_pthread_key_create(pthread_key_t *key,
- void (*destr_function) (void *)) {
- if (pthread_key_create) {
- return pthread_key_create(key, destr_function);
- } else {
- assert(next_key < MAX_PERTHREAD_VALS);
- *key = (pthread_key_t)(next_key++);
- return 0;
- }
-}
-
-void *perftools_pthread_getspecific(pthread_key_t key) {
- if (pthread_getspecific) {
- return pthread_getspecific(key);
- } else {
- return perftools_pthread_specific_vals[(int)key];
- }
-}
-
-int perftools_pthread_setspecific(pthread_key_t key, void *val) {
- if (pthread_setspecific) {
- return pthread_setspecific(key, val);
- } else {
- perftools_pthread_specific_vals[(int)key] = val;
- return 0;
- }
-}
-
-static pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT;
-int perftools_pthread_once(pthread_once_t *ctl,
- void (*init_routine) (void)) {
- if (pthread_once) {
- return pthread_once(ctl, init_routine);
- } else {
- if (memcmp(ctl, &pthread_once_init, sizeof(*ctl)) == 0) {
- init_routine();
- ++*(char*)(ctl); // make it so it's no longer equal to init
- }
- return 0;
- }
-}
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/maybe_threads.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/maybe_threads.h 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/maybe_threads.h 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,52 +0,0 @@
-// Copyright (c) 2005, 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: Paul Menage <opensource at google.com>
-
-//-------------------------------------------------------------------
-// Some wrappers for pthread functions so that we can be LD_PRELOADed
-// against non-pthreads apps.
-//-------------------------------------------------------------------
-
-#ifndef GOOGLE_MAYBE_THREADS_H_
-#define GOOGLE_MAYBE_THREADS_H_
-
-#ifdef HAVE_PTHREAD
-#include <pthread.h>
-#endif
-
-int perftools_pthread_key_create(pthread_key_t *key,
- void (*destr_function) (void *));
-void *perftools_pthread_getspecific(pthread_key_t key);
-int perftools_pthread_setspecific(pthread_key_t key, void *val);
-int perftools_pthread_once(pthread_once_t *ctl,
- void (*init_routine) (void));
-
-#endif /* GOOGLE_MAYBE_THREADS_H_ */
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/memfs_malloc.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/memfs_malloc.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/memfs_malloc.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,229 +0,0 @@
-// Copyright (c) 2007, 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: Arun Sharma
-//
-// A tcmalloc system allocator that uses a memory based filesystem such as
-// tmpfs or hugetlbfs
-//
-// Since these only exist on linux, we only register this allocator there.
-
-#ifdef __linux
-
-#include "tcmalloc-platform.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/vfs.h> // for statfs
-#include <string>
-
-#include "basictypes.h"
-#include "googleinit.h"
-#include "sysinfo.h"
-#include "system-alloc.h"
-#include "internal_logging.h"
-
-using std::string;
-
-DEFINE_string(memfs_malloc_path, EnvToString("TCMALLOC_MEMFS_MALLOC_PATH", ""),
- "Path where hugetlbfs or tmpfs is mounted. The caller is "
- "responsible for ensuring that the path is unique and does "
- "not conflict with another process");
-DEFINE_int64(memfs_malloc_limit_mb,
- EnvToInt("TCMALLOC_MEMFS_LIMIT_MB", 0),
- "Limit total allocation size to the "
- "specified number of MiB. 0 == no limit.");
-DEFINE_bool(memfs_malloc_abort_on_fail,
- EnvToBool("TCMALLOC_MEMFS_ABORT_ON_FAIL", false),
- "abort() whenever memfs_malloc fails to satisfy an allocation "
- "for any reason.");
-DEFINE_bool(memfs_malloc_ignore_mmap_fail,
- EnvToBool("TCMALLOC_MEMFS_IGNORE_MMAP_FAIL", false),
- "Ignore failures from mmap");
-
-// Hugetlbfs based allocator for tcmalloc
-class HugetlbSysAllocator: public SysAllocator {
-public:
- HugetlbSysAllocator(int fd, int page_size)
- : big_page_size_(page_size),
- hugetlb_fd_(fd),
- hugetlb_base_(0) {
- }
-
- void* Alloc(size_t size, size_t *actual_size, size_t alignment);
-
- void DumpStats(TCMalloc_Printer* printer);
-
-private:
- int64 big_page_size_;
- int hugetlb_fd_; // file descriptor for hugetlb
- off_t hugetlb_base_;
-};
-
-void HugetlbSysAllocator::DumpStats(TCMalloc_Printer* printer) {
- printer->printf("HugetlbSysAllocator: failed_=%d allocated=%"PRId64"\n",
- failed_, static_cast<int64_t>(hugetlb_base_));
-}
-
-// No locking needed here since we assume that tcmalloc calls
-// us with an internal lock held (see tcmalloc/system-alloc.cc).
-void* HugetlbSysAllocator::Alloc(size_t size, size_t *actual_size,
- size_t alignment) {
-
- // We don't respond to allocation requests smaller than big_page_size_ unless
- // the caller is willing to take more than they asked for.
- if (actual_size == NULL && size < big_page_size_) {
- return NULL;
- }
-
- // Enforce huge page alignment. Be careful to deal with overflow.
- if (alignment < big_page_size_) alignment = big_page_size_;
- size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;
- if (aligned_size < size) {
- return NULL;
- }
- size = aligned_size;
-
- // Ask for extra memory if alignment > pagesize
- size_t extra = 0;
- if (alignment > big_page_size_) {
- extra = alignment - big_page_size_;
- }
-
- // Test if this allocation would put us over the limit.
- off_t limit = FLAGS_memfs_malloc_limit_mb*1024*1024;
- if (limit > 0 && hugetlb_base_ + size + extra > limit) {
- // Disable the allocator when there's less than one page left.
- if (limit - hugetlb_base_ < big_page_size_) {
- TCMalloc_MESSAGE(__FILE__, __LINE__, "reached memfs_malloc_limit_mb\n");
- failed_ = true;
- }
- else {
- TCMalloc_MESSAGE(__FILE__, __LINE__, "alloc size=%"PRIuS
- " too large while %"PRId64" bytes remain\n",
- size, static_cast<int64_t>(limit - hugetlb_base_));
- }
- if (FLAGS_memfs_malloc_abort_on_fail) {
- CRASH("memfs_malloc_abort_on_fail is set\n");
- }
- return NULL;
- }
-
- // This is not needed for hugetlbfs, but needed for tmpfs. Annoyingly
- // hugetlbfs returns EINVAL for ftruncate.
- int ret = ftruncate(hugetlb_fd_, hugetlb_base_ + size + extra);
- if (ret != 0 && errno != EINVAL) {
- TCMalloc_MESSAGE(__FILE__, __LINE__, "ftruncate failed: %s\n",
- strerror(errno));
- failed_ = true;
- if (FLAGS_memfs_malloc_abort_on_fail) {
- CRASH("memfs_malloc_abort_on_fail is set\n");
- }
- return NULL;
- }
-
- // Note: size + extra does not overflow since:
- // size + alignment < (1<<NBITS).
- // and extra <= alignment
- // therefore size + extra < (1<<NBITS)
- void *result = mmap(0, size + extra, PROT_WRITE|PROT_READ,
- MAP_SHARED, hugetlb_fd_, hugetlb_base_);
- if (result == reinterpret_cast<void*>(MAP_FAILED)) {
- if (!FLAGS_memfs_malloc_ignore_mmap_fail) {
- TCMalloc_MESSAGE(__FILE__, __LINE__, "mmap failed: %s\n",
- strerror(errno));
- failed_ = true;
- if (FLAGS_memfs_malloc_abort_on_fail) {
- CRASH("memfs_malloc_abort_on_fail is set\n");
- }
- }
- return NULL;
- }
- uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-
- // Adjust the return memory so it is aligned
- size_t adjust = 0;
- if ((ptr & (alignment - 1)) != 0) {
- adjust = alignment - (ptr & (alignment - 1));
- }
- ptr += adjust;
- hugetlb_base_ += (size + extra);
-
- if (actual_size) {
- *actual_size = size + extra - adjust;
- }
-
- return reinterpret_cast<void*>(ptr);
-}
-
-static void InitSystemAllocator() {
- if (FLAGS_memfs_malloc_path.length()) {
- char path[PATH_MAX];
- int rc = snprintf(path, sizeof(path), "%s.XXXXXX",
- FLAGS_memfs_malloc_path.c_str());
- if (rc < 0 || rc >= sizeof(path)) {
- CRASH("XX fatal: memfs_malloc_path too long\n");
- }
-
- int hugetlb_fd = mkstemp(path);
- if (hugetlb_fd == -1) {
- TCMalloc_MESSAGE(__FILE__, __LINE__,
- "warning: unable to create memfs_malloc_path %s: %s\n",
- path, strerror(errno));
- return;
- }
-
- // Cleanup memory on process exit
- if (unlink(path) == -1) {
- CRASH("fatal: error unlinking memfs_malloc_path %s: %s\n",
- path, strerror(errno));
- }
-
- // Use fstatfs to figure out the default page size for memfs
- struct statfs sfs;
- if (fstatfs(hugetlb_fd, &sfs) == -1) {
- CRASH("fatal: error fstatfs of memfs_malloc_path: %s\n",
- strerror(errno));
- }
- int64 page_size = sfs.f_bsize;
-
- SysAllocator *alloc = new HugetlbSysAllocator(hugetlb_fd, page_size);
- // Register ourselves with tcmalloc
- RegisterSystemAllocator(alloc, 0);
- }
-}
-
-REGISTER_MODULE_INITIALIZER(memfs_malloc, { InitSystemAllocator(); });
-
-#endif /* ifdef __linux */
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/symbolize.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/symbolize.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/symbolize.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,162 +0,0 @@
-// 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.
-
-// ---
-// Author: Craig Silverstein
-//
-// This forks out to pprof to do the actual symbolizing. We might
-// be better off writing our own in C++.
-
-#include "tcmalloc-platform.h"
-#include "symbolize.h"
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> // for write()
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h> // for socketpair() -- needed by Symbolize
-#endif
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h> // for wait() -- needed by Symbolize
-#endif
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
-#include <string>
-#include "commandlineflags.h"
-#include "sysinfo.h"
-
-using std::string;
-using tcmalloc::DumpProcSelfMaps; // from sysinfo.h
-
-
-DEFINE_string(symbolize_pprof,
- EnvToString("PPROF_PATH", "pprof"),
- "Path to pprof to call for reporting function names.");
-
-// heap_profile_table_pprof may be referenced after destructors are
-// called (since that's when leak-checking is done), so we make
-// a more-permanent copy that won't ever get destroyed.
-static string* g_pprof_path = new string(FLAGS_symbolize_pprof);
-
-// It would be much more efficient to call Symbolize on a bunch of pc's
-// at once, rather than calling one at a time, but this way it's simpler
-// to code, and efficiency probably isn't a top concern when reporting
-// found leaks at program-exit time.
-// Note that the forking/etc is not thread-safe or re-entrant. That's
-// ok for the purpose we need -- reporting leaks detected by heap-checker
-// -- but be careful if you decide to use this routine for other purposes.
-extern "C" bool Symbolize(void *pc, char *out, int out_size) {
-#if !defined(HAVE_UNISTD_H) || !defined(HAVE_SYS_SOCKET_H) || !defined(HAVE_SYS_WAIT_H)
- return false;
-#elif !defined(HAVE_PROGRAM_INVOCATION_NAME)
- return false; // TODO(csilvers): get argv[0] somehow
-#else
- // All this work is to do two-way communication. ugh.
- extern char* program_invocation_name; // gcc provides this
- int child_in[2]; // file descriptors
- int child_out[2]; // for now, we don't worry about child_err
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, child_in) == -1) {
- return false;
- }
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, child_out) == -1) {
- close(child_in[0]);
- close(child_in[1]);
- return false;
- }
- switch (fork()) {
- case -1: { // error
- close(child_in[0]);
- close(child_in[1]);
- close(child_out[0]);
- close(child_out[1]);
- return false;
- }
- case 0: { // child
- close(child_in[1]); // child uses the 0's, parent uses the 1's
- close(child_out[1]); // child uses the 0's, parent uses the 1's
- close(0);
- close(1);
- if (dup2(child_in[0], 0) == -1) _exit(1);
- if (dup2(child_out[0], 1) == -1) _exit(2);
- // Unset vars that might cause trouble when we fork
- unsetenv("CPUPROFILE");
- unsetenv("HEAPPROFILE");
- unsetenv("HEAPCHECK");
- unsetenv("PERFTOOLS_VERBOSE");
- execlp(g_pprof_path->c_str(), g_pprof_path->c_str(),
- "--symbols", program_invocation_name, NULL);
- _exit(3); // if execvp fails, it's bad news for us
- }
- default: { // parent
- close(child_in[0]); // child uses the 0's, parent uses the 1's
- close(child_out[0]); // child uses the 0's, parent uses the 1's
-#ifdef HAVE_POLL_H
- // For maximum safety, we check to make sure the execlp
- // succeeded before trying to write. (Otherwise we'll get a
- // SIGPIPE.) For systems without poll.h, we'll just skip this
- // check, and trust that the user set PPROF_PATH correctly!
- struct pollfd pfd = { child_in[1], POLLOUT, 0 };
- if (!poll(&pfd, 1, 0) || !(pfd.revents & POLLOUT) ||
- (pfd.revents & (POLLHUP|POLLERR))) {
- return false;
- }
-#endif
- DumpProcSelfMaps(child_in[1]); // what pprof expects on stdin
- char pcstr[64]; // enough for a single address
- snprintf(pcstr, sizeof(pcstr), // pprof expects format to be 0xXXXXXX...
- "0x%" PRIxPTR "\n", reinterpret_cast<uintptr_t>(pc));
- write(child_in[1], pcstr, strlen(pcstr));
- close(child_in[1]); // that's all we need to write
- int total_bytes_read = 0;
- while (1) {
- int bytes_read = read(child_out[1], out + total_bytes_read,
- out_size - total_bytes_read);
- if (bytes_read < 0) {
- close(child_out[1]);
- return false;
- } else if (bytes_read == 0) {
- close(child_out[1]);
- wait(NULL);
- break;
- } else {
- total_bytes_read += bytes_read;
- }
- }
- // We have successfully read the output of pprof into out. Make sure
- // we got the full symbol (we can tell because it ends with a \n).
- if (total_bytes_read == 0 || out[total_bytes_read - 1] != '\n')
- return false;
- out[total_bytes_read - 1] = '\0'; // remove the trailing newline
- return true;
- }
- }
- return false; // shouldn't be reachable
-#endif
-}
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/symbolize.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/symbolize.h 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/symbolize.h 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,38 +0,0 @@
-// 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.
-
-// ---
-// Author: Craig Silverstein
-
-#ifndef TCMALLOC_SYMBOLIZE_H_
-#define TCMALLOC_SYMBOLIZE_H_
-
-extern "C" bool Symbolize(void *pc, char *out, int out_size);
-
-#endif // TCMALLOC_SYMBOLIZE_H_
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sysinfo.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sysinfo.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sysinfo.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -37,6 +37,8 @@
#include <string.h> // for memmove(), memchr(), etc.
#include <fcntl.h> // for open()
#include <errno.h> // for errno
+#include <cassert>
+
#ifdef HAVE_UNISTD_H
#include <unistd.h> // for read()
#endif
@@ -56,7 +58,6 @@
#endif
#include "sysinfo.h"
#include "commandlineflags.h"
-#include "logging.h"
#include "cycleclock.h"
#ifdef PLATFORM_WINDOWS
@@ -110,8 +111,8 @@
// 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);
+// 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);
}
@@ -825,23 +826,4 @@
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
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sysinfo.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sysinfo.h 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sysinfo.h 2009-10-14 18:14:29 UTC (rev 3476)
@@ -46,7 +46,6 @@
#include <stddef.h> // for size_t
#include <limits.h> // for PATH_MAX
#include "basictypes.h"
-#include "logging.h" // for RawFD
// This getenv function is safe to call before the C runtime is initialized.
// On Windows, it utilizes GetEnvironmentVariable() and on unix it uses
@@ -223,7 +222,6 @@
namespace tcmalloc {
int FillProcSelfMaps(char buf[], int size);
-void DumpProcSelfMaps(RawFD fd);
}
#endif /* #ifndef _SYSINFO_H_ */
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/system-alloc.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/system-alloc.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/system-alloc.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -48,7 +48,6 @@
#include <errno.h>
#include "system-alloc.h"
#include "internal_logging.h"
-#include "logging.h"
#include "commandlineflags.h"
#include "spinlock.h"
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/tcmalloc.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/tcmalloc.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/tcmalloc.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -121,7 +121,6 @@
#include "central_freelist.h"
#include "internal_logging.h"
#include "linked_list.h"
-#include "maybe_threads.h"
#include "page_heap.h"
#include "page_heap_allocator.h"
#include "pagemap.h"
@@ -152,32 +151,7 @@
DECLARE_int64(tcmalloc_sample_parameter);
DECLARE_double(tcmalloc_release_rate);
-// For windows, the printf we use to report large allocs is
-// potentially dangerous: it could cause a malloc that would cause an
-// infinite loop. So by default we set the threshold to a huge number
-// on windows, so this bad situation will never trigger. You can
-// always set TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD manually if you
-// want this functionality.
-#ifdef _WIN32
-const int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 62;
-#else
-const int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 30;
-#endif
-DEFINE_int64(tcmalloc_large_alloc_report_threshold,
- EnvToInt64("TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD",
- kDefaultLargeAllocReportThreshold),
- "Allocations larger than this value cause a stack "
- "trace to be dumped to stderr. The threshold for "
- "dumping stack traces is increased by a factor of 1.125 "
- "every time we print a message so that the threshold "
- "automatically goes up by a factor of ~1000 every 60 "
- "messages. This bounds the amount of extra logging "
- "generated by this flag. Default value of this flag "
- "is very large and therefore you should see no extra "
- "logging unless the flag is overridden. Set to 0 to "
- "disable reporting entirely.");
-
// Override the libc functions to prefer our own instead. This comes
// first so code in tcmalloc.cc can use the overridden versions. One
// exception: in windows, by default, we patch our code into these
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -36,7 +36,6 @@
#endif
#include <algorithm> // for min and max
#include "thread_cache.h"
-#include "maybe_threads.h"
using std::min;
using std::max;
@@ -310,7 +309,7 @@
void ThreadCache::InitTSD() {
ASSERT(!tsd_inited_);
- perftools_pthread_key_create(&heap_key_, DestroyThreadCache);
+ pthread_key_create(&heap_key_, DestroyThreadCache);
tsd_inited_ = true;
// We may have used a fake pthread_t for the main thread. Fix it.
@@ -357,7 +356,7 @@
// pthread_setspecific() if we are already inside pthread_setspecific().
if (!heap->in_setspecific_ && tsd_inited_) {
heap->in_setspecific_ = true;
- perftools_pthread_setspecific(heap_key_, heap);
+ pthread_setspecific(heap_key_, heap);
#ifdef HAVE_TLS
// Also keep a copy in __thread for faster retrieval
threadlocal_heap_ = heap;
@@ -392,7 +391,7 @@
if (heap->in_setspecific_) return; // Do not disturb the active caller
heap->in_setspecific_ = true;
- perftools_pthread_setspecific(heap_key_, NULL);
+ pthread_setspecific(heap_key_, NULL);
#ifdef HAVE_TLS
// Also update the copy in __thread
threadlocal_heap_ = NULL;
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.h 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.h 2009-10-14 18:14:29 UTC (rev 3476)
@@ -39,7 +39,6 @@
#endif
#include "common.h"
#include "linked_list.h"
-#include "maybe_threads.h"
#include "page_heap_allocator.h"
#include "static_vars.h"
@@ -356,7 +355,7 @@
return threadlocal_heap_;
#endif
return reinterpret_cast<ThreadCache *>(
- perftools_pthread_getspecific(heap_key_));
+ pthread_getspecific(heap_key_));
}
inline ThreadCache* ThreadCache::GetCache() {
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/vdso_support.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/vdso_support.cc 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/vdso_support.cc 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,560 +0,0 @@
-// Copyright (c) 2008, 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: Paul Pluzhnikov
-//
-// Allow dynamic symbol lookup in the kernel VDSO page.
-//
-// VDSOSupport -- a class representing kernel VDSO (if present).
-//
-
-#include "vdso_support.h"
-
-#ifdef HAVE_VDSO_SUPPORT // defined in vdso_support.h
-
-#include <fcntl.h>
-
-#include "atomicops.h" // for MemoryBarrier
-#include "logging.h"
-#include "linux_syscall_support.h"
-#include "dynamic_annotations.h"
-#include "basictypes.h" // for COMPILE_ASSERT
-
-using base::subtle::MemoryBarrier;
-
-#ifndef AT_SYSINFO_EHDR
-#define AT_SYSINFO_EHDR 33
-#endif
-
-// From binutils/include/elf/common.h (this doesn't appear to be documented
-// anywhere else).
-//
-// /* This flag appears in a Versym structure. It means that the symbol
-// is hidden, and is only visible with an explicit version number.
-// This is a GNU extension. */
-// #define VERSYM_HIDDEN 0x8000
-//
-// /* This is the mask for the rest of the Versym information. */
-// #define VERSYM_VERSION 0x7fff
-
-#define VERSYM_VERSION 0x7fff
-
-namespace base {
-
-namespace {
-template <int N> class ElfClass {
- public:
- static const int kElfClass = -1;
- static int ElfBind(const ElfW(Sym) *) {
- CHECK(false); // << "Unexpected word size";
- return 0;
- }
- static int ElfType(const ElfW(Sym) *) {
- CHECK(false); // << "Unexpected word size";
- return 0;
- }
-};
-
-template <> class ElfClass<32> {
- public:
- static const int kElfClass = ELFCLASS32;
- static int ElfBind(const ElfW(Sym) *symbol) {
- return ELF32_ST_BIND(symbol->st_info);
- }
- static int ElfType(const ElfW(Sym) *symbol) {
- return ELF32_ST_TYPE(symbol->st_info);
- }
-};
-
-template <> class ElfClass<64> {
- public:
- static const int kElfClass = ELFCLASS64;
- static int ElfBind(const ElfW(Sym) *symbol) {
- return ELF64_ST_BIND(symbol->st_info);
- }
- static int ElfType(const ElfW(Sym) *symbol) {
- return ELF64_ST_TYPE(symbol->st_info);
- }
-};
-
-typedef ElfClass<__WORDSIZE> CurrentElfClass;
-
-// Extract an element from one of the ELF tables, cast it to desired type.
-// This is just a simple arithmetic and a glorified cast.
-// Callers are responsible for bounds checking.
-template <class T>
-const T* GetTableElement(const ElfW(Ehdr) *ehdr,
- ElfW(Off) table_offset,
- ElfW(Word) element_size,
- size_t index) {
- return reinterpret_cast<const T*>(reinterpret_cast<const char *>(ehdr)
- + table_offset
- + index * element_size);
-}
-} // namespace
-
-const void *const VDSOSupport::kInvalidBase =
- reinterpret_cast<const void *>(~0L);
-
-const void *VDSOSupport::vdso_base_ = kInvalidBase;
-VDSOSupport::GetCpuFn VDSOSupport::getcpu_fn_ = &InitAndGetCPU;
-
-VDSOSupport::ElfMemImage::ElfMemImage(const void *base) {
- CHECK(base != kInvalidBase);
- Init(base);
-}
-
-int VDSOSupport::ElfMemImage::GetNumSymbols() const {
- if (!hash_) {
- return 0;
- }
- // See http://www.caldera.com/developers/gabi/latest/ch5.dynamic.html#hash
- return hash_[1];
-}
-
-const ElfW(Sym) *VDSOSupport::ElfMemImage::GetDynsym(int index) const {
- CHECK_LT(index, GetNumSymbols());
- return dynsym_ + index;
-}
-
-const ElfW(Versym) *VDSOSupport::ElfMemImage::GetVersym(int index) const {
- CHECK_LT(index, GetNumSymbols());
- return versym_ + index;
-}
-
-const ElfW(Phdr) *VDSOSupport::ElfMemImage::GetPhdr(int index) const {
- CHECK_LT(index, ehdr_->e_phnum);
- return GetTableElement<ElfW(Phdr)>(ehdr_,
- ehdr_->e_phoff,
- ehdr_->e_phentsize,
- index);
-}
-
-const char *VDSOSupport::ElfMemImage::GetDynstr(ElfW(Word) offset) const {
- CHECK_LT(offset, strsize_);
- return dynstr_ + offset;
-}
-
-const void *VDSOSupport::ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const {
- if (sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE) {
- // Symbol corresponds to "special" (e.g. SHN_ABS) section.
- return reinterpret_cast<const void *>(sym->st_value);
- }
- CHECK_LT(link_base_, sym->st_value);
- return GetTableElement<char>(ehdr_, 0, 1, sym->st_value) - link_base_;
-}
-
-const ElfW(Verdef) *VDSOSupport::ElfMemImage::GetVerdef(int index) const {
- CHECK_LE(index, verdefnum_);
- const ElfW(Verdef) *version_definition = verdef_;
- while (version_definition->vd_ndx < index && version_definition->vd_next) {
- const char *const version_definition_as_char =
- reinterpret_cast<const char *>(version_definition);
- version_definition =
- reinterpret_cast<const ElfW(Verdef) *>(version_definition_as_char +
- version_definition->vd_next);
- }
- return version_definition->vd_ndx == index ? version_definition : NULL;
-}
-
-const ElfW(Verdaux) *VDSOSupport::ElfMemImage::GetVerdefAux(
- const ElfW(Verdef) *verdef) const {
- return reinterpret_cast<const ElfW(Verdaux) *>(verdef+1);
-}
-
-const char *VDSOSupport::ElfMemImage::GetVerstr(ElfW(Word) offset) const {
- CHECK_LT(offset, strsize_);
- return dynstr_ + offset;
-}
-
-void VDSOSupport::ElfMemImage::Init(const void *base) {
- ehdr_ = NULL;
- dynsym_ = NULL;
- dynstr_ = NULL;
- versym_ = NULL;
- verdef_ = NULL;
- hash_ = NULL;
- strsize_ = 0;
- verdefnum_ = 0;
- link_base_ = ~0L; // Sentinel: PT_LOAD .p_vaddr can't possibly be this.
- if (!base) {
- return;
- }
- const char *const base_as_char = reinterpret_cast<const char *>(base);
- if (base_as_char[EI_MAG0] != ELFMAG0 || base_as_char[EI_MAG1] != ELFMAG1 ||
- base_as_char[EI_MAG2] != ELFMAG2 || base_as_char[EI_MAG3] != ELFMAG3) {
- RAW_DCHECK(false, "no ELF magic"); // at %p", base);
- return;
- }
- int elf_class = base_as_char[EI_CLASS];
- if (elf_class != CurrentElfClass::kElfClass) {
- DCHECK_EQ(elf_class, CurrentElfClass::kElfClass);
- return;
- }
- switch (base_as_char[EI_DATA]) {
- case ELFDATA2LSB: {
- if (__LITTLE_ENDIAN != __BYTE_ORDER) {
- DCHECK_EQ(__LITTLE_ENDIAN, __BYTE_ORDER); // << ": wrong byte order";
- return;
- }
- break;
- }
- case ELFDATA2MSB: {
- if (__BIG_ENDIAN != __BYTE_ORDER) {
- DCHECK_EQ(__BIG_ENDIAN, __BYTE_ORDER); // << ": wrong byte order";
- return;
- }
- break;
- }
- default: {
- RAW_DCHECK(false, "unexpected data encoding"); // << base_as_char[EI_DATA];
- return;
- }
- }
-
- ehdr_ = reinterpret_cast<const ElfW(Ehdr) *>(base);
- const ElfW(Phdr) *dynamic_program_header = NULL;
- for (int i = 0; i < ehdr_->e_phnum; ++i) {
- const ElfW(Phdr) *const program_header = GetPhdr(i);
- switch (program_header->p_type) {
- case PT_LOAD:
- if (link_base_ == ~0L) {
- link_base_ = program_header->p_vaddr;
- }
- break;
- case PT_DYNAMIC:
- dynamic_program_header = program_header;
- break;
- }
- }
- if (link_base_ == ~0L || !dynamic_program_header) {
- RAW_DCHECK(~0L != link_base_, "no PT_LOADs in VDSO");
- RAW_DCHECK(dynamic_program_header, "no PT_DYNAMIC in VDSO");
- // Mark this image as not present. Can not recur infinitely.
- Init(0);
- return;
- }
- ptrdiff_t relocation =
- base_as_char - reinterpret_cast<const char *>(link_base_);
- ElfW(Dyn) *dynamic_entry =
- reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr +
- relocation);
- for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) {
- ElfW(Xword) value = dynamic_entry->d_un.d_val;
- if (link_base_ == 0) {
- // A complication: in the real VDSO, dynamic entries are not relocated
- // (it wasn't loaded by a dynamic loader). But when testing with a
- // "fake" dlopen()ed vdso library, the loader relocates some (but
- // not all!) of them before we get here.
- // Since real VDSO is never linked at address 0, and "fake" vdso
- // library always is, we know we are dealing with the "fake" one here.
- if (dynamic_entry->d_tag == DT_VERDEF) {
- // The only dynamic entry (of the ones we care about) libc-2.3.6
- // loader doesn't relocate.
- value += relocation;
- }
- } else {
- // Real VDSO. Everything needs to be relocated.
- value += relocation;
- }
- switch (dynamic_entry->d_tag) {
- case DT_HASH:
- hash_ = reinterpret_cast<ElfW(Word) *>(value);
- break;
- case DT_SYMTAB:
- dynsym_ = reinterpret_cast<ElfW(Sym) *>(value);
- break;
- case DT_STRTAB:
- dynstr_ = reinterpret_cast<const char *>(value);
- break;
- case DT_VERSYM:
- versym_ = reinterpret_cast<ElfW(Versym) *>(value);
- break;
- case DT_VERDEF:
- verdef_ = reinterpret_cast<ElfW(Verdef) *>(value);
- break;
- case DT_VERDEFNUM:
- verdefnum_ = dynamic_entry->d_un.d_val;
- break;
- case DT_STRSZ:
- strsize_ = dynamic_entry->d_un.d_val;
- break;
- default:
- // Unrecognized entries explicitly ignored.
- break;
- }
- }
- if (!hash_ || !dynsym_ || !dynstr_ || !versym_ ||
- !verdef_ || !verdefnum_ || !strsize_) {
- RAW_DCHECK(hash_, "invalid VDSO (no DT_HASH)");
- RAW_DCHECK(dynsym_, "invalid VDSO (no DT_SYMTAB)");
- RAW_DCHECK(dynstr_, "invalid VDSO (no DT_STRTAB)");
- RAW_DCHECK(versym_, "invalid VDSO (no DT_VERSYM)");
- RAW_DCHECK(verdef_, "invalid VDSO (no DT_VERDEF)");
- RAW_DCHECK(verdefnum_, "invalid VDSO (no DT_VERDEFNUM)");
- RAW_DCHECK(strsize_, "invalid VDSO (no DT_STRSZ)");
- // Mark this image as not present. Can not recur infinitely.
- Init(0);
- return;
- }
-}
-
-VDSOSupport::VDSOSupport()
- // If vdso_base_ is still set to kInvalidBase, we got here
- // before VDSOSupport::Init has been called. Call it now.
- : image_(vdso_base_ == kInvalidBase ? Init() : vdso_base_) {
-}
-
-// NOTE: we can't use GoogleOnceInit() below, because we can be
-// called by tcmalloc, and none of the *once* stuff may be functional yet.
-//
-// In addition, we hope that the VDSOSupportHelper constructor
-// causes this code to run before there are any threads, and before
-// InitGoogle() has executed any chroot or setuid calls.
-//
-// Finally, even if there is a race here, it is harmless, because
-// the operation should be idempotent.
-const void *VDSOSupport::Init() {
- if (vdso_base_ == kInvalidBase) {
- // Valgrind zaps AT_SYSINFO_EHDR and friends from the auxv[]
- // on stack, and so glibc works as if VDSO was not present.
- // But going directly to kernel via /proc/self/auxv below bypasses
- // Valgrind zapping. So we check for Valgrind separately.
- if (RunningOnValgrind()) {
- vdso_base_ = NULL;
- getcpu_fn_ = &GetCPUViaSyscall;
- return NULL;
- }
- int fd = open("/proc/self/auxv", O_RDONLY);
- if (fd == -1) {
- // Kernel too old to have a VDSO.
- vdso_base_ = NULL;
- getcpu_fn_ = &GetCPUViaSyscall;
- return NULL;
- }
- ElfW(auxv_t) aux;
- while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) {
- if (aux.a_type == AT_SYSINFO_EHDR) {
- COMPILE_ASSERT(sizeof(vdso_base_) == sizeof(aux.a_un.a_val),
- unexpected_sizeof_pointer_NE_sizeof_a_val);
- vdso_base_ = reinterpret_cast<void *>(aux.a_un.a_val);
- break;
- }
- }
- close(fd);
- if (vdso_base_ == kInvalidBase) {
- // Didn't find AT_SYSINFO_EHDR in auxv[].
- vdso_base_ = NULL;
- }
- }
- GetCpuFn fn = &GetCPUViaSyscall; // default if VDSO not present.
- if (vdso_base_) {
- VDSOSupport vdso;
- SymbolInfo info;
- if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) {
- // Casting from an int to a pointer is not legal C++. To emphasize
- // this, we use a C-style cast rather than a C++-style cast.
- fn = (GetCpuFn)(info.address);
- }
- }
- // Subtle: this code runs outside of any locks; prevent compiler
- // from assigning to getcpu_fn_ more than once.
- MemoryBarrier();
- getcpu_fn_ = fn;
- return vdso_base_;
-}
-
-const void *VDSOSupport::SetBase(const void *base) {
- const void *old_base = vdso_base_;
- vdso_base_ = base;
- image_.Init(base);
- // Also reset getcpu_fn_, so GetCPU could be tested with simulated VDSO.
- getcpu_fn_ = &InitAndGetCPU;
- return old_base;
-}
-
-bool VDSOSupport::LookupSymbol(const char *name,
- const char *version,
- int type,
- SymbolInfo *info) const {
- for (SymbolIterator it = begin(); it != end(); ++it) {
- if (strcmp(it->name, name) == 0 && strcmp(it->version, version) == 0 &&
- CurrentElfClass::ElfType(it->symbol) == type) {
- if (info) {
- *info = *it;
- }
- return true;
- }
- }
- return false;
-}
-
-bool VDSOSupport::LookupSymbolByAddress(const void *address,
- SymbolInfo *info_out) const {
- for (SymbolIterator it = begin(); it != end(); ++it) {
- const char *const symbol_start =
- reinterpret_cast<const char *>(it->address);
- const char *const symbol_end = symbol_start + it->symbol->st_size;
- if (symbol_start <= address && address < symbol_end) {
- if (info_out) {
- // Client wants to know details for that symbol (the usual case).
- if (CurrentElfClass::ElfBind(it->symbol) == STB_GLOBAL) {
- // Strong symbol; just return it.
- *info_out = *it;
- return true;
- } else {
- // Weak or local. Record it, but keep looking for a strong one.
- *info_out = *it;
- }
- } else {
- // Client only cares if there is an overlapping symbol.
- return true;
- }
- }
- }
- return false;
-}
-
-VDSOSupport::SymbolIterator::SymbolIterator(const void *const image, int index)
- : index_(index), image_(image) {
-}
-
-const VDSOSupport::SymbolInfo *VDSOSupport::SymbolIterator::operator->() const {
- return &info_;
-}
-
-const VDSOSupport::SymbolInfo& VDSOSupport::SymbolIterator::operator*() const {
- return info_;
-}
-
-bool VDSOSupport::SymbolIterator::operator==(const SymbolIterator &rhs) const {
- return this->image_ == rhs.image_ && this->index_ == rhs.index_;
-}
-
-bool VDSOSupport::SymbolIterator::operator!=(const SymbolIterator &rhs) const {
- return !(*this == rhs);
-}
-
-VDSOSupport::SymbolIterator &VDSOSupport::SymbolIterator::operator++() {
- this->Update(1);
- return *this;
-}
-
-VDSOSupport::SymbolIterator VDSOSupport::begin() const {
- SymbolIterator it(&image_, 0);
- it.Update(0);
- return it;
-}
-
-VDSOSupport::SymbolIterator VDSOSupport::end() const {
- return SymbolIterator(&image_, image_.GetNumSymbols());
-}
-
-void VDSOSupport::SymbolIterator::Update(int increment) {
- const ElfMemImage *image = reinterpret_cast<const ElfMemImage *>(image_);
- CHECK(image->IsPresent() || increment == 0);
- if (!image->IsPresent()) {
- return;
- }
- index_ += increment;
- if (index_ >= image->GetNumSymbols()) {
- index_ = image->GetNumSymbols();
- return;
- }
- const ElfW(Sym) *symbol = image->GetDynsym(index_);
- const ElfW(Versym) *version_symbol = image->GetVersym(index_);
- CHECK(symbol && version_symbol);
- const char *const symbol_name = image->GetDynstr(symbol->st_name);
- const ElfW(Versym) version_index = version_symbol[0] & VERSYM_VERSION;
- const ElfW(Verdef) *version_definition = NULL;
- const char *version_name = "";
- if (symbol->st_shndx == SHN_UNDEF) {
- // Undefined symbols reference DT_VERNEED, not DT_VERDEF, and
- // version_index could well be greater than verdefnum_, so calling
- // GetVerdef(version_index) may trigger assertion.
- } else {
- version_definition = image->GetVerdef(version_index);
- }
- if (version_definition) {
- // I am expecting 1 or 2 auxiliary entries: 1 for the version itself,
- // optional 2nd if the version has a parent.
- CHECK_LE(1, version_definition->vd_cnt);
- CHECK_LE(version_definition->vd_cnt, 2);
- const ElfW(Verdaux) *version_aux = image->GetVerdefAux(version_definition);
- version_name = image->GetVerstr(version_aux->vda_name);
- }
- info_.name = symbol_name;
- info_.version = version_name;
- info_.address = image->GetSymAddr(symbol);
- info_.symbol = symbol;
-}
-
-// NOLINT on 'long' because this routine mimics kernel api.
-long VDSOSupport::GetCPUViaSyscall(unsigned *cpu, void *, void *) { // NOLINT
-#if defined(__NR_getcpu)
- return sys_getcpu(cpu, NULL, NULL);
-#else
- // x86_64 never implemented sys_getcpu(), except as a VDSO call.
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-// Use fast __vdso_getcpu if available.
-long VDSOSupport::InitAndGetCPU(unsigned *cpu, void *x, void *y) { // NOLINT
- Init();
- CHECK_NE(getcpu_fn_, &InitAndGetCPU); // << "Init() did not set getcpu_fn_";
- return (*getcpu_fn_)(cpu, x, y);
-}
-
-// This function must be very fast, and may be called from very
-// low level (e.g. tcmalloc). Hence I avoid things like
-// GoogleOnceInit() and ::operator new.
-int GetCPU(void) {
- unsigned cpu;
- int ret_code = (*VDSOSupport::getcpu_fn_)(&cpu, NULL, NULL);
- return ret_code == 0 ? cpu : ret_code;
-}
-
-// We need to make sure VDSOSupport::Init() is called before
-// the main() runs, since it might do something like setuid or
-// chroot. If VDSOSupport
-// is used in any global constructor, this will happen, since
-// VDSOSupport's constructor calls Init. But if not, we need to
-// ensure it here, with a global constructor of our own. This
-// is an allowed exception to the normal rule against non-trivial
-// global constructors.
-static class VDSOInitHelper {
- public:
- VDSOInitHelper() { VDSOSupport::Init(); }
-} vdso_init_helper;
-}
-
-#endif // HAVE_VDSO_SUPPORT
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/vdso_support.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/vdso_support.h 2009-10-14 17:30:34 UTC (rev 3475)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/vdso_support.h 2009-10-14 18:14:29 UTC (rev 3476)
@@ -1,182 +0,0 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
-// Author: ppluzhnikov at google.com (Paul Pluzhnikov)
-//
-// Allow dynamic symbol lookup in the kernel VDSO page.
-//
-// VDSO stands for "Virtual Dynamic Shared Object" -- a page of
-// executable code, which looks like a shared library, but doesn't
-// necessarily exist anywhere on disk, and which gets mmap()ed into
-// every process by kernels which support VDSO, such as 2.6.x for 32-bit
-// executables, and 2.6.24 and above for 64-bit executables.
-//
-// More details could be found here:
-// http://www.trilithium.com/johan/2005/08/linux-gate/
-//
-// VDSOSupport -- a class representing kernel VDSO (if present).
-//
-// Example usage:
-// VDSOSupport vdso;
-// VDSOSupport::SymbolInfo info;
-// typedef (*FN)(unsigned *, void *, void *);
-// FN fn = NULL;
-// if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) {
-// fn = reinterpret_cast<FN>(info.address);
-// }
-
-#ifndef BASE_VDSO_SUPPORT_H_
-#define BASE_VDSO_SUPPORT_H_
-
-#include "tcmalloc-platform.h"
-#ifdef HAVE_FEATURES_H
-#include <features.h> // for __GLIBC__
-#endif
-
-// Maybe one day we can rewrite this file not to require the elf
-// symbol extensions in glibc, but for right now we need them.
-#if defined(__ELF__) && defined(__GLIBC__)
-
-#define HAVE_VDSO_SUPPORT 1
-
-#include <stdlib.h> // for NULL
-#include <link.h> // for ElfW
-#include "basictypes.h"
-
-namespace base {
-
-// NOTE: this class may be used from within tcmalloc, and can not
-// use any memory allocation routines.
-class VDSOSupport {
- public:
- // Sentinel: there could never be a VDSO at this address.
- static const void *const kInvalidBase;
-
- // Information about a single vdso symbol.
- // All pointers are into .dynsym, .dynstr, or .text of the VDSO.
- // Do not free() them or modify through them.
- struct SymbolInfo {
- const char *name; // E.g. "__vdso_getcpu"
- const char *version; // E.g. "LINUX_2.6", could be ""
- // for unversioned symbol.
- const void *address; // Relocated symbol address.
- const ElfW(Sym) *symbol; // Symbol in the dynamic symbol table.
- };
-
- // Supports iteration over all dynamic symbols.
- class SymbolIterator {
- public:
- friend struct VDSOSupport;
- const SymbolInfo *operator->() const;
- const SymbolInfo &operator*() const;
- SymbolIterator& operator++();
- bool operator!=(const SymbolIterator &rhs) const;
- bool operator==(const SymbolIterator &rhs) const;
- private:
- SymbolIterator(const void *const image, int index);
- void Update(int incr);
- SymbolInfo info_;
- int index_;
- const void *const image_;
- };
-
- VDSOSupport();
-
- // Answers whether we have a vdso at all.
- bool IsPresent() const { return image_.IsPresent(); }
-
- // Allow to iterate over all VDSO symbols.
- SymbolIterator begin() const;
- SymbolIterator end() const;
-
- // Look up versioned dynamic symbol in the kernel VDSO.
- // Returns false if VDSO is not present, or doesn't contain given
- // symbol/version/type combination.
- // If info_out != NULL, additional details are filled in.
- bool LookupSymbol(const char *name, const char *version,
- int symbol_type, SymbolInfo *info_out) const;
-
- // Find info about symbol (if any) which overlaps given address.
- // Returns true if symbol was found; false if VDSO isn't present
- // or doesn't have a symbol overlapping given address.
- // If info_out != NULL, additional details are filled in.
- bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const;
-
- // Used only for testing. Replace real VDSO base with a mock.
- // Returns previous value of vdso_base_. After you are done testing,
- // you are expected to call SetBase() with previous value, in order to
- // reset state to the way it was.
- const void *SetBase(const void *s);
-
- // Computes vdso_base_ and returns it. Should be called as early as
- // possible; before any thread creation, chroot or setuid.
- static const void *Init();
-
- private:
- // An in-memory ELF image (may not exist on disk).
- class ElfMemImage {
- public:
- explicit ElfMemImage(const void *base);
- void Init(const void *base);
- bool IsPresent() const { return ehdr_ != NULL; }
- const ElfW(Phdr)* GetPhdr(int index) const;
- const ElfW(Sym)* GetDynsym(int index) const;
- const ElfW(Versym)* GetVersym(int index) const;
- const ElfW(Verdef)* GetVerdef(int index) const;
- const ElfW(Verdaux)* GetVerdefAux(const ElfW(Verdef) *verdef) const;
- const char* GetDynstr(ElfW(Word) offset) const;
- const void* GetSymAddr(const ElfW(Sym) *sym) const;
- const char* GetVerstr(ElfW(Word) offset) const;
- int GetNumSymbols() const;
- private:
- const ElfW(Ehdr) *ehdr_;
- const ElfW(Sym) *dynsym_;
- const ElfW(Versym) *versym_;
- const ElfW(Verdef) *verdef_;
- const ElfW(Word) *hash_;
- const char *dynstr_;
- size_t strsize_;
- size_t verdefnum_;
- ElfW(Addr) link_base_; // Link-time base (p_vaddr of first PT_LOAD).
- };
-
- // image_ represents VDSO ELF image in memory.
- // image_.ehdr_ == NULL implies there is no VDSO.
- ElfMemImage image_;
-
- // Cached value of auxv AT_SYSINFO_EHDR, computed once.
- // This is a tri-state:
- // kInvalidBase => value hasn't been determined yet.
- // 0 => there is no VDSO.
- // else => vma of VDSO Elf{32,64}_Ehdr.
- static const void *vdso_base_;
-
- // NOLINT on 'long' because these routines mimic kernel api.
- // The 'cache' parameter may be used by some versions of the kernel,
- // and should be NULL or point to a static buffer containing at
- // least two 'long's.
- static long InitAndGetCPU(unsigned *cpu, void *cache, // NOLINT 'long'.
- void *unused);
- static long GetCPUViaSyscall(unsigned *cpu, void *cache, // NOLINT 'long'.
- void *unused);
- typedef long (*GetCpuFn)(unsigned *cpu, void *cache, // NOLINT 'long'.
- void *unused);
-
- // This function pointer may point to InitAndGetCPU,
- // GetCPUViaSyscall, or __vdso_getcpu at different stages of initialization.
- static GetCpuFn getcpu_fn_;
-
- friend int GetCPU(void); // Needs access to getcpu_fn_.
-
- DISALLOW_COPY_AND_ASSIGN(VDSOSupport);
-};
-
-// Same as sched_getcpu() on later glibc versions.
-// Return current CPU, using (fast) __vdso_getcpu at LINUX_2.6 if present,
-// otherwise use syscall(SYS_getcpu,...).
-// May return -1 with errno == ENOSYS if the kernel doesn't
-// support SYS_getcpu.
-int GetCPU();
-} // namespace base
-
-#endif // __ELF__ and __GLIBC__
-
-#endif // BASE_VDSO_SUPPORT_H_
More information about the Avida-cvs
mailing list