1
1

Really fixes trac:2104. There is a lengthy discussion about this patch on

#2322.

The short version is that this patch consolidates two pieces of code
that call the back-end munmap and ensures that (if dlsym is used) the
corresponding dlsym is only invoked once and that the variable holding
the result is volatile.

This commit was SVN r22863.

The following Trac tickets were found above:
  Ticket 2104 --> https://svn.open-mpi.org/trac/ompi/ticket/2104
Этот коммит содержится в:
Jeff Squyres 2010-03-23 01:04:25 +00:00
родитель 62e751a95c
Коммит 136f926fd1
4 изменённых файлов: 33 добавлений и 58 удалений

Просмотреть файл

@ -292,7 +292,6 @@ ptmalloc_unlock_all2 __MALLOC_P((void))
#endif /* !defined NO_THREADS */
#include <dlfcn.h>
/* Initialization routine. */
#ifdef _LIBC
@ -519,40 +518,8 @@ dump_heap(heap) heap_info *heap;
#endif /* MALLOC_DEBUG > 1 */
int
munmap_real(void *start, size_t length)
{
#if !defined(HAVE___MUNMAP) && \
!(defined(HAVE_SYSCALL) && defined(__NR_munmap)) && defined(HAVE_DLSYM)
static int (*realmunmap)(void*, size_t);
#endif
{
extern bool opal_memory_ptmalloc2_munmap_invoked;
opal_memory_ptmalloc2_munmap_invoked = true;
}
#if defined(HAVE___MUNMAP)
return __munmap(start, length);
#elif defined(HAVE_SYSCALL) && defined(__NR_munmap)
return syscall(__NR_munmap, start, length);
#elif defined(HAVE_DLSYM)
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(start, length);
#else
#error "Can not determine how to call munmap"
#endif
}
extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int run_hooks);
/* Create a new heap. size is automatically rounded up to a multiple
@ -589,8 +556,9 @@ new_heap(size, top_pad) size_t size, top_pad;
if(p1 != MAP_FAILED) {
p2 = (char *)(((unsigned long)p1 + (HEAP_MAX_SIZE-1)) & ~(HEAP_MAX_SIZE-1));
ul = p2 - p1;
munmap_real(p1, ul);
munmap_real(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul);
opal_mem_free_ptmalloc2_munmap(p1, ul, 1, 0);
opal_mem_free_ptmalloc2_munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul,
1, 0);
} else {
/* Try to take the chance that an allocation of only HEAP_MAX_SIZE
is already aligned. */
@ -598,12 +566,12 @@ new_heap(size, top_pad) size_t size, top_pad;
if(p2 == MAP_FAILED)
return 0;
if((unsigned long)p2 & (HEAP_MAX_SIZE-1)) {
munmap_real(p2, HEAP_MAX_SIZE);
opal_mem_free_ptmalloc2_munmap(p2, HEAP_MAX_SIZE, 1, 0);
return 0;
}
}
if(mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) {
munmap_real(p2, HEAP_MAX_SIZE);
opal_mem_free_ptmalloc2_munmap(p2, HEAP_MAX_SIZE, 1, 0);
return 0;
}
h = (heap_info *)p2;

Просмотреть файл

@ -30,14 +30,14 @@ opal_mem_free_ptmalloc2_sbrk(int inc)
return sbrk(inc);
}
extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc);
extern int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int run_hooks);
/* if we are trying to catch only allocations from and releases to the
operating system, intercept sbrk, mmap, and munmap. If we want to
intercept every call to malloc/realloc/free/etc., don't do this, as
we need to add something into each of those calls anyway. */
#define MORECORE opal_mem_free_ptmalloc2_sbrk
#define munmap(a,b) opal_mem_free_ptmalloc2_munmap(a,b,1)
#define munmap(a,b) opal_mem_free_ptmalloc2_munmap(a,b,1,1)
/* make some non-GCC compilers happy */
#ifndef __GNUC__

Просмотреть файл

@ -50,7 +50,7 @@ int __munmap(void* addr, size_t len);
OPAL_DECLSPEC int
munmap(void* addr, size_t len)
{
return opal_mem_free_ptmalloc2_munmap(addr, len, 0);
return opal_mem_free_ptmalloc2_munmap(addr, len, 0, 1);
}
@ -59,36 +59,43 @@ munmap(void* addr, size_t len)
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, int from_alloc)
opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc,
int call_hooks)
{
#if !defined(HAVE___MUNMAP) && \
!(defined(HAVE_SYSCALL) && defined(__NR_munmap)) && defined(HAVE_DLSYM)
static int (*realmunmap)(void*, size_t);
#endif
{
extern bool opal_memory_ptmalloc2_munmap_invoked;
opal_memory_ptmalloc2_munmap_invoked = true;
}
opal_mem_hooks_release_hook(start, length, from_alloc);
if (call_hooks) {
opal_mem_hooks_release_hook(start, length, from_alloc);
}
#if defined(HAVE___MUNMAP)
return __munmap(start, length);
#elif defined(HAVE_SYSCALL) && defined(__NR_munmap)
return syscall(__NR_munmap, start, length);
#elif defined(HAVE_DLSYM)
if (NULL == realmunmap) {
union {
int (*munmap_fp)(void*, size_t);
void *munmap_p;
} tmp;
{
/* Must use a typedef here because we need volatile to be an
attribute of the variable, not the function (which would be
meaningless, anyway). */
typedef int (*munmap_fn_t)(void*, size_t);
static volatile munmap_fn_t realmunmap = NULL;
tmp.munmap_p = dlsym(RTLD_NEXT, "munmap");
realmunmap = tmp.munmap_fp;
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;
++count;
}
return realmunmap(start, length);
}
return realmunmap(start, length);
#else
#error "Can not determine how to call munmap"
#endif

Просмотреть файл

@ -23,7 +23,7 @@
BEGIN_C_DECLS
OPAL_DECLSPEC int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc);
OPAL_DECLSPEC int opal_mem_free_ptmalloc2_munmap(void *start, size_t length, int from_alloc, int call_hooks);
OPAL_DECLSPEC int munmap(void* addr, size_t len);