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:
Chris Cambly 2021-05-14 11:11:48 -04:00 committed by Aliaksey Kandratsenka
parent 26927d1333
commit 2d70ea9ad2
9 changed files with 144 additions and 6 deletions

61
INSTALL
View File

@ -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
==================

View File

@ -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 \

View File

@ -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
View 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_

View File

@ -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

View File

@ -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;

View File

@ -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));

View File

@ -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).
//

View File

@ -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