root/opal/mca/mpool/base/mpool_base_tree.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mca_mpool_base_tree_node_compare
  2. mca_mpool_base_tree_init
  3. mca_mpool_base_tree_fini
  4. mca_mpool_base_tree_insert
  5. mca_mpool_base_tree_delete
  6. mca_mpool_base_tree_find
  7. mca_mpool_base_tree_item_get
  8. mca_mpool_base_tree_item_put
  9. mca_mpool_base_tree_print
  10. condition
  11. action

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2013 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.5A
  13  * Copyright (c) 2007      Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2007      Voltaire. All rights reserved.
  15  * Copyright (c) 2010      IBM Corporation.  All rights reserved.
  16  * Copyright (c) 2012-2015 Los Alamos National Security, LLC.
  17  *                         All rights reserved.
  18  * Copyright (c) 2015      Research Organization for Information Science
  19  *                         and Technology (RIST). All rights reserved.
  20  * Copyright (c) 2018      Amazon.com, Inc. or its affiliates.  All Rights reserved.
  21  * $COPYRIGHT$
  22  *
  23  * Additional copyrights may follow
  24  *
  25  * $HEADER$
  26  */
  27 
  28 #include "opal_config.h"
  29 
  30 #include "opal/mca/mca.h"
  31 #include "opal/util/show_help.h"
  32 #include "opal/util/proc.h"
  33 #include "opal/util/printf.h"
  34 
  35 #include "opal/class/opal_rb_tree.h"
  36 #include "mpool_base_tree.h"
  37 
  38 
  39 static int num_leaks = 0;
  40 static int max_mem_leaks = -1;
  41 static char *leak_msg = NULL;
  42 
  43 static int condition(void *value);
  44 static void action(void *key, void *value);
  45 
  46 OBJ_CLASS_INSTANCE(mca_mpool_base_tree_item_t, opal_free_list_item_t, NULL, NULL);
  47 
  48 /*
  49  * use globals for the tree and the tree_item free list..
  50  */
  51 opal_rb_tree_t mca_mpool_base_tree = {{0}};
  52 opal_free_list_t mca_mpool_base_tree_item_free_list = {{{0}}};
  53 static opal_mutex_t tree_lock;
  54 
  55 /*
  56  *  simple minded compare function...
  57  */
  58 int mca_mpool_base_tree_node_compare(void * key1, void * key2)
  59 {
  60     if(key1 < key2)
  61     {
  62         return -1;
  63     }
  64     else if(key1 > key2)
  65     {
  66         return 1;
  67     }
  68     else
  69     {
  70         return 0;
  71     }
  72 }
  73 
  74 /*
  75  * initialize the rb tree
  76  */
  77 int mca_mpool_base_tree_init(void) {
  78     int rc;
  79     OBJ_CONSTRUCT(&mca_mpool_base_tree, opal_rb_tree_t);
  80     OBJ_CONSTRUCT(&mca_mpool_base_tree_item_free_list, opal_free_list_t);
  81     OBJ_CONSTRUCT(&tree_lock, opal_mutex_t);
  82     rc = opal_free_list_init (&mca_mpool_base_tree_item_free_list,
  83             sizeof(mca_mpool_base_tree_item_t),
  84             opal_cache_line_size,
  85             OBJ_CLASS(mca_mpool_base_tree_item_t),
  86             0,opal_cache_line_size,
  87             0, -1 , 4, NULL, 0, NULL, NULL, NULL);
  88     if(OPAL_SUCCESS == rc) {
  89         rc = opal_rb_tree_init(&mca_mpool_base_tree, mca_mpool_base_tree_node_compare);
  90     }
  91     return rc;
  92 }
  93 
  94 /*
  95  *
  96  */
  97 int mca_mpool_base_tree_fini(void)
  98 {
  99     OBJ_DESTRUCT(&mca_mpool_base_tree);
 100     OBJ_DESTRUCT(&mca_mpool_base_tree_item_free_list);
 101     OBJ_DESTRUCT(&tree_lock);
 102     return OPAL_SUCCESS;
 103 }
 104 
 105 /*
 106  * insert an item in the rb tree
 107  */
 108 int mca_mpool_base_tree_insert(mca_mpool_base_tree_item_t* item) {
 109     int rc;
 110 
 111     OPAL_THREAD_LOCK(&tree_lock);
 112     rc = opal_rb_tree_insert(&mca_mpool_base_tree, item->key, item);
 113     OPAL_THREAD_UNLOCK(&tree_lock);
 114 
 115     return rc;
 116 }
 117 
 118 /*
 119  * remove an item from the rb tree
 120  * Does not put the item back onto the free list. That
 121  * must be done separately by calling mca_mpool_base_tree_item_put.
 122  * This allows a caller to remove an item from the tree
 123  * before safely cleaning up the item and only then returning it
 124  * to the free list. If the item is returned to the free list too soon
 125  * race conditions can occur
 126  *
 127  */
 128 int mca_mpool_base_tree_delete(mca_mpool_base_tree_item_t* item) {
 129     int rc;
 130 
 131     OPAL_THREAD_LOCK(&tree_lock);
 132     rc = opal_rb_tree_delete(&mca_mpool_base_tree, item->key);
 133     OPAL_THREAD_UNLOCK(&tree_lock);
 134 
 135     return rc;
 136 }
 137 
 138 /**
 139  *  find the item in the rb tree
 140  */
 141 mca_mpool_base_tree_item_t* mca_mpool_base_tree_find(void* base) {
 142     mca_mpool_base_tree_item_t* item;
 143 
 144     OPAL_THREAD_LOCK(&tree_lock);
 145     item = (mca_mpool_base_tree_item_t*)opal_rb_tree_find(&mca_mpool_base_tree,
 146             base);
 147     OPAL_THREAD_UNLOCK(&tree_lock);
 148 
 149     return item;
 150 }
 151 
 152 /*
 153  * get a tree item from the free list
 154  */
 155 mca_mpool_base_tree_item_t* mca_mpool_base_tree_item_get(void) {
 156     return (mca_mpool_base_tree_item_t *)
 157         opal_free_list_get (&mca_mpool_base_tree_item_free_list);
 158 }
 159 
 160 /*
 161  * put an item back into the free list
 162  */
 163 void mca_mpool_base_tree_item_put(mca_mpool_base_tree_item_t* item) {
 164     opal_free_list_return (&mca_mpool_base_tree_item_free_list,
 165                            &item->super);
 166 }
 167 
 168 
 169 /*
 170  * Print a show_help kind of message for an items still left in the
 171  * tree
 172  */
 173 void mca_mpool_base_tree_print(int show_up_to_mem_leaks)
 174 {
 175     /* If they asked to show 0 leaks, then don't show anything.  */
 176     if (0 == show_up_to_mem_leaks) {
 177         return;
 178     }
 179 
 180     num_leaks = 0;
 181     max_mem_leaks = show_up_to_mem_leaks;
 182     opal_rb_tree_traverse(&mca_mpool_base_tree, condition, action);
 183     if (0 == num_leaks) {
 184         return;
 185     }
 186 
 187     if (num_leaks <= show_up_to_mem_leaks ||
 188         show_up_to_mem_leaks < 0) {
 189         opal_show_help("help-mpool-base.txt", "all mem leaks",
 190                        true, OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 191                        opal_proc_local_get()->proc_hostname,
 192                        getpid(), leak_msg);
 193     } else {
 194         int i = num_leaks - show_up_to_mem_leaks;
 195         opal_show_help("help-mpool-base.txt", "some mem leaks",
 196                        true, OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 197                        opal_proc_local_get()->proc_hostname,
 198                        getpid(), leak_msg, i,
 199                        (i > 1) ? "s were" : " was",
 200                        (i > 1) ? "are" : "is");
 201     }
 202     free(leak_msg);
 203     leak_msg = NULL;
 204 }
 205 
 206 
 207 /* Condition function for rb traversal */
 208 static int condition(void *value)
 209 {
 210     return 1;
 211 }
 212 
 213 
 214 /* Action function for rb traversal */
 215 static void action(void *key, void *value)
 216 {
 217     char *tmp;
 218     mca_mpool_base_tree_item_t *item = (mca_mpool_base_tree_item_t *) value;
 219 
 220     if( (++num_leaks <= max_mem_leaks) || (max_mem_leaks < 0) ) {
 221 
 222         /* We know that we're supposed to make the first one; check on
 223            successive items if we're supposed to catenate more
 224            notices. */
 225         if (NULL == leak_msg) {
 226             opal_asprintf(&leak_msg, "    %lu bytes at address 0x%lx",
 227                      (unsigned long) item->num_bytes,
 228                      (unsigned long) key);
 229         } else {
 230             opal_asprintf(&tmp, "%s\n    %lu bytes at address 0x%lx",
 231                      leak_msg, (unsigned long) item->num_bytes,
 232                      (unsigned long) key);
 233             free(leak_msg);
 234             leak_msg = tmp;
 235         }
 236     }
 237 }

/* [<][>][^][v][top][bottom][index][help] */