1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2004-2007 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 (c) 2007-2011 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009-2011 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "opal_config.h"
#include "opal/constants.h"
#include "opal/mca/memory/base/empty.h"
#include "opal/mca/memory/memory.h"
#include "opal/memoryhooks/memory_internal.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#if defined(HAVE___MUNMAP)
/* here so we only include others if we absolutely have to */
#elif defined(HAVE_SYSCALL)
# include <sys/syscall.h>
# include <unistd.h>
#endif
#if defined(HAVE___MUNMAP)
int __munmap(caddr_t addr, size_t len);
#endif
static int opal_memory_malloc_open(void);
static int opal_memory_malloc_query(int *);
const opal_memory_base_component_2_0_0_t mca_memory_malloc_solaris_component = {
/* First, the mca_component_t struct containing meta information
about the component itself */
.memoryc_version =
{
OPAL_MEMORY_BASE_VERSION_2_0_0,
/* Component name and version */
.mca_component_name = "malloc_solaris",
MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION,
OPAL_RELEASE_VERSION),
/* Component open and close functions */
.mca_open_component = opal_memory_malloc_open,
},
.memoryc_data =
{/* The component is checkpoint ready */
MCA_BASE_METADATA_PARAM_CHECKPOINT},
/* This component doesn't need these functions, but need to
provide safe/empty register/deregister functions to call */
.memoryc_query = opal_memory_malloc_query,
.memoryc_register = opal_memory_base_component_register_empty,
.memoryc_deregister = opal_memory_base_component_deregister_empty,
.memoryc_set_alignment = opal_memory_base_component_set_alignment_empty,
};
/*
* This component exists to establish the memory hook support
* level available on Solaris. By default Solaris does not
* return memory to the system, i.e. does not unmap memory
* from the process space, when a user calls free(). This allows
* us to declare OPAL_MEMORY_FREE_SUPPORT. Additionally, by
* intercepting munmap we can declare OPAL_MEMORY_MUNMAP_SUPPORT.
*
* NOTE: Not releasing memory back to the system when calling
* free() may be unique to Solaris which is why this component
* was created.
*/
static int opal_memory_malloc_open(void)
{
opal_mem_hooks_set_support((OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_MUNMAP_SUPPORT));
return OPAL_SUCCESS;
}
static int opal_memory_malloc_query(int *priority)
{
*priority = 79;
return OPAL_SUCCESS;
}
/*
* Three ways to call munmap. Preferred is to call __munmap, which
* will exist if munmap is a weak symbol. If not available next try
* the syscall, and if that doesn't work, try looking in the dynamic
* libc.
*/
#if USE_SOLARIS_LEGACY_MUNMAP_PROTOTYPE
/* We are compiling using S10 so use its munmap prototype */
int munmap(caddr_t addr, size_t len)
#else
/* From S11 on forward munmap's addr is void * */
int munmap(void *addr, size_t len)
#endif
{
#if !defined(HAVE___MUNMAP) && !defined(HAVE_SYSCALL) && defined(HAVE_DLSYM)
static int (*realmunmap)(void *, size_t);
#endif
opal_mem_hooks_release_hook(addr, len, 0);
#if defined(HAVE___MUNMAP)
return __munmap(addr, len);
#elif defined(HAVE_SYSCALL)
return syscall(SYS_munmap, addr, len);
#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(addr, len);
#else
# error "Can not determine how to call munmap"
#endif
}
|