This source file includes following definitions.
- opal_mem_hooks_finalize
- opal_mem_hooks_init
- opal_mem_hooks_set_support
- opal_mem_hooks_release_hook
- opal_mem_hooks_support_level
- opal_mem_hooks_register_release
- opal_mem_hooks_unregister_release
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 #include "opal_config.h"
  23 
  24 #ifdef HAVE_SYS_TYPES_H
  25 #include <sys/types.h>
  26 #endif  
  27 #ifdef HAVE_SYS_MMAN_H
  28 #include <sys/mman.h>
  29 #endif  
  30 
  31 #include "opal/constants.h"
  32 #include "opal/memoryhooks/memory.h"
  33 #include "opal/memoryhooks/memory_internal.h"
  34 #include "opal/class/opal_list.h"
  35 #include "opal/class/opal_object.h"
  36 #include "opal/sys/atomic.h"
  37 #include "opal/runtime/opal.h"
  38 
  39 
  40 
  41 
  42 struct callback_list_item_t {
  43     opal_list_item_t super;
  44     opal_mem_hooks_callback_fn_t *cbfunc;
  45     void *cbdata;
  46 };
  47 typedef struct callback_list_item_t callback_list_item_t;
  48 static OBJ_CLASS_INSTANCE(callback_list_item_t, opal_list_item_t, NULL, NULL);
  49 
  50 
  51 
  52 
  53 static int hooks_support = 0;
  54 
  55 static opal_list_t release_cb_list;
  56 static opal_atomic_lock_t release_lock;
  57 static int release_run_callbacks;
  58 
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 
  72 
  73 
  74 static void opal_mem_hooks_finalize(void)
  75 {
  76     
  77     release_run_callbacks = false;
  78     opal_atomic_mb();
  79 
  80     
  81 
  82 
  83     opal_atomic_lock(&release_lock);
  84 
  85     
  86     OPAL_LIST_DESTRUCT(&release_cb_list);
  87 
  88     opal_atomic_unlock(&release_lock);
  89 }
  90 
  91 int opal_mem_hooks_init (void)
  92 {
  93     OBJ_CONSTRUCT(&release_cb_list, opal_list_t);
  94 
  95     opal_atomic_lock_init(&release_lock, OPAL_ATOMIC_LOCK_UNLOCKED);
  96 
  97     
  98 
  99     release_run_callbacks = false;
 100     opal_atomic_mb();
 101 
 102     opal_finalize_register_cleanup (opal_mem_hooks_finalize);
 103 
 104     return OPAL_SUCCESS;
 105 }
 106 
 107 
 108 
 109 
 110 void
 111 opal_mem_hooks_set_support(int support)
 112 {
 113     hooks_support = support;
 114 }
 115 
 116 
 117 
 118 void
 119 opal_mem_hooks_release_hook(void *buf, size_t length, bool from_alloc)
 120 {
 121     callback_list_item_t *cbitem, *next;
 122 
 123     if (!release_run_callbacks) return;
 124 
 125     
 126 
 127 
 128 
 129 
 130 
 131 
 132 
 133 
 134 
 135     opal_atomic_lock(&release_lock);
 136     OPAL_LIST_FOREACH_SAFE(cbitem, next, &release_cb_list, callback_list_item_t) {
 137         opal_atomic_unlock(&release_lock);
 138         cbitem->cbfunc(buf, length, cbitem->cbdata, (bool) from_alloc);
 139         opal_atomic_lock(&release_lock);
 140     }
 141     opal_atomic_unlock(&release_lock);
 142 }
 143 
 144 
 145 int
 146 opal_mem_hooks_support_level(void)
 147 {
 148     return hooks_support;
 149 }
 150 
 151 
 152 int
 153 opal_mem_hooks_register_release(opal_mem_hooks_callback_fn_t *func, void *cbdata)
 154 {
 155     callback_list_item_t *cbitem, *new_cbitem;
 156     int ret = OPAL_SUCCESS;
 157 
 158     if (0 == ((OPAL_MEMORY_FREE_SUPPORT|OPAL_MEMORY_MUNMAP_SUPPORT) & hooks_support)) {
 159         return OPAL_ERR_NOT_SUPPORTED;
 160     }
 161 
 162     
 163 
 164 
 165     new_cbitem = OBJ_NEW(callback_list_item_t);
 166     if (NULL == new_cbitem) {
 167         ret = OPAL_ERR_OUT_OF_RESOURCE;
 168         goto done;
 169     }
 170 
 171     opal_atomic_lock(&release_lock);
 172     
 173 
 174 
 175     release_run_callbacks = true;
 176     opal_atomic_mb();
 177 
 178     
 179     OPAL_LIST_FOREACH(cbitem, &release_cb_list, callback_list_item_t) {
 180         if (cbitem->cbfunc == func) {
 181             ret = OPAL_EXISTS;
 182             goto done;
 183         }
 184     }
 185 
 186     new_cbitem->cbfunc = func;
 187     new_cbitem->cbdata = cbdata;
 188 
 189     opal_list_append(&release_cb_list, (opal_list_item_t*) new_cbitem);
 190 
 191  done:
 192     opal_atomic_unlock(&release_lock);
 193 
 194     if (OPAL_EXISTS == ret && NULL != new_cbitem) {
 195         OBJ_RELEASE(new_cbitem);
 196     }
 197 
 198     return ret;
 199 }
 200 
 201 
 202 int
 203 opal_mem_hooks_unregister_release(opal_mem_hooks_callback_fn_t* func)
 204 {
 205     callback_list_item_t *cbitem, *found_item = NULL;
 206     int ret = OPAL_ERR_NOT_FOUND;
 207 
 208     opal_atomic_lock(&release_lock);
 209 
 210     
 211     OPAL_LIST_FOREACH(cbitem, &release_cb_list, callback_list_item_t) {
 212         if (cbitem->cbfunc == func) {
 213             opal_list_remove_item(&release_cb_list, (opal_list_item_t *) cbitem);
 214             found_item = cbitem;
 215             ret = OPAL_SUCCESS;
 216             break;
 217         }
 218     }
 219 
 220     opal_atomic_unlock(&release_lock);
 221 
 222     
 223 
 224     if (NULL != found_item) {
 225         OBJ_RELEASE(found_item);
 226     }
 227 
 228     return ret;
 229 }