/src/hdf5/src/H5ACproxy_entry.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | | * Copyright by The HDF Group. * |
3 | | * All rights reserved. * |
4 | | * * |
5 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
6 | | * terms governing use, modification, and redistribution, is contained in * |
7 | | * the LICENSE file, which can be found at the root of the source code * |
8 | | * distribution tree, or in https://www.hdfgroup.org/licenses. * |
9 | | * If you do not have access to either file, you may request a copy from * |
10 | | * help@hdfgroup.org. * |
11 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
12 | | |
13 | | /*------------------------------------------------------------------------- |
14 | | * |
15 | | * Created: H5ACproxy_entry.c |
16 | | * |
17 | | * Purpose: Functions and a cache client for a "proxy" cache entry. |
18 | | * A proxy cache entry is used as a placeholder for entire |
19 | | * data structures to attach flush dependencies, etc. |
20 | | * |
21 | | *------------------------------------------------------------------------- |
22 | | */ |
23 | | |
24 | | /****************/ |
25 | | /* Module Setup */ |
26 | | /****************/ |
27 | | #include "H5ACmodule.h" /* This source code file is part of the H5AC module */ |
28 | | |
29 | | /***********/ |
30 | | /* Headers */ |
31 | | /***********/ |
32 | | #include "H5private.h" /* Generic Functions */ |
33 | | #include "H5ACpkg.h" /* Metadata cache */ |
34 | | #include "H5Eprivate.h" /* Error handling */ |
35 | | #include "H5FLprivate.h" /* Free Lists */ |
36 | | #include "H5MFprivate.h" /* File memory management */ |
37 | | #include "H5SLprivate.h" /* Skip Lists */ |
38 | | |
39 | | /****************/ |
40 | | /* Local Macros */ |
41 | | /****************/ |
42 | | |
43 | | /******************/ |
44 | | /* Local Typedefs */ |
45 | | /******************/ |
46 | | |
47 | | /********************/ |
48 | | /* Package Typedefs */ |
49 | | /********************/ |
50 | | |
51 | | /********************/ |
52 | | /* Local Prototypes */ |
53 | | /********************/ |
54 | | |
55 | | /* Metadata cache (H5AC) callbacks */ |
56 | | static herr_t H5AC__proxy_entry_image_len(const void *thing, size_t *image_len); |
57 | | static herr_t H5AC__proxy_entry_serialize(const H5F_t *f, void *image_ptr, size_t len, void *thing); |
58 | | static herr_t H5AC__proxy_entry_notify(H5AC_notify_action_t action, void *thing); |
59 | | static herr_t H5AC__proxy_entry_free_icr(void *thing); |
60 | | |
61 | | /*********************/ |
62 | | /* Package Variables */ |
63 | | /*********************/ |
64 | | |
65 | | /* H5AC proxy entries inherit cache-like properties from H5AC */ |
66 | | const H5AC_class_t H5AC_PROXY_ENTRY[1] = {{ |
67 | | H5AC_PROXY_ENTRY_ID, /* Metadata client ID */ |
68 | | "Proxy entry", /* Metadata client name (for debugging) */ |
69 | | H5FD_MEM_SUPER, /* File space memory type for client */ |
70 | | 0, /* Client class behavior flags */ |
71 | | NULL, /* 'get_initial_load_size' callback */ |
72 | | NULL, /* 'get_final_load_size' callback */ |
73 | | NULL, /* 'verify_chksum' callback */ |
74 | | NULL, /* 'deserialize' callback */ |
75 | | H5AC__proxy_entry_image_len, /* 'image_len' callback */ |
76 | | NULL, /* 'pre_serialize' callback */ |
77 | | H5AC__proxy_entry_serialize, /* 'serialize' callback */ |
78 | | H5AC__proxy_entry_notify, /* 'notify' callback */ |
79 | | H5AC__proxy_entry_free_icr, /* 'free_icr' callback */ |
80 | | NULL, /* 'fsf_size' callback */ |
81 | | }}; |
82 | | |
83 | | /*****************************/ |
84 | | /* Library Private Variables */ |
85 | | /*****************************/ |
86 | | |
87 | | /*******************/ |
88 | | /* Local Variables */ |
89 | | /*******************/ |
90 | | |
91 | | /* Declare a free list to manage H5AC_proxy_entry_t objects */ |
92 | | H5FL_DEFINE_STATIC(H5AC_proxy_entry_t); |
93 | | |
94 | | /*------------------------------------------------------------------------- |
95 | | * Function: H5AC_proxy_entry_create |
96 | | * |
97 | | * Purpose: Create a new proxy entry |
98 | | * |
99 | | * Return: Success: Pointer to the new proxy entry object. |
100 | | * Failure: NULL |
101 | | * |
102 | | *------------------------------------------------------------------------- |
103 | | */ |
104 | | H5AC_proxy_entry_t * |
105 | | H5AC_proxy_entry_create(void) |
106 | 0 | { |
107 | 0 | H5AC_proxy_entry_t *pentry = NULL; /* Pointer to new proxy entry */ |
108 | 0 | H5AC_proxy_entry_t *ret_value = NULL; /* Return value */ |
109 | |
|
110 | 0 | FUNC_ENTER_NOAPI(NULL) |
111 | | |
112 | | /* Allocate new proxy entry */ |
113 | 0 | if (NULL == (pentry = H5FL_CALLOC(H5AC_proxy_entry_t))) |
114 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "can't allocate proxy entry"); |
115 | | |
116 | | /* Set non-zero fields */ |
117 | 0 | pentry->addr = HADDR_UNDEF; |
118 | | |
119 | | /* Set return value */ |
120 | 0 | ret_value = pentry; |
121 | |
|
122 | 0 | done: |
123 | | /* Release resources on error */ |
124 | 0 | if (!ret_value) |
125 | 0 | if (pentry) |
126 | 0 | pentry = H5FL_FREE(H5AC_proxy_entry_t, pentry); |
127 | |
|
128 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
129 | 0 | } /* end H5AC_proxy_entry_create() */ |
130 | | |
131 | | /*------------------------------------------------------------------------- |
132 | | * Function: H5AC_proxy_entry_add_parent |
133 | | * |
134 | | * Purpose: Add a parent to a proxy entry |
135 | | * |
136 | | * Return: Non-negative on success/Negative on failure |
137 | | * |
138 | | *------------------------------------------------------------------------- |
139 | | */ |
140 | | herr_t |
141 | | H5AC_proxy_entry_add_parent(H5AC_proxy_entry_t *pentry, void *_parent) |
142 | 0 | { |
143 | 0 | H5AC_info_t *parent = (H5AC_info_t *)_parent; /* Parent entry's cache info */ |
144 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
145 | |
|
146 | 0 | FUNC_ENTER_NOAPI(FAIL) |
147 | | |
148 | | /* Sanity checks */ |
149 | 0 | assert(parent); |
150 | 0 | assert(pentry); |
151 | | |
152 | | /* Add parent to the list of parents */ |
153 | 0 | if (NULL == pentry->parents) |
154 | 0 | if (NULL == (pentry->parents = H5SL_create(H5SL_TYPE_HADDR, NULL))) |
155 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, |
156 | 0 | "unable to create skip list for parents of proxy entry"); |
157 | | |
158 | | /* Insert parent address into skip list */ |
159 | 0 | if (H5SL_insert(pentry->parents, parent, &parent->addr) < 0) |
160 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, "unable to insert parent into proxy's skip list"); |
161 | | |
162 | | /* Add flush dependency on parent */ |
163 | 0 | if (pentry->nchildren > 0) { |
164 | | /* Sanity check */ |
165 | 0 | assert(H5_addr_defined(pentry->addr)); |
166 | |
|
167 | 0 | if (H5AC_create_flush_dependency(parent, pentry) < 0) |
168 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "unable to set flush dependency on proxy entry"); |
169 | 0 | } /* end if */ |
170 | | |
171 | 0 | done: |
172 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
173 | 0 | } /* end H5AC_proxy_entry_add_parent() */ |
174 | | |
175 | | /*------------------------------------------------------------------------- |
176 | | * Function: H5AC_proxy_entry_remove_parent |
177 | | * |
178 | | * Purpose: Removes a parent from a proxy entry |
179 | | * |
180 | | * Return: Non-negative on success/Negative on failure |
181 | | * |
182 | | *------------------------------------------------------------------------- |
183 | | */ |
184 | | herr_t |
185 | | H5AC_proxy_entry_remove_parent(H5AC_proxy_entry_t *pentry, void *_parent) |
186 | 0 | { |
187 | 0 | H5AC_info_t *parent = (H5AC_info_t *)_parent; /* Pointer to the parent entry */ |
188 | 0 | H5AC_info_t *rem_parent; /* Pointer to the removed parent entry */ |
189 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
190 | |
|
191 | 0 | FUNC_ENTER_NOAPI(FAIL) |
192 | | |
193 | | /* Sanity checks */ |
194 | 0 | assert(pentry); |
195 | 0 | assert(pentry->parents); |
196 | 0 | assert(parent); |
197 | | |
198 | | /* Remove parent from skip list */ |
199 | 0 | if (NULL == (rem_parent = (H5AC_info_t *)H5SL_remove(pentry->parents, &parent->addr))) |
200 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "unable to remove proxy entry parent from skip list"); |
201 | 0 | if (!H5_addr_eq(rem_parent->addr, parent->addr)) |
202 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "removed proxy entry parent not the same as real parent"); |
203 | | |
204 | | /* Shut down the skip list, if this is the last parent */ |
205 | 0 | if (0 == H5SL_count(pentry->parents)) { |
206 | | /* Sanity check */ |
207 | 0 | assert(0 == pentry->nchildren); |
208 | |
|
209 | 0 | if (H5SL_close(pentry->parents) < 0) |
210 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CLOSEERROR, FAIL, "can't close proxy parent skip list"); |
211 | 0 | pentry->parents = NULL; |
212 | 0 | } /* end if */ |
213 | | |
214 | | /* Remove flush dependency between the proxy entry and a parent */ |
215 | 0 | if (pentry->nchildren > 0) |
216 | 0 | if (H5AC_destroy_flush_dependency(parent, pentry) < 0) |
217 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, |
218 | 0 | "unable to remove flush dependency on proxy entry"); |
219 | | |
220 | 0 | done: |
221 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
222 | 0 | } /* end H5AC_proxy_entry_remove_parent() */ |
223 | | |
224 | | /*------------------------------------------------------------------------- |
225 | | * Function: H5AC__proxy_entry_add_child_cb |
226 | | * |
227 | | * Purpose: Callback routine for adding an entry as a flush dependency for |
228 | | * a proxy entry. |
229 | | * |
230 | | * Return: Success: Non-negative on success |
231 | | * Failure: Negative |
232 | | * |
233 | | *------------------------------------------------------------------------- |
234 | | */ |
235 | | static int |
236 | | H5AC__proxy_entry_add_child_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) |
237 | 0 | { |
238 | 0 | H5AC_info_t *parent = (H5AC_info_t *)_item; /* Pointer to the parent entry */ |
239 | 0 | H5AC_proxy_entry_t *pentry = (H5AC_proxy_entry_t *)_udata; /* Pointer to the proxy entry */ |
240 | 0 | int ret_value = H5_ITER_CONT; /* Callback return value */ |
241 | |
|
242 | 0 | FUNC_ENTER_PACKAGE |
243 | | |
244 | | /* Add flush dependency on parent for proxy entry */ |
245 | 0 | if (H5AC_create_flush_dependency(parent, pentry) < 0) |
246 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, H5_ITER_ERROR, |
247 | 0 | "unable to set flush dependency for virtual entry"); |
248 | | |
249 | 0 | done: |
250 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
251 | 0 | } /* end H5AC__proxy_entry_add_child_cb() */ |
252 | | |
253 | | /*------------------------------------------------------------------------- |
254 | | * Function: H5AC_proxy_entry_add_child |
255 | | * |
256 | | * Purpose: Add a child a proxy entry |
257 | | * |
258 | | * Return: Non-negative on success/Negative on failure |
259 | | * |
260 | | *------------------------------------------------------------------------- |
261 | | */ |
262 | | herr_t |
263 | | H5AC_proxy_entry_add_child(H5AC_proxy_entry_t *pentry, H5F_t *f, void *child) |
264 | 0 | { |
265 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
266 | |
|
267 | 0 | FUNC_ENTER_NOAPI(FAIL) |
268 | | |
269 | | /* Sanity checks */ |
270 | 0 | assert(pentry); |
271 | 0 | assert(child); |
272 | | |
273 | | /* Check for first child */ |
274 | 0 | if (0 == pentry->nchildren) { |
275 | | /* Get an address, if the proxy doesn't already have one */ |
276 | 0 | if (!H5_addr_defined(pentry->addr)) |
277 | 0 | if (HADDR_UNDEF == (pentry->addr = H5MF_alloc_tmp(f, 1))) |
278 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, |
279 | 0 | "temporary file space allocation failed for proxy entry"); |
280 | | |
281 | | /* Insert the proxy entry into the cache */ |
282 | 0 | if (H5AC_insert_entry(f, H5AC_PROXY_ENTRY, pentry->addr, pentry, H5AC__PIN_ENTRY_FLAG) < 0) |
283 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, "unable to cache proxy entry"); |
284 | | |
285 | | /* Proxies start out clean (insertions are automatically marked dirty) */ |
286 | 0 | if (H5AC_mark_entry_clean(pentry) < 0) |
287 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTCLEAN, FAIL, "can't mark proxy entry clean"); |
288 | | |
289 | | /* Proxies start out serialized (insertions are automatically marked unserialized) */ |
290 | 0 | if (H5AC_mark_entry_serialized(pentry) < 0) |
291 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTSERIALIZE, FAIL, "can't mark proxy entry clean"); |
292 | | |
293 | | /* If there are currently parents, iterate over the list of parents, creating flush dependency on them |
294 | | */ |
295 | 0 | if (pentry->parents) |
296 | 0 | if (H5SL_iterate(pentry->parents, H5AC__proxy_entry_add_child_cb, pentry) < 0) |
297 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "can't visit parents"); |
298 | 0 | } /* end if */ |
299 | | |
300 | | /* Add flush dependency on proxy entry */ |
301 | 0 | if (H5AC_create_flush_dependency(pentry, child) < 0) |
302 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "unable to set flush dependency on proxy entry"); |
303 | | |
304 | | /* Increment count of children */ |
305 | 0 | pentry->nchildren++; |
306 | |
|
307 | 0 | done: |
308 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
309 | 0 | } /* end H5AC_proxy_entry_add_child() */ |
310 | | |
311 | | /*------------------------------------------------------------------------- |
312 | | * Function: H5AC__proxy_entry_remove_child_cb |
313 | | * |
314 | | * Purpose: Callback routine for removing an entry as a flush dependency for |
315 | | * proxy entry. |
316 | | * |
317 | | * Return: Success: Non-negative on success |
318 | | * Failure: Negative |
319 | | * |
320 | | *------------------------------------------------------------------------- |
321 | | */ |
322 | | static int |
323 | | H5AC__proxy_entry_remove_child_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) |
324 | 0 | { |
325 | 0 | H5AC_info_t *parent = (H5AC_info_t *)_item; /* Pointer to the parent entry */ |
326 | 0 | H5AC_proxy_entry_t *pentry = (H5AC_proxy_entry_t *)_udata; /* Pointer to the proxy entry */ |
327 | 0 | int ret_value = H5_ITER_CONT; /* Callback return value */ |
328 | |
|
329 | 0 | FUNC_ENTER_PACKAGE |
330 | | |
331 | | /* Remove flush dependency on parent for proxy entry */ |
332 | 0 | if (H5AC_destroy_flush_dependency(parent, pentry) < 0) |
333 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, H5_ITER_ERROR, |
334 | 0 | "unable to remove flush dependency for proxy entry"); |
335 | | |
336 | 0 | done: |
337 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
338 | 0 | } /* end H5AC__proxy_entry_remove_child_cb() */ |
339 | | |
340 | | /*------------------------------------------------------------------------- |
341 | | * Function: H5AC_proxy_entry_remove_child |
342 | | * |
343 | | * Purpose: Remove a child a proxy entry |
344 | | * |
345 | | * Return: Non-negative on success/Negative on failure |
346 | | * |
347 | | *------------------------------------------------------------------------- |
348 | | */ |
349 | | herr_t |
350 | | H5AC_proxy_entry_remove_child(H5AC_proxy_entry_t *pentry, void *child) |
351 | 0 | { |
352 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
353 | |
|
354 | 0 | FUNC_ENTER_NOAPI(FAIL) |
355 | | |
356 | | /* Sanity checks */ |
357 | 0 | assert(pentry); |
358 | 0 | assert(child); |
359 | | |
360 | | /* Remove flush dependency on proxy entry */ |
361 | 0 | if (H5AC_destroy_flush_dependency(pentry, child) < 0) |
362 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "unable to remove flush dependency on proxy entry"); |
363 | | |
364 | | /* Decrement count of children */ |
365 | 0 | pentry->nchildren--; |
366 | | |
367 | | /* Check for last child */ |
368 | 0 | if (0 == pentry->nchildren) { |
369 | | /* Check for flush dependencies on proxy's parents */ |
370 | 0 | if (pentry->parents) |
371 | | /* Iterate over the list of parents, removing flush dependency on them */ |
372 | 0 | if (H5SL_iterate(pentry->parents, H5AC__proxy_entry_remove_child_cb, pentry) < 0) |
373 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "can't visit parents"); |
374 | | |
375 | | /* Unpin proxy */ |
376 | 0 | if (H5AC_unpin_entry(pentry) < 0) |
377 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "can't unpin proxy entry"); |
378 | | |
379 | | /* Remove proxy entry from cache */ |
380 | 0 | if (H5AC_remove_entry(pentry) < 0) |
381 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "unable to remove proxy entry"); |
382 | 0 | } /* end if */ |
383 | | |
384 | 0 | done: |
385 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
386 | 0 | } /* end H5AC_proxy_entry_remove_child() */ |
387 | | |
388 | | /*------------------------------------------------------------------------- |
389 | | * Function: H5AC_proxy_entry_dest |
390 | | * |
391 | | * Purpose: Destroys a proxy entry in memory. |
392 | | * |
393 | | * Return: Non-negative on success/Negative on failure |
394 | | * |
395 | | *------------------------------------------------------------------------- |
396 | | */ |
397 | | herr_t |
398 | | H5AC_proxy_entry_dest(H5AC_proxy_entry_t *pentry) |
399 | 0 | { |
400 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
401 | |
|
402 | 0 | FUNC_ENTER_NOAPI(FAIL) |
403 | | |
404 | | /* Sanity checks */ |
405 | 0 | assert(pentry); |
406 | 0 | assert(NULL == pentry->parents); |
407 | 0 | assert(0 == pentry->nchildren); |
408 | 0 | assert(0 == pentry->ndirty_children); |
409 | 0 | assert(0 == pentry->nunser_children); |
410 | | |
411 | | /* Free the proxy entry object */ |
412 | 0 | pentry = H5FL_FREE(H5AC_proxy_entry_t, pentry); |
413 | |
|
414 | 0 | done: |
415 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
416 | 0 | } /* end H5AC_proxy_entry_dest() */ |
417 | | |
418 | | /*------------------------------------------------------------------------- |
419 | | * Function: H5AC__proxy_entry_image_len |
420 | | * |
421 | | * Purpose: Compute the size of the data structure on disk. |
422 | | * |
423 | | * Return: Non-negative on success/Negative on failure |
424 | | * |
425 | | *------------------------------------------------------------------------- |
426 | | */ |
427 | | static herr_t |
428 | | H5AC__proxy_entry_image_len(const void H5_ATTR_UNUSED *thing, size_t *image_len) |
429 | 0 | { |
430 | 0 | FUNC_ENTER_PACKAGE_NOERR |
431 | | |
432 | | /* Check arguments */ |
433 | 0 | assert(image_len); |
434 | | |
435 | | /* Set the image length size to 1 byte */ |
436 | 0 | *image_len = 1; |
437 | |
|
438 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
439 | 0 | } /* end H5AC__proxy_entry_image_len() */ |
440 | | |
441 | | /*------------------------------------------------------------------------- |
442 | | * Function: H5AC__proxy_entry_serialize |
443 | | * |
444 | | * Purpose: Serializes a data structure for writing to disk. |
445 | | * |
446 | | * Note: Should never be invoked. |
447 | | * |
448 | | * Return: Non-negative on success/Negative on failure |
449 | | * |
450 | | *------------------------------------------------------------------------- |
451 | | */ |
452 | | static herr_t |
453 | | H5AC__proxy_entry_serialize(const H5F_t H5_ATTR_UNUSED *f, void H5_ATTR_UNUSED *image, |
454 | | size_t H5_ATTR_UNUSED len, void H5_ATTR_UNUSED *thing) |
455 | 0 | { |
456 | 0 | FUNC_ENTER_PACKAGE_NOERR /* Yes, even though this pushes an error on the stack */ |
457 | 0 |
|
458 | 0 | /* Should never be invoked */ |
459 | 0 | assert(0 && "Invalid callback?!?"); |
460 | |
|
461 | 0 | HERROR(H5E_CACHE, H5E_CANTSERIALIZE, "called unreachable fcn."); |
462 | |
|
463 | 0 | FUNC_LEAVE_NOAPI(FAIL) |
464 | 0 | } /* end H5AC__proxy_entry_serialize() */ |
465 | | |
466 | | /*------------------------------------------------------------------------- |
467 | | * Function: H5AC__proxy_entry_notify |
468 | | * |
469 | | * Purpose: Handle cache action notifications |
470 | | * |
471 | | * Return: Non-negative on success/Negative on failure |
472 | | * |
473 | | *------------------------------------------------------------------------- |
474 | | */ |
475 | | static herr_t |
476 | | H5AC__proxy_entry_notify(H5AC_notify_action_t action, void *_thing) |
477 | 0 | { |
478 | 0 | H5AC_proxy_entry_t *pentry = (H5AC_proxy_entry_t *)_thing; |
479 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
480 | |
|
481 | 0 | FUNC_ENTER_PACKAGE |
482 | | |
483 | | /* Sanity check */ |
484 | 0 | assert(pentry); |
485 | |
|
486 | 0 | switch (action) { |
487 | 0 | case H5AC_NOTIFY_ACTION_AFTER_INSERT: |
488 | 0 | break; |
489 | | |
490 | 0 | case H5AC_NOTIFY_ACTION_AFTER_LOAD: |
491 | 0 | #ifdef NDEBUG |
492 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "invalid notify action from metadata cache"); |
493 | | #else /* NDEBUG */ |
494 | | assert(0 && "Invalid action?!?"); |
495 | | #endif /* NDEBUG */ |
496 | 0 | break; |
497 | | |
498 | 0 | case H5AC_NOTIFY_ACTION_AFTER_FLUSH: |
499 | 0 | #ifdef NDEBUG |
500 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "invalid notify action from metadata cache"); |
501 | | #else /* NDEBUG */ |
502 | | assert(0 && "Invalid action?!?"); |
503 | | #endif /* NDEBUG */ |
504 | 0 | break; |
505 | | |
506 | 0 | case H5AC_NOTIFY_ACTION_BEFORE_EVICT: |
507 | | /* Sanity checks */ |
508 | 0 | assert(0 == pentry->ndirty_children); |
509 | 0 | assert(0 == pentry->nunser_children); |
510 | | |
511 | | /* No action */ |
512 | 0 | break; |
513 | | |
514 | 0 | case H5AC_NOTIFY_ACTION_ENTRY_DIRTIED: |
515 | | /* Sanity checks */ |
516 | 0 | assert(pentry->ndirty_children > 0); |
517 | | |
518 | | /* No action */ |
519 | 0 | break; |
520 | | |
521 | 0 | case H5AC_NOTIFY_ACTION_ENTRY_CLEANED: |
522 | | /* Sanity checks */ |
523 | 0 | assert(0 == pentry->ndirty_children); |
524 | | |
525 | | /* No action */ |
526 | 0 | break; |
527 | | |
528 | 0 | case H5AC_NOTIFY_ACTION_CHILD_DIRTIED: |
529 | | /* Increment # of dirty children */ |
530 | 0 | pentry->ndirty_children++; |
531 | | |
532 | | /* Check for first dirty child */ |
533 | 0 | if (1 == pentry->ndirty_children) |
534 | 0 | if (H5AC_mark_entry_dirty(pentry) < 0) |
535 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTDIRTY, FAIL, "can't mark proxy entry dirty"); |
536 | 0 | break; |
537 | | |
538 | 0 | case H5AC_NOTIFY_ACTION_CHILD_CLEANED: |
539 | | /* Sanity check */ |
540 | 0 | assert(pentry->ndirty_children > 0); |
541 | | |
542 | | /* Decrement # of dirty children */ |
543 | 0 | pentry->ndirty_children--; |
544 | | |
545 | | /* Check for last dirty child */ |
546 | 0 | if (0 == pentry->ndirty_children) |
547 | 0 | if (H5AC_mark_entry_clean(pentry) < 0) |
548 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTCLEAN, FAIL, "can't mark proxy entry clean"); |
549 | 0 | break; |
550 | | |
551 | 0 | case H5AC_NOTIFY_ACTION_CHILD_UNSERIALIZED: |
552 | | /* Increment # of unserialized children */ |
553 | 0 | pentry->nunser_children++; |
554 | | |
555 | | /* Check for first unserialized child */ |
556 | 0 | if (1 == pentry->nunser_children) |
557 | 0 | if (H5AC_mark_entry_unserialized(pentry) < 0) |
558 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTUNSERIALIZE, FAIL, "can't mark proxy entry unserialized"); |
559 | 0 | break; |
560 | | |
561 | 0 | case H5AC_NOTIFY_ACTION_CHILD_SERIALIZED: |
562 | | /* Sanity check */ |
563 | 0 | assert(pentry->nunser_children > 0); |
564 | | |
565 | | /* Decrement # of unserialized children */ |
566 | 0 | pentry->nunser_children--; |
567 | | |
568 | | /* Check for last unserialized child */ |
569 | 0 | if (0 == pentry->nunser_children) |
570 | 0 | if (H5AC_mark_entry_serialized(pentry) < 0) |
571 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTSERIALIZE, FAIL, "can't mark proxy entry serialized"); |
572 | 0 | break; |
573 | | |
574 | 0 | default: |
575 | 0 | #ifdef NDEBUG |
576 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "unknown notify action from metadata cache"); |
577 | | #else /* NDEBUG */ |
578 | | assert(0 && "Unknown action?!?"); |
579 | | #endif /* NDEBUG */ |
580 | 0 | } /* end switch */ |
581 | | |
582 | 0 | done: |
583 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
584 | 0 | } /* end H5AC__proxy_entry_notify() */ |
585 | | |
586 | | /*------------------------------------------------------------------------- |
587 | | * Function: H5AC__proxy_entry_free_icr |
588 | | * |
589 | | * Purpose: Destroy/release an "in core representation" of a data |
590 | | * structure |
591 | | * |
592 | | * Return: Non-negative on success/Negative on failure |
593 | | * |
594 | | *------------------------------------------------------------------------- |
595 | | */ |
596 | | static herr_t |
597 | | H5AC__proxy_entry_free_icr(void *_thing) |
598 | 0 | { |
599 | 0 | H5AC_proxy_entry_t *pentry = (H5AC_proxy_entry_t *)_thing; |
600 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
601 | |
|
602 | 0 | FUNC_ENTER_PACKAGE |
603 | | |
604 | | /* Destroy the proxy entry */ |
605 | 0 | if (H5AC_proxy_entry_dest(pentry) < 0) |
606 | 0 | HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to destroy proxy entry"); |
607 | | |
608 | 0 | done: |
609 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
610 | 0 | } /* H5AC__proxy_entry_free_icr() */ |