mirror of
https://github.com/gperftools/gperftools
synced 2025-01-02 12:42:04 +00:00
initial batch of changes to enable AIX in 32-bit and 64-bit
- Some small automake changes. Add libc++ for AIX instead of libstdc++ - Add the interface changes for AIX:User-defined malloc replacement - Add code to avoid use of pthreads library prior to its initialization - Some small changes to the unittest case - Update INSTALL for AIX [alkondratenko@gmail.com]: lower-case/de-trailing-dot for commit subject line [alkondratenko@gmail.com]: rebase [alkondratenko@gmail.com]: amputate unused AM_CONDITIONAL for AIX [alkondratenko@gmail.com]: explicitly mention libc_override_aix.h in Makefile.am
This commit is contained in:
parent
26927d1333
commit
2d70ea9ad2
61
INSTALL
61
INSTALL
@ -339,6 +339,67 @@ above, by linking in libtcmalloc_minimal.
|
||||
process. 'make install' should also work. The Makefile will limit
|
||||
itself to those libraries and binaries that work on windows.
|
||||
|
||||
** AIX
|
||||
|
||||
I've tested using the IBM XL and IBM Open XL Compilers. The
|
||||
minimum requirement for IBM XL is V16 which includes C++11
|
||||
support. IBM XL and gcc are not ABI compatible. If you would
|
||||
like to use the library with a gcc built executable then the
|
||||
library must also be built with gcc. To use the library with
|
||||
and IBM XL built binary then it follows that the library must
|
||||
also be built with IBM XL.
|
||||
|
||||
Both 32-bit and 64-bit builds have been tested.
|
||||
|
||||
To do a 32-bit IBM XL build:
|
||||
% ./configure CC="xlclang" CXX="xlclang++" AR="ar"
|
||||
RANLIB="ranlib" NM="nm"
|
||||
To do a 64-bit IBM XL build:
|
||||
% ./configure CC="xlclang -q64" CXX="xlclang++ -q64"
|
||||
AR="ar -X64" RANLIB="ranlib -X64" NM="nm -X64"
|
||||
|
||||
Add your favorite optimization levels via CFLAGS and CXXFLAGS.
|
||||
|
||||
If you link to the shared library but it may not work as you
|
||||
expect. Allocations and deallocations that occur from within
|
||||
the Standard C and C++ libraries will not be redirected the
|
||||
tcmalloc library.
|
||||
|
||||
The recommended method is to use the AIX User-defined malloc
|
||||
replacement as documented by IBM. This replaces the default
|
||||
AIX memory subsystem with a user defined memory subsystem.
|
||||
|
||||
The AIX user defined memory subsystem specifies that the 32-
|
||||
and 64- bit objects must be placed in an archive with the
|
||||
32-bit shared object named mem32.o and the 64-bit shared
|
||||
object named mem64.o.
|
||||
|
||||
It is recommended to make combined 32_64 bit archive by
|
||||
doing a 64-bit build, then copy the shared library to mem64.o
|
||||
add mem64.o the archive, then do a 32-bit build
|
||||
copy the shared library to mem32.o and add it to the same
|
||||
combined archive.
|
||||
|
||||
For eg) perform a 64-bit build then:
|
||||
% cp libtcmalloc_minimal.so.4 mem64.o
|
||||
% ar -X32_64 -r libtmalloc_minimal.a mem64.o
|
||||
|
||||
Followed by a 32-bit build:
|
||||
% cp libtcmalloc_minimal.so.4 mem32.o
|
||||
% ar -X32_64 -r libtmalloc_minimal.a mem32.o
|
||||
|
||||
The final archive should contain both mem32.o and mem64.o
|
||||
|
||||
To use the library you are expected have the library location
|
||||
in your LIBPATH or LD_LIBRARY_PATH followed by exporting the
|
||||
environment variable MALLOCTYPE=user:libtcmalloc_minimal.a to
|
||||
enable the new user defined memory subsystem.
|
||||
|
||||
I recommend using:
|
||||
% MALLOCTYPE=user:libtcmalloc_minimal.a <user-exectuable>
|
||||
to minimize the impact of replacing the memory subsystem. Once
|
||||
the subsystem is replaced it is used for all commands issued from
|
||||
the terminal.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
@ -386,6 +386,7 @@ S_TCMALLOC_MINIMAL_INCLUDES = src/common.h \
|
||||
src/central_freelist.h \
|
||||
src/linked_list.h \
|
||||
src/libc_override.h \
|
||||
src/libc_override_aix.h \
|
||||
src/libc_override_gcc_and_weak.h \
|
||||
src/libc_override_glibc.h \
|
||||
src/libc_override_osx.h \
|
||||
|
@ -428,7 +428,6 @@ else
|
||||
AC_SUBST(ac_cv_have_std_align_val_t, 0)
|
||||
fi
|
||||
|
||||
|
||||
AC_CACHE_CHECK([if target has _Unwind_Backtrace],
|
||||
[perftools_cv_have_unwind_backtrace],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
@ -490,6 +489,8 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([#if defined(__GNUC__) && ((__GNUC__ < 4) || (__
|
||||
#error mingw doesnt really support tls
|
||||
#elif defined(__APPLE__)
|
||||
#error OSX __thread support is known to call malloc which makes it unsafe to use from malloc replacement
|
||||
#elif defined(_AIX)
|
||||
#error AIX thread support is known to call malloc which makes it unsafe to use from malloc replacement
|
||||
#endif
|
||||
], [static __thread int p = 0])],
|
||||
[AC_DEFINE(HAVE_TLS, 1,
|
||||
@ -594,7 +595,7 @@ AH_TOP([
|
||||
AH_VERBATIM([PTHREADS_CRASHES_IF_RUN_TOO_EARLY],
|
||||
[/* Mark the systems where we know it's bad if pthreads runs too
|
||||
early before main (before threads are initialized, presumably). */
|
||||
#ifdef __FreeBSD__
|
||||
#if defined(__FreeBSD__) || defined(_AIX)
|
||||
#define PTHREADS_CRASHES_IF_RUN_TOO_EARLY 1
|
||||
#endif])
|
||||
|
||||
|
59
src/libc_override_aix.h
Normal file
59
src/libc_override_aix.h
Normal file
@ -0,0 +1,59 @@
|
||||
// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
|
||||
// Copyright (c) 2021, IBM Ltd.
|
||||
// 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 Cambly <ccambly@ca.ibm.com>
|
||||
//
|
||||
// Used to override malloc routines on AIX
|
||||
|
||||
#ifndef TCMALLOC_LIBC_OVERRIDE_AIX_INL_H_
|
||||
#define TCMALLOC_LIBC_OVERRIDE_AIX_INL_H_
|
||||
|
||||
#ifndef _AIX
|
||||
# error libc_override_aix.h is for AIX systems only.
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
// AIX user-defined malloc replacement routines
|
||||
void* __malloc__(size_t size) __THROW ALIAS(tc_malloc);
|
||||
void __free__(void* ptr) __THROW ALIAS(tc_free);
|
||||
void* __realloc__(void* ptr, size_t size) __THROW ALIAS(tc_realloc);
|
||||
void* __calloc__(size_t n, size_t size) __THROW ALIAS(tc_calloc);
|
||||
int __posix_memalign__(void** r, size_t a, size_t s) __THROW ALIAS(tc_posix_memalign);
|
||||
int __mallopt__(int cmd, int value) __THROW ALIAS(tc_mallopt);
|
||||
#ifdef HAVE_STRUCT_MALLINFO
|
||||
struct mallinfo __mallinfo__(void) __THROW ALIAS(tc_mallinfo);
|
||||
#endif
|
||||
void __malloc_init__(void) { tc_free(tc_malloc(1));}
|
||||
void* __malloc_prefork_lock__(void) { /* nothing to lock */ }
|
||||
void* __malloc_postfork_unlock__(void) { /* nothing to unlock */}
|
||||
} // extern "C"
|
||||
|
||||
#endif // TCMALLOC_LIBC_OVERRIDE_AIX_INL_H_
|
@ -235,6 +235,11 @@ extern "C" {
|
||||
#endif
|
||||
} // extern "C"
|
||||
|
||||
/* AIX User-defined malloc replacement interface overrides */
|
||||
#if defined(_AIX)
|
||||
#include "libc_override_aix.h"
|
||||
#endif
|
||||
|
||||
#undef ALIAS
|
||||
|
||||
// No need to do anything at tcmalloc-registration time: we do it all
|
||||
|
@ -134,7 +134,7 @@ int perftools_pthread_setspecific(pthread_key_t key, void *val) {
|
||||
static pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT;
|
||||
int perftools_pthread_once(pthread_once_t *ctl,
|
||||
void (*init_routine) (void)) {
|
||||
#ifdef __FreeBSD__
|
||||
#if PTHREADS_CRASHES_IF_RUN_TOO_EARLY
|
||||
// On __FreeBSD__, calling pthread_once on a system that is not
|
||||
// linked with -pthread is silently a noop. :-( Luckily, we have a
|
||||
// workaround: FreeBSD exposes __isthreaded in <stdio.h>, which is
|
||||
@ -142,11 +142,17 @@ int perftools_pthread_once(pthread_once_t *ctl,
|
||||
// we can use our own separate pthreads-once mechanism, which is
|
||||
// used until __isthreaded is 1 (which will never be true if the app
|
||||
// is not linked with -pthread).
|
||||
// On AIX __n_pthreads is -1 until pthreads has been intialized
|
||||
static bool pthread_once_ran_before_threads = false;
|
||||
if (pthread_once_ran_before_threads) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
if (!__isthreaded) {
|
||||
#endif
|
||||
#ifdef _AIX
|
||||
if (__n_pthreads == -1) {
|
||||
#endif
|
||||
init_routine();
|
||||
pthread_once_ran_before_threads = true;
|
||||
return 0;
|
||||
|
@ -98,7 +98,7 @@ int GET_STACK_TRACE_OR_FRAMES {
|
||||
// different asm syntax. I don't know quite the best way to discriminate
|
||||
// systems using the old as from the new one; I've gone with __APPLE__.
|
||||
// TODO(csilvers): use autoconf instead, to look for 'as --version' == 1 or 2
|
||||
#ifdef __FreeBSD__
|
||||
#if defined(__FreeBSD__) || defined(_AIX)
|
||||
__asm__ volatile ("mr %0,1" : "=r" (sp));
|
||||
#else
|
||||
__asm__ volatile ("mr %0,r1" : "=r" (sp));
|
||||
|
@ -112,7 +112,8 @@ void Static::InitStaticVars() {
|
||||
|
||||
void Static::InitLateMaybeRecursive() {
|
||||
#if defined(HAVE_FORK) && defined(HAVE_PTHREAD) \
|
||||
&& !defined(__APPLE__) && !defined(TCMALLOC_NO_ATFORK)
|
||||
&& !defined(__APPLE__) && !defined(TCMALLOC_NO_ATFORK) \
|
||||
&& !defined(PTHREADS_CRASHES_IF_RUN_TOO_EARLY)
|
||||
// OSX has it's own way of handling atfork in malloc (see
|
||||
// libc_override_osx.h).
|
||||
//
|
||||
|
@ -1472,6 +1472,10 @@ static int RunAllTests(int argc, char** argv) {
|
||||
|
||||
#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
|
||||
|
||||
// On AIX user defined malloc replacement of libc routines
|
||||
// cannot be done at link time must be done a runtime via
|
||||
// environment variable MALLOCTYPE
|
||||
#if !defined(_AIX)
|
||||
// Try strdup(), which the system allocates but we must free. If
|
||||
// all goes well, libc will use our malloc!
|
||||
p2 = noopt(strdup("in memory of James Golick"));
|
||||
@ -1479,7 +1483,7 @@ static int RunAllTests(int argc, char** argv) {
|
||||
VerifyNewHookWasCalled();
|
||||
free(p2);
|
||||
VerifyDeleteHookWasCalled();
|
||||
|
||||
#endif
|
||||
|
||||
// Test mmap too: both anonymous mmap and mmap of a file
|
||||
// Note that for right now we only override mmap on linux
|
||||
|
Loading…
Reference in New Issue
Block a user