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 }