* Intercept both allocations and deallocations from ptmalloc2 (including
both mmap and munmap), adjusting the configure script so that the component will only be activated on systems that use ptmalloc2 in the first place -- ie, Linux * Remove the malloc_hooks component - it became an unworkable solution once threads and such were considered. * Remove malloc_interpose component - it never worked quite right and was not going to be able to intercept malloc, so it wasn't going to be useful for OMPI's purposes. * Update tests a little bit to match recent memory hooks api issues - still needs a bit of work. This commit was SVN r8381.
Этот коммит содержится в:
родитель
7998cca0f3
Коммит
f44bd9e067
@ -1,28 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
|
||||
|
||||
noinst_LTLIBRARIES = libmca_memory_malloc_hooks.la
|
||||
|
||||
# Source code files
|
||||
libmca_memory_malloc_hooks_la_SOURCES = \
|
||||
memory_malloc_hooks.c \
|
||||
memory_malloc_hooks_component.c
|
||||
libmca_memory_malloc_hooks_la_LIBADD = \
|
||||
$(memory_malloc_hooks_LIBS)
|
@ -1,89 +0,0 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AC_DEFUN([MCA_memory_malloc_hooks_COMPILE_MODE], [
|
||||
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
|
||||
$4="static"
|
||||
AC_MSG_RESULT([$$4])
|
||||
])
|
||||
|
||||
|
||||
# MCA_memory_malloc_hooks_CONFIG(action-if-can-compile,
|
||||
# [action-if-cant-compile])
|
||||
# ------------------------------------------------
|
||||
AC_DEFUN([MCA_memory_malloc_hooks_CONFIG],[
|
||||
AC_ARG_WITH([memory-manager],
|
||||
[AC_HELP_STRING([--with-memory-manager=TYPE],
|
||||
[Use TYPE for intercepting memory management
|
||||
calls to control memory pinning.])])
|
||||
|
||||
AS_IF([test "$with_memory_manager" = "malloc_hooks"],
|
||||
[memory_malloc_hooks_happy="yes"
|
||||
memory_malloc_hooks_should_use=1],
|
||||
[memory_malloc_hooks_should_use=0
|
||||
AS_IF([test "$with_memory_manager" = ""],
|
||||
[memory_malloc_hooks_happy="yes"],
|
||||
[memory_malloc_hooks_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_malloc_hooks_happy" = "yes"],
|
||||
[AS_IF([test "$enable_mpi_threads" = "yes" -o \
|
||||
"$enable_progress_threads" = "yes"],
|
||||
[memory_malloc_hooks_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_malloc_hooks_happy" = "yes"],
|
||||
[# check for malloc.h
|
||||
AC_CHECK_HEADER([malloc.h],
|
||||
[memory_malloc_hooks_happy="yes"],
|
||||
[memory_malloc_hooks_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_malloc_hooks_happy" = "yes"],
|
||||
[# check for init hook symbol
|
||||
AC_CHECK_DECL([__malloc_initialize_hook],
|
||||
[memory_malloc_hooks_happy="yes"],
|
||||
[memory_malloc_hooks_happy="no"],
|
||||
[AC_INCLUDES_DEFAULT
|
||||
#include <malloc.h>])])
|
||||
|
||||
AS_IF([test "$memory_malloc_hooks_happy" = "yes"],
|
||||
[# check for the chunk size function
|
||||
AC_CHECK_FUNC([malloc_usable_size],
|
||||
[memory_malloc_hooks_happy="yes"],
|
||||
[memory_malloc_hooks_happy="no"])])
|
||||
|
||||
memory_malloc_hooks_LIBS_SAVE="$LIBS"
|
||||
AS_IF([test "$memory_malloc_hooks_happy" = "yes"],
|
||||
[AC_CHECK_LIB([dl],
|
||||
[dlsym],
|
||||
[memory_malloc_hooks_happy="yes"],
|
||||
[memory_malloc_hooks_happy="no"])])
|
||||
LIBS="$memory_malloc_hooks_LIBS_SAVE"
|
||||
|
||||
AS_IF([test "$memory_malloc_hooks_happy" = "yes"],
|
||||
[memory_malloc_hooks_WRAPPER_EXTRA_LIBS="-ldl"
|
||||
memory_malloc_hooks_LIBS="-ldl"])
|
||||
|
||||
AS_IF([test "$memory_malloc_hooks_happy" = "no" -a \
|
||||
"$memory_malloc_hoooks_should_use" = "1"],
|
||||
[AC_MSG_ERROR([malloc hooks memory management requested but not available. Aborting.])])
|
||||
|
||||
AC_SUBST(memory_malloc_hooks_LIBS)
|
||||
|
||||
AS_IF([test "$memory_malloc_hooks_happy" = "yes"],
|
||||
[$1], [$2])
|
||||
])
|
@ -1,23 +0,0 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# Specific to this module
|
||||
|
||||
PARAM_CONFIG_PRIORITY=20
|
||||
PARAM_CONFIG_FILES="Makefile"
|
@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdio.h>
|
||||
#define __USE_GNU
|
||||
#include <dlfcn.h>
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "opal/memoryhooks/memory_internal.h"
|
||||
|
||||
/* Prototypes for our hooks. */
|
||||
void opal_memory_malloc_hooks_init(void);
|
||||
|
||||
static void local_free_hook(void*, const void*);
|
||||
static void* local_malloc_hook(size_t, const void*);
|
||||
static void* local_realloc_hook(void*, size_t, const void*);
|
||||
|
||||
/* Override initializing hook from the C library. */
|
||||
void (*__malloc_initialize_hook) (void) = opal_memory_malloc_hooks_init;
|
||||
|
||||
/* local variable - next in stack of free hooks */
|
||||
static void (*old_free_hook)(void*, const void*);
|
||||
static void* (*old_realloc_hook)(void*, size_t, const void*);
|
||||
static void* (*old_malloc_hook)(size_t, const void*);
|
||||
|
||||
int opal_memory_malloc_hooks_initialized = 0;
|
||||
|
||||
void
|
||||
opal_memory_malloc_hooks_init(void)
|
||||
{
|
||||
if (opal_memory_malloc_hooks_initialized != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
opal_memory_malloc_hooks_initialized = 1;
|
||||
|
||||
old_free_hook = __free_hook;
|
||||
old_malloc_hook = __malloc_hook;
|
||||
old_realloc_hook = __realloc_hook;
|
||||
|
||||
__free_hook = local_free_hook;
|
||||
__malloc_hook = local_malloc_hook;
|
||||
__realloc_hook = local_realloc_hook;
|
||||
|
||||
opal_mem_hooks_set_support(OPAL_MEMORY_FREE_SUPPORT|OPAL_MEMORY_MALLOC_SUPPORT);
|
||||
assert(__malloc_hook == local_malloc_hook);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
local_free_hook(void *ptr, const void *caller)
|
||||
{
|
||||
if (__malloc_hook != local_malloc_hook) abort();
|
||||
/* dispatch about the pending free */
|
||||
opal_mem_hooks_release_hook(ptr, malloc_usable_size(ptr));
|
||||
|
||||
__free_hook = old_free_hook;
|
||||
|
||||
/* call the next chain down */
|
||||
free(ptr);
|
||||
|
||||
/* save the hooks again and restore our hook again */
|
||||
old_free_hook = __free_hook;
|
||||
__free_hook = local_free_hook;
|
||||
}
|
||||
|
||||
|
||||
static void*
|
||||
local_malloc_hook(size_t size, const void *caller)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
__malloc_hook = old_malloc_hook;
|
||||
|
||||
/* call the next chain down */
|
||||
ret = malloc(size);
|
||||
|
||||
/* save the hooks again and restory our hack again */
|
||||
old_malloc_hook = __malloc_hook;
|
||||
__malloc_hook = local_malloc_hook;
|
||||
|
||||
opal_mem_hooks_alloc_hook(ret, malloc_usable_size(ret));
|
||||
|
||||
assert(__malloc_hook == local_malloc_hook);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* for better or worse, we must assume that the buffer being passed to
|
||||
realloc is not going to be expandable and therefore is going to be
|
||||
free()ed. */
|
||||
static void*
|
||||
local_realloc_hook(void *ptr, size_t size, const void *caller)
|
||||
{
|
||||
void *ret;
|
||||
assert(__malloc_hook == local_malloc_hook);
|
||||
|
||||
/* dispatch about the pending free */
|
||||
opal_mem_hooks_release_hook(ptr, malloc_usable_size(ptr));
|
||||
|
||||
/* realloc can call malloc (but not free). Doing so with the
|
||||
* memory hooks causes us some interesting problems and causes
|
||||
* the malloc_hook to be left as NULL. Pop the stack now so
|
||||
* that we don't see the memory registration twice.
|
||||
*/
|
||||
__realloc_hook = old_realloc_hook;
|
||||
__malloc_hook = old_malloc_hook;
|
||||
|
||||
/* call the next chain down */
|
||||
ret = realloc(ptr, size);
|
||||
|
||||
/* save the hooks again and restore our hook again */
|
||||
old_realloc_hook = __realloc_hook;
|
||||
old_malloc_hook = __malloc_hook;
|
||||
__realloc_hook = local_realloc_hook;
|
||||
__malloc_hook = local_malloc_hook;
|
||||
|
||||
opal_mem_hooks_alloc_hook(ret, malloc_usable_size(ret));
|
||||
assert(__malloc_hook == local_malloc_hook);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* mmap is a weak symbol on any platform that I know of that
|
||||
supports malloc hooks, so we can just intercept it like this... */
|
||||
void*
|
||||
mmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
static void* (*realmmap)(void*, size_t, int, int, int, off_t);
|
||||
|
||||
if (NULL == realmmap) {
|
||||
union {
|
||||
void* (*mmap_fp)(void*, size_t, int, int, int, off_t);
|
||||
void *mmap_p;
|
||||
} tmp;
|
||||
|
||||
tmp.mmap_p = dlsym(RTLD_NEXT, "mmap");
|
||||
realmmap = tmp.mmap_fp;
|
||||
}
|
||||
|
||||
ret = realmmap(addr, len, prot, flags, fd, offset);
|
||||
|
||||
opal_mem_hooks_alloc_hook(ret, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* munmap is a weak symbol on any platform that I know of that
|
||||
supports malloc hooks, so we can just intercept it like this... */
|
||||
int
|
||||
munmap(void* addr, size_t len)
|
||||
{
|
||||
static int (*realmunmap)(void*, size_t);
|
||||
/* dispatch about the pending release */
|
||||
opal_mem_hooks_release_hook(addr, len);
|
||||
assert(__malloc_hook == local_malloc_hook);
|
||||
|
||||
if (NULL == realmunmap) {
|
||||
union {
|
||||
int (*munmap_fp)(void*, size_t);
|
||||
void *munmap_p;
|
||||
} tmp;
|
||||
|
||||
tmp.munmap_p = dlsym(RTLD_NEXT, "munmap");
|
||||
realmunmap = tmp.munmap_fp;
|
||||
}
|
||||
|
||||
return realmunmap(addr, len);
|
||||
}
|
||||
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "opal/mca/memory/memory.h"
|
||||
#include "opal/include/constants.h"
|
||||
|
||||
extern int opal_memory_malloc_hooks_initialized;
|
||||
|
||||
extern void opal_memory_malloc_hooks_init(void);
|
||||
|
||||
static int opal_memory_malloc_open(void);
|
||||
|
||||
const opal_memory_base_component_1_0_0_t mca_memory_malloc_hooks_component = {
|
||||
/* First, the mca_component_t struct containing meta information
|
||||
about the component itself */
|
||||
{
|
||||
/* Indicate that we are a memory v1.0.0 component (which also
|
||||
implies a specific MCA version) */
|
||||
OPAL_MEMORY_BASE_VERSION_1_0_0,
|
||||
|
||||
/* Component name and version */
|
||||
"malloc_hooks",
|
||||
OPAL_MAJOR_VERSION,
|
||||
OPAL_MINOR_VERSION,
|
||||
OPAL_RELEASE_VERSION,
|
||||
|
||||
/* Component open and close functions */
|
||||
opal_memory_malloc_open,
|
||||
NULL
|
||||
},
|
||||
|
||||
/* Next the MCA v1.0.0 component meta data */
|
||||
{
|
||||
/* Whether the component is checkpointable or not */
|
||||
true
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
opal_memory_malloc_open(void)
|
||||
{
|
||||
void *a;
|
||||
/* allocate some memory to make sure that malloc has been called,
|
||||
then make sure we initialized */
|
||||
a = malloc(1);
|
||||
free(a);
|
||||
|
||||
if (0 == opal_memory_malloc_hooks_initialized) {
|
||||
printf("memory_malloc_hooks not properly initialized\n");
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
noinst_LTLIBRARIES = libmca_memory_malloc_interpose.la
|
||||
|
||||
libmca_memory_malloc_interpose_la_SOURCES = \
|
||||
memory_malloc_interpose.c
|
||||
libmca_memory_malloc_interpose_la_LIBADD = \
|
||||
$(memory_malloc_interpose_LIBS)
|
||||
|
@ -1,75 +0,0 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AC_DEFUN([MCA_memory_malloc_interpose_COMPILE_MODE], [
|
||||
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
|
||||
$4="static"
|
||||
AC_MSG_RESULT([$$4])
|
||||
])
|
||||
|
||||
|
||||
# MCA_memory_malloc_interpose_CONFIG(action-if-can-compile,
|
||||
# [action-if-cant-compile])
|
||||
# ------------------------------------------------
|
||||
AC_DEFUN([MCA_memory_malloc_interpose_CONFIG],[
|
||||
AC_ARG_WITH([memory-manager],
|
||||
[AC_HELP_STRING([--with-memory-manager=TYPE],
|
||||
[Use TYPE for intercepting memory management
|
||||
calls to control memory pinning.])])
|
||||
|
||||
AS_IF([test "$with_memory_manager" = "malloc_interpose"],
|
||||
[memory_malloc_interpose_happy="yes"
|
||||
memory_malloc_interpose_should_use=1],
|
||||
[memory_malloc_interpose_should_use=0
|
||||
AS_IF([test "$with_memory_manager" = ""],
|
||||
[memory_malloc_interpose_happy="yes"],
|
||||
[memory_malloc_interpose_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_malloc_interpose_happy" = "yes"],
|
||||
[# check for malloc.h
|
||||
AC_CHECK_HEADER([malloc.h],
|
||||
[memory_malloc_interpose_happy="yes"],
|
||||
[memory_malloc_interpose_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_malloc_interpose_happy" = "yes"],
|
||||
[AC_CHECK_FUNC([malloc_usable_size],
|
||||
[memory_malloc_interpose_happy="yes"],
|
||||
[memory_malloc_interpose_happy="no"])])
|
||||
|
||||
memory_malloc_interpose_LIBS_SAVE="$LIBS"
|
||||
AS_IF([test "$memory_malloc_interpose_happy" = "yes"],
|
||||
[AC_CHECK_LIB([dl],
|
||||
[dlsym],
|
||||
[memory_malloc_interpose_happy="yes"],
|
||||
[memory_malloc_interpose_happy="no"])])
|
||||
LIBS="$memory_malloc_interpose_LIBS_SAVE"
|
||||
|
||||
AS_IF([test "$memory_malloc_interpose_happy" = "yes"],
|
||||
[memory_malloc_interpose_WRAPPER_EXTRA_LIBS="-ldl"
|
||||
memory_malloc_interpose_LIBS="-ldl"])
|
||||
|
||||
AS_IF([test "$memory_malloc_interpose_happy" = "no" -a \
|
||||
"$memory_malloc_interpose_should_use" = "1"],
|
||||
[AC_MSG_ERROR([malloc interpose memory management requested but not available. Aborting.])])
|
||||
|
||||
AC_SUBST(memory_malloc_interpose_LIBS)
|
||||
|
||||
AS_IF([test "$memory_malloc_interpose_happy" = "yes"],
|
||||
[$1], [$2])
|
||||
])
|
@ -1,23 +0,0 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# Specific to this module
|
||||
|
||||
PARAM_CONFIG_PRIORITY=10
|
||||
PARAM_CONFIG_FILES="Makefile"
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#define OMPI_DISABLE_ENABLE_MEM_DEBUG 1
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "opal/include/constants.h"
|
||||
#include "opal/mca/memory/memory.h"
|
||||
#include "opal/memoryhooks/memory_internal.h"
|
||||
|
||||
static int opal_memory_malloc_interpose_open(void);
|
||||
|
||||
const opal_memory_base_component_1_0_0_t mca_memory_malloc_interpose_component = {
|
||||
/* First, the mca_component_t struct containing meta information
|
||||
about the component itself */
|
||||
{
|
||||
/* Indicate that we are a memory v1.0.0 component (which also
|
||||
implies a specific MCA version) */
|
||||
OPAL_MEMORY_BASE_VERSION_1_0_0,
|
||||
|
||||
/* Component name and version */
|
||||
"malloc_interpose",
|
||||
OPAL_MAJOR_VERSION,
|
||||
OPAL_MINOR_VERSION,
|
||||
OPAL_RELEASE_VERSION,
|
||||
|
||||
/* Component open and close functions */
|
||||
opal_memory_malloc_interpose_open,
|
||||
NULL
|
||||
},
|
||||
|
||||
/* Next the MCA v1.0.0 component meta data */
|
||||
{
|
||||
/* Whether the component is checkpointable or not */
|
||||
true
|
||||
},
|
||||
};
|
||||
|
||||
#define FIND_REALFREE() \
|
||||
do { \
|
||||
if (NULL == realfree) { \
|
||||
union { \
|
||||
void (*free_fp)(void*); \
|
||||
void *free_p; \
|
||||
} tmp; \
|
||||
tmp.free_p = dlsym(RTLD_NEXT, "free"); \
|
||||
realfree = tmp.free_fp; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define FIND_REALREALLOC() \
|
||||
do { \
|
||||
if (NULL == realrealloc) { \
|
||||
union { \
|
||||
void* (*realloc_fp)(void*, size_t); \
|
||||
void* realloc_p; \
|
||||
} tmp; \
|
||||
tmp.realloc_p = dlsym(RTLD_NEXT, "realloc"); \
|
||||
realrealloc = tmp.realloc_fp; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define FIND_REALMUNMAP() \
|
||||
do { \
|
||||
if (NULL == realmunmap) { \
|
||||
union { \
|
||||
int (*munmap_fp)(void*, size_t); \
|
||||
void *munmap_p; \
|
||||
} tmp; \
|
||||
tmp.munmap_p = dlsym(RTLD_NEXT, "munmap"); \
|
||||
realmunmap = tmp.munmap_fp; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
static void (*realfree)(void*);
|
||||
static void* (*realrealloc)(void*, size_t);
|
||||
static int (*realmunmap)(void*, size_t);
|
||||
|
||||
static int
|
||||
opal_memory_malloc_interpose_open(void)
|
||||
{
|
||||
opal_mem_hooks_set_support(OPAL_MEMORY_FREE_SUPPORT);
|
||||
|
||||
FIND_REALFREE();
|
||||
FIND_REALREALLOC();
|
||||
FIND_REALMUNMAP();
|
||||
|
||||
if (NULL == realfree || NULL == realrealloc || NULL == realmunmap) {
|
||||
/* this shoudl really never happen */
|
||||
fprintf(stderr,
|
||||
"Could not find real memory functions. Aborting in dispair\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
free(void *ptr)
|
||||
{
|
||||
FIND_REALFREE();
|
||||
|
||||
/* dispatch about the pending release */
|
||||
opal_mem_hooks_release_hook(ptr, malloc_usable_size(ptr));
|
||||
realfree(ptr);
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
realloc(void *ptr, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
FIND_REALREALLOC();
|
||||
opal_mem_hooks_release_hook(ptr, malloc_usable_size(ptr));
|
||||
ret = realrealloc(ptr, size);
|
||||
opal_mem_hooks_alloc_hook(ret, malloc_usable_size(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
munmap(void *start, size_t length)
|
||||
{
|
||||
FIND_REALMUNMAP();
|
||||
|
||||
/* dispatch about the pending release */
|
||||
opal_mem_hooks_release_hook(start, length);
|
||||
return realmunmap(start, length);
|
||||
}
|
@ -40,12 +40,12 @@ doc_DATA = ptmalloc2-COPYRIGHT
|
||||
noinst_LTLIBRARIES = libmca_memory_ptmalloc2.la
|
||||
|
||||
libmca_memory_ptmalloc2_la_SOURCES = \
|
||||
ptmalloc2_component.c \
|
||||
ptmalloc2_munmap.c \
|
||||
opal_ptmalloc2_component.c \
|
||||
opal_ptmalloc2_munmap.c \
|
||||
malloc.c \
|
||||
malloc-stats.c \
|
||||
malloc.h
|
||||
|
||||
|
||||
# these are included directly and shouldn't be built solo
|
||||
EXTRA_libmca_memory_ptmalloc2_la_SOURCES = \
|
||||
arena.c \
|
||||
|
@ -468,7 +468,11 @@ ptmalloc_init __MALLOC_P((void))
|
||||
/********************** BEGIN OMPI CHANGES *****************************/
|
||||
/* don't use __hook for this, as someone might want to use those
|
||||
features */
|
||||
opal_mem_hooks_set_support(OPAL_MEMORY_FREE_SUPPORT|OPAL_MEMORY_CHUNK_SUPPORT);
|
||||
opal_mem_hooks_set_support(OPAL_MEMORY_FREE_SUPPORT |
|
||||
#if defined(HAVE_SYSCALL) || defined(HAVE___MMAP)
|
||||
OPAL_MEMORY_MALLOC_SUPPORT |
|
||||
#endif
|
||||
OPAL_MEMORY_CHUNK_SUPPORT);
|
||||
/********************* BEGIN OMPI CHANGES ******************************/
|
||||
|
||||
__malloc_initialized = 1;
|
||||
|
@ -29,24 +29,80 @@ AC_DEFUN([MCA_memory_ptmalloc2_COMPILE_MODE], [
|
||||
# ------------------------------------------------
|
||||
AC_DEFUN([MCA_memory_ptmalloc2_CONFIG],[
|
||||
AC_ARG_WITH([memory-manager],
|
||||
AC_HELP_STRING([--with-memory-manager=TYPE],
|
||||
[AC_HELP_STRING([--with-memory-manager=TYPE],
|
||||
[Use TYPE for intercepting memory management
|
||||
calls to control memory pinning.]),
|
||||
[memory_ptmalloc2_WANT_MEMORY="$withval"],
|
||||
[memory_ptmalloc2_WANT_MEMORY="none"])
|
||||
calls to control memory pinning.])])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_WANT_MEMORY" = "ptmalloc2"],
|
||||
[if test "`echo $host | grep apple-darwin`" != "" ; then
|
||||
AS_IF([test "$with_memory_manager" = "ptmalloc2"],
|
||||
[if test "`echo $host | grep apple-darwin`" != "" ; then
|
||||
AC_MSG_WARN([*** Using ptmalloc with OS X will result in failure.])
|
||||
AC_MSG_ERROR([*** Aborting to save you the effort])
|
||||
fi
|
||||
fi
|
||||
memory_ptmalloc2_happy="yes"
|
||||
memory_ptmalloc2_should_use=1],
|
||||
[memory_ptmalloc2_should_use=0
|
||||
AS_IF([test "$with_memory_manager" = ""],
|
||||
[memory_ptmalloc2_happy="yes"],
|
||||
[memory_ptmalloc2_happy="no"])])
|
||||
|
||||
#
|
||||
# See if we have sbrk prototyped
|
||||
#
|
||||
AC_CHECK_DECL([sbrk], [have_decl_sbrk=1], [have_decl_sbrk=0])
|
||||
AC_DEFINE_UNQUOTED(OMPI_HAVE_DECL_SBRK, $have_decl_sbrk,
|
||||
[Whether we have a declaration for sbrk() or not])
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[AS_IF([test "$enable_mpi_threads" = "yes" -o \
|
||||
"$enable_progress_threads" = "yes"],
|
||||
[memory_ptmalloc2_happy="no"])])
|
||||
|
||||
$1], [$2])
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[# check for malloc.h
|
||||
AC_CHECK_HEADER([malloc.h],
|
||||
[memory_ptmalloc2_happy="yes"],
|
||||
[memory_ptmalloc2_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[# check for init hook symbol
|
||||
AC_CHECK_DECL([__malloc_initialize_hook],
|
||||
[memory_ptmalloc2_happy="yes"],
|
||||
[memory_ptmalloc2_happy="no"],
|
||||
[AC_INCLUDES_DEFAULT
|
||||
#include <malloc.h>])])
|
||||
|
||||
#
|
||||
# See if we have sbrk prototyped
|
||||
#
|
||||
AC_CHECK_DECLS([sbrk])
|
||||
|
||||
#
|
||||
# Figure out how we're going to call mmap/munmap for real
|
||||
#
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[memory_ptmalloc2_mmap=0
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0"],
|
||||
[AC_CHECK_HEADER([syscall.h],
|
||||
[AC_CHECK_FUNCS([syscall], [memory_ptmalloc2_mmap=1])])])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0"],
|
||||
[AC_CHECK_FUNCS([__munmap], [memory_ptmalloc2_mmap=1])
|
||||
AC_CHECK_FUNCS([__mmap])])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0"],
|
||||
[memory_ptmalloc2_LIBS_SAVE="$LIBS"
|
||||
AC_CHECK_LIB([dl],
|
||||
[dlsym],
|
||||
[memory_ptmalloc2_LIBS="-ldl"
|
||||
memory_ptmalloc2_mmap=1])
|
||||
AC_CHECK_FUNCS([dlsym])
|
||||
LIBS="$memory_ptmalloc2_LIBS_SAVE"])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_mmap" = "0"],
|
||||
[memory_ptmalloc2_happy="no"])])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[memory_ptmalloc2_WRAPPER_EXTRA_LIBS="$memory_ptmalloc2_LIBS"])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "no" -a \
|
||||
"$memory_malloc_hoooks_should_use" = "1"],
|
||||
[AC_MSG_ERROR([ptmalloc2 memory management requested but not available. Aborting.])])
|
||||
|
||||
AC_SUBST([memory_ptmalloc2_LIBS])
|
||||
|
||||
AS_IF([test "$memory_ptmalloc2_happy" = "yes"],
|
||||
[$1], [$2])
|
||||
])
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Not all systems have sbrk() declared, since it's technically not a
|
||||
* POSIX function.
|
||||
*/
|
||||
#if !OMPI_HAVE_DECL_SBRK
|
||||
#if !HAVE_DECL_SBRK
|
||||
void *sbrk();
|
||||
#endif
|
||||
|
||||
@ -21,15 +21,24 @@ opal_mem_free_ptmalloc2_sbrk(int inc)
|
||||
if (inc < 0) {
|
||||
long oldp = (long) sbrk(0);
|
||||
opal_mem_hooks_release_hook((void*) (oldp + inc), -inc);
|
||||
#if defined(HAVE_SYSCALL) || defined(HAVE___MMAP)
|
||||
} else if (inc > 0) {
|
||||
long oldp = (long) sbrk(0);
|
||||
opal_mem_hooks_alloc_hook((void*) oldp, inc);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sbrk(inc);
|
||||
}
|
||||
|
||||
extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length);
|
||||
extern void* opal_mem_free_ptmalloc2_mmap(void *start, size_t length,
|
||||
int prot, int flags,
|
||||
int fd, off_t offset);
|
||||
|
||||
#define MORECORE opal_mem_free_ptmalloc2_sbrk
|
||||
#define munmap(a,b) opal_mem_free_ptmalloc2_munmap(a,b)
|
||||
#define mmap(a, b, c, d, e, f) opal_mem_free_ptmalloc2_mmap(a, b, c, d, e, f)
|
||||
/* easier to just not use mremap - having it makes tracking more
|
||||
difficult */
|
||||
#define HAVE_MREMAP 0
|
||||
@ -44,7 +53,7 @@ extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length);
|
||||
#define __const const
|
||||
#endif
|
||||
|
||||
/********************* BEGIN OMPI CHANGES ******************************/
|
||||
/********************* END OMPI CHANGES ******************************/
|
||||
|
||||
|
||||
|
||||
|
146
opal/mca/memory/ptmalloc2/opal_ptmalloc2_munmap.c
Обычный файл
146
opal/mca/memory/ptmalloc2/opal_ptmalloc2_munmap.c
Обычный файл
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
|
||||
#include "opal/memoryhooks/memory_internal.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#if defined(HAVE_SYSCALL)
|
||||
#include <syscall.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(HAVE___MUNMAP)
|
||||
/* here only so that we only include dlfcn.h if needed */
|
||||
#elif defined(HAVE_DLSYM)
|
||||
#define __USE_GNU
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* munmap is always intercepted
|
||||
*/
|
||||
int opal_mem_free_ptmalloc2_munmap(void *start, size_t length);
|
||||
#if defined(HAVE_SYSCALL) || defined(HAVE___MUNMAP)
|
||||
int __munmap(void* addr, size_t len);
|
||||
#endif
|
||||
|
||||
|
||||
/* intercept munmap, as the user can give back memory that way as well. */
|
||||
int
|
||||
munmap(void* addr, size_t len)
|
||||
{
|
||||
return opal_mem_free_ptmalloc2_munmap(addr, len);
|
||||
}
|
||||
|
||||
|
||||
/* with syscall, we can safely intercept this as well */
|
||||
#if defined(HAVE_SYSCALL)
|
||||
int
|
||||
__munmap(void* addr, size_t len)
|
||||
{
|
||||
return opal_mem_free_ptmalloc2_munmap(addr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* three ways to call munmap. Prefered is to just call syscall, so
|
||||
that we can intercept both munmap and __munmap. If that isn't
|
||||
possible, try calling __munmap from munmap and let __munmap go. If
|
||||
that doesn't work, try dlsym */
|
||||
int
|
||||
opal_mem_free_ptmalloc2_munmap(void *start, size_t length)
|
||||
{
|
||||
#ifdef HAVE_DLSYM
|
||||
static int (*realmunmap)(void*, size_t);
|
||||
#endif
|
||||
|
||||
opal_mem_hooks_release_hook(start, length);
|
||||
|
||||
#if defined(HAVE_SYSCALL)
|
||||
return syscall(__NR_munmap, start, length);
|
||||
#elif defined(HAVE___MUNMAP)
|
||||
return __munmap(start, length);
|
||||
#elif defined(HAVE_DLSYM)
|
||||
if (NULL == realmunmap) {
|
||||
realmunmap = (int (*)(void*, size_t)) dlsym(RTLD_NEXT, "munmap");
|
||||
}
|
||||
|
||||
return realmunmap(start, length);
|
||||
#else
|
||||
#error "Can not determine how to call munmap"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_SYSCALL) || defined(HAVE___MMAP)
|
||||
/*
|
||||
* mmap is only intercepted if we have a chance of finding it (ie, a
|
||||
* syscall or weak symbol)
|
||||
*/
|
||||
void* opal_mem_free_ptmalloc2_mmap(void *start, size_t length,
|
||||
int prot, int flags,
|
||||
int fd, off_t offset);
|
||||
|
||||
void* __mmap(void *start, size_t length, int prot, int flags,
|
||||
int fd, off_t offset);
|
||||
|
||||
|
||||
void*
|
||||
mmap(void *start, size_t length, int prot, int flags,
|
||||
int fd, off_t offset)
|
||||
{
|
||||
return opal_mem_free_ptmalloc2_mmap(start, length, prot, flags,
|
||||
fd, offset);
|
||||
}
|
||||
|
||||
#if defined(HAVE_SYSCALL)
|
||||
/* with syscall, we can safely intercept this as well */
|
||||
void*
|
||||
__mmap(void *start, size_t length, int prot, int flags,
|
||||
int fd, off_t offset)
|
||||
{
|
||||
return opal_mem_free_ptmalloc2_mmap(start, length, prot, flags,
|
||||
fd, offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* three ways to call mmap. Prefered is to just call syscall, so that
|
||||
we can intercept both munmap and __munmap. If that isn't possible,
|
||||
try calling __mmap from mmap and let __mmap go. Do not try to
|
||||
dlsym, as that generally requires calling mmap.
|
||||
*/
|
||||
void* opal_mem_free_ptmalloc2_mmap(void *start, size_t length,
|
||||
int prot, int flags,
|
||||
int fd, off_t offset)
|
||||
{
|
||||
opal_mem_hooks_alloc_hook(start, length);
|
||||
|
||||
#if defined(HAVE_SYSCALL)
|
||||
return (void*) syscall(__NR_mmap, start, length, prot, flags, fd, offset);
|
||||
#elif defined(HAVE___MUNMAP)
|
||||
return __mmap(start, length, prot, flags, fd, offset);
|
||||
#else
|
||||
#error "Can not determine how to call mmap"
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* #if defined(HAVE_SYSCALL) || defined(HAVE___MMAP) */
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "opal/memoryhooks/memory_internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#define __USE_GNU
|
||||
#include <dlfcn.h>
|
||||
|
||||
static int (*realmunmap)(void*, size_t);
|
||||
|
||||
/* munmap is a weak symbol on any platform that I know of that
|
||||
supports malloc hooks, so we can just intercept it like this... */
|
||||
int
|
||||
munmap(void* addr, size_t len)
|
||||
{
|
||||
/* dispatch about the pending release */
|
||||
opal_mem_hooks_release_hook(addr, len);
|
||||
|
||||
if (NULL == realmunmap) {
|
||||
realmunmap = (int (*)(void*, size_t)) dlsym(RTLD_NEXT, "munmap");
|
||||
}
|
||||
|
||||
return realmunmap(addr, len);
|
||||
}
|
||||
|
||||
/* put this here beacuse malloc.c really doesn't like dlfcn.h, but we
|
||||
need it for getting the right munmap... */
|
||||
int
|
||||
opal_mem_free_ptmalloc2_munmap(void *start, size_t length)
|
||||
{
|
||||
opal_mem_hooks_release_hook(start, length);
|
||||
|
||||
if (NULL == realmunmap) {
|
||||
realmunmap = (int (*)(void*, size_t)) dlsym(RTLD_NEXT, "munmap");
|
||||
}
|
||||
|
||||
return realmunmap(start, length);
|
||||
}
|
@ -72,6 +72,7 @@ alloc_free_test(void)
|
||||
foo = malloc(bigsize);
|
||||
assert(counter >= 1);
|
||||
printf(" - free of big buffer\n");
|
||||
counter = 1;
|
||||
free(foo);
|
||||
assert(counter == 0);
|
||||
|
||||
@ -110,7 +111,8 @@ main(int argc, char *argv[])
|
||||
if (0 == support) {
|
||||
printf("no memory registration supported. skipping test.\n");
|
||||
ret = 77;
|
||||
} else if ((OPAL_MEMORY_FREE_SUPPORT|OPAL_MEMORY_MALLOC_SUPPORT) & support) {
|
||||
} else if ((OPAL_MEMORY_FREE_SUPPORT|OPAL_MEMORY_MALLOC_SUPPORT) ==
|
||||
((OPAL_MEMORY_FREE_SUPPORT|OPAL_MEMORY_MALLOC_SUPPORT) & support)) {
|
||||
ret = alloc_free_test();
|
||||
} else if (OPAL_MEMORY_FREE_SUPPORT & support) {
|
||||
ret = free_only_test();
|
||||
|
@ -60,10 +60,10 @@ main(int argc, char *argv[])
|
||||
printf(" - allocating big vector\n");
|
||||
big_vec = new vector<int>;
|
||||
|
||||
big_vec->reserve(10000);
|
||||
big_vec->reserve(size);
|
||||
/* touch all the locations, just to make sure C++ isn't smarter
|
||||
than I am */
|
||||
for (int i = 0 ; i < 10000 ; ++i) {
|
||||
for (int i = 0 ; i < size ; ++i) {
|
||||
(*big_vec)[i] = i;
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user