From bd4a0c4ee0bed909b7beed885e8f4d93e7efc5da Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Tue, 9 Aug 2005 19:32:49 +0000 Subject: [PATCH] * start memory manager code. Not activated yet, since configure changes aren't included yet This commit was SVN r6784. --- opal/memory/Makefile.am | 38 +++++++++ opal/memory/memory.c | 156 ++++++++++++++++++++++++++++++++++ opal/memory/memory.h | 106 +++++++++++++++++++++++ opal/memory/memory_internal.h | 22 +++++ 4 files changed, 322 insertions(+) create mode 100644 opal/memory/Makefile.am create mode 100644 opal/memory/memory.c create mode 100644 opal/memory/memory.h create mode 100644 opal/memory/memory_internal.h diff --git a/opal/memory/Makefile.am b/opal/memory/Makefile.am new file mode 100644 index 0000000000..5ad66c27c7 --- /dev/null +++ b/opal/memory/Makefile.am @@ -0,0 +1,38 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University. +# All rights reserved. +# Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +# 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 $(top_srcdir)/config/Makefile.options + +noinst_LTLIBRARIES = libopalmemory.la + +# Source code files + +headers = \ + memory.h \ + memory_internal.h + +libopalutil_la_SOURCES = \ + $(headers) \ + memory.c + +# Conditionally install the header files + +if WANT_INSTALL_HEADERS +ompidir = $(includedir)/openmpi/opal/memory +ompi_HEADERS = $(headers) +else +ompidir = $(includedir) +endif diff --git a/opal/memory/memory.c b/opal/memory/memory.c new file mode 100644 index 0000000000..6b77317ce9 --- /dev/null +++ b/opal/memory/memory.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University. + * All rights reserved. + * Copyright (c) 2004-2005 The Trustees of the University of Tennessee. + * 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 "ompi/include/constants.h" +#include "opal/memory/memory.h" +#include "opal/memory/memory_internal.h" +#include "opal/class/opal_list.h" + + +/* + * local types + */ +struct callback_list_item_t { + opal_list_item_t super; + opal_mem_free_unpin_fn_t cbfunc; + void *cbdata; +}; +typedef struct callback_list_item_t callback_list_item_t; +static OBJ_CLASS_INSTANCE(callback_list_item_t opal_list_item_t, NULL, NULL); + +/* + * local data + */ +static opal_list_t callback_list; +static opal_atomic_lock_t callback_lock; +static bool have_free_support; + +int +opal_mem_free_init(void) +{ + OBJ_DECLARATION(&callback_list, opal_list_t); + opal_atomic_init(&callback_lock, OPAL_ATOMIC_UNLOCKED); +} + + +int +opal_mem_free_finalize(void) +{ + opal_list_item_t *item; + + while (NULL != (item = opal_list_remove_first(&callback_list))) { + OBJ_RELEASE(item); + } + OBJ_DESTRUCT(&callback_list); +} + + +/* called from the memory manager / memory-manager specific hooks */ +void +opal_mem_free_release_hook(void *buf, size_t length) +{ + opal_list_item_t *item; + + opal_atomic_lock(&callback_lock); + + for (item = opal_list_get_first(&callback_list) ; + item != opal_list_get_end(&callback_list) ; + item = opal_list_get_next(item)) { + callback_list_item_t *cbitem = (callback_list_item_t*) item; + + cbitem->cbfunc(buf, length, cbitem->cbdata); + } + + opal_atomic_unlock(&callback_lock); +} + + +bool +opal_mem_free_is_supported(void) +{ + return have_free_support; +} + + +int +opal_mem_free_register_handler(opal_memory_unpin_t *func, void *cbdata) +{ + opal_list_item_t *item; + callback_list_item_t *cbitem; + int ret = OMPI_SUCCESS; + + if (!have_free_support) return OMPI_ERR_NOT_SUPPORTED; + + opal_atomic_lock(&callback_lock); + + /* make sure the callback isn't already in the list */ + for (item = opal_list_get_first(&callback_list) ; + item != opal_list_get_end(&callback_list) ; + item = opal_list_get_next(item)) { + cbitem = (callback_list_item_t*) item; + + if (cbitem->cbfunc == func) { + ret = OMPI_EXISTS; + goto done; + } + } + + cbitem = OBJ_NEW(callback_list_item_t); + if (NULL == cbitem) { + ret = OMPI_ERR_OUT_OF_RESOURCE; + goto done; + } + + cbitem->cbfunc = func; + cbitem->cbdata = cbdata; + + opal_list_appemd(&callback_list, (opal_list_item_t*) cbitem); + + done: + opal_atomic_unlock(&callback_lock); + + return ret; +} + + +int +opal_mem_free_unregister_handler(opal_memory_unpin_t *func) +{ + opal_list_item_t *item; + callback_list_item_t *cbitem; + int ret = OMPI_ERR_NOT_FOUND; + + opal_atomic_lock(&callback_lock); + + /* make sure the callback isn't already in the list */ + for (item = opal_list_get_first(&callback_list) ; + item != opal_list_get_end(&callback_list) ; + item = opal_list_get_next(item)) { + cbitem = (callback_list_item_t*) item; + + if (cbitem->cbfunc == func) { + opal_list_remove_item(&callback_list, item); + ret = OMPI_SUCCESS; + break; + } + } + + opal_atomic_unlock(&callback_lock); + + return ret; +} diff --git a/opal/memory/memory.h b/opal/memory/memory.h new file mode 100644 index 0000000000..56ae63b9f1 --- /dev/null +++ b/opal/memory/memory.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University. + * All rights reserved. + * Copyright (c) 2004-2005 The Trustees of the University of Tennessee. + * 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$ + */ + +/** + * @file@ + * + * Hooks for catching release of memory from the current process + * + * Hooks for catching the release of memory from the current process. + * For linking reasons, this is not a component framework (some of + * these require tight coupling into libopal and the wrapper compilers + * and that entire stack). + */ + +#ifndef OPAL_MEMORY_MEMORY_H +#define OPAl_MEMORY_MEMORY_H + + +int opal_mem_free_init(void); + +int opal_mem_free_finalize(void); + + +/** + * Callback when memory is about to be released by the process + * + * Callback when the process is about to release memory (but before it + * actually does so). It is not specified whether this means that + * free() is being called on that piece of memory and the memory may + * remain associated with the process or if the memory is being given + * back to the system through sbrk() or munmap(). + * + * @param buf Pointer to the start of the allocation + * to be released + * @param lentgh Length of the allocation to be released + * (starting at \c buf) + * @param cbdata Pointer-length of information passed to + * the handler registration function. + */ +typedef void (opal_mem_free_unpin_fn_t)(void *buf, size_t length, void *cbdata); + + +/** + * Query functionality of memory callbacks + * + * Query whether the system is capable of providing callbacks when + * memory is about to be released by a process. + * + * @retval true opal_mem_free_register_handler() will not return + * \c OMPI_ERR_NOT_SUPPORTED. + * @retval false opal_mem_free_register_handler() will always return + * \c OMPI_ERR_NOT_SUPPORTED. + * + * \note There is no reason you have to call this function before + * calling opal_mem_free_register_handler(). It exists for component + * selection logic that may want to see what the status of the memory + * hook support is without actually registering anything. + */ +bool opal_mem_free_is_supported(void); + + +/** + * Register callback for when memory is to be released + * + * Register a \c opal_memory_unpin_fn_t function pointer to be called + * whenever the current process is about to release memory. + * + * @param func Function pointer to call when memory is to be released + * @param cbdata A pointer-length field to be passed to func when it is + * invoked. + * + * @retval OMPI_SUCCESS The registration completed successfully. + * @retval OMPI_EXISTS The function is already registered and will not + * be registered again. + * @retval OMPI_ERR_NOT_SUPPORTED There are no hooks available for + * receiving callbacks when memory is to be released + */ +int opal_mem_free_register_handler(opal_memory_unpin_t *func, void *cbdata); + + +/** + * Unregister previously registered callback + * + * Unregister previously registered callback. + * + * @param func Function pointer to registered callback to remove + * + * @retval OMPI_SUCCESS The function was successfully deregistered + * @retval OMPI_ERR_NOT_FOUND The function was not previously registered + */ +int opal_mem_free_unregister_handler(opal_memory_unpin_t *func); + +#endif /* OPAL_MEMORY_MEMORY_H */ diff --git a/opal/memory/memory_internal.h b/opal/memory/memory_internal.h new file mode 100644 index 0000000000..db4800f942 --- /dev/null +++ b/opal/memory/memory_internal.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University. + * All rights reserved. + * Copyright (c) 2004-2005 The Trustees of the University of Tennessee. + * 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$ + */ + +#ifndef OPAL_MEMORY_MEMORY_INTERNAL_H +#define OPAL_MEMORY_MEMORY_INTERNAL_H + +void opal_mem_free_release_hook(void *buf, size_t length); + +#endif /* OPAL_MEMORY_MEMORY_INTERNAL_H */