summaryrefslogtreecommitdiffstats
path: root/src/H5B2cache.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2016-12-02 16:07:04 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2016-12-02 16:07:04 (GMT)
commit64a339183f0e4532597744351548308203e993c8 (patch)
treeddfff2f15c0f3a01782f191a847665c6eceadd42 /src/H5B2cache.c
parent5d7d029b97b36d1c380cef82d637342921bf3a1d (diff)
downloadhdf5-64a339183f0e4532597744351548308203e993c8.zip
hdf5-64a339183f0e4532597744351548308203e993c8.tar.gz
hdf5-64a339183f0e4532597744351548308203e993c8.tar.bz2
Bring SWMR support in to the main development branch. (Finally!) More tests
and the tool and API wrappers will be coming in over the weekend.
Diffstat (limited to 'src/H5B2cache.c')
-rw-r--r--src/H5B2cache.c254
1 files changed, 246 insertions, 8 deletions
diff --git a/src/H5B2cache.c b/src/H5B2cache.c
index 51ad32b..6954e6c 100644
--- a/src/H5B2cache.c
+++ b/src/H5B2cache.c
@@ -72,6 +72,7 @@ static void *H5B2__cache_hdr_deserialize(const void *image, size_t len,
static herr_t H5B2__cache_hdr_image_len(const void *thing, size_t *image_len);
static herr_t H5B2__cache_hdr_serialize(const H5F_t *f, void *image, size_t len,
void *thing);
+static herr_t H5B2__cache_hdr_notify(H5AC_notify_action_t action, void *thing);
static herr_t H5B2__cache_hdr_free_icr(void *thing);
static herr_t H5B2__cache_int_get_initial_load_size(void *udata, size_t *image_len);
@@ -81,6 +82,7 @@ static void *H5B2__cache_int_deserialize(const void *image, size_t len,
static herr_t H5B2__cache_int_image_len(const void *thing, size_t *image_len);
static herr_t H5B2__cache_int_serialize(const H5F_t *f, void *image, size_t len,
void *thing);
+static herr_t H5B2__cache_int_notify(H5AC_notify_action_t action, void *thing);
static herr_t H5B2__cache_int_free_icr(void *thing);
static herr_t H5B2__cache_leaf_get_initial_load_size(void *udata, size_t *image_len);
@@ -90,6 +92,7 @@ static void *H5B2__cache_leaf_deserialize(const void *image, size_t len,
static herr_t H5B2__cache_leaf_image_len(const void *thing, size_t *image_len);
static herr_t H5B2__cache_leaf_serialize(const H5F_t *f, void *image, size_t len,
void *thing);
+static herr_t H5B2__cache_leaf_notify(H5AC_notify_action_t action, void *thing);
static herr_t H5B2__cache_leaf_free_icr(void *thing);
/*********************/
@@ -109,7 +112,7 @@ const H5AC_class_t H5AC_BT2_HDR[1] = {{
H5B2__cache_hdr_image_len, /* 'image_len' callback */
NULL, /* 'pre_serialize' callback */
H5B2__cache_hdr_serialize, /* 'serialize' callback */
- NULL, /* 'notify' callback */
+ H5B2__cache_hdr_notify, /* 'notify' callback */
H5B2__cache_hdr_free_icr, /* 'free_icr' callback */
NULL, /* 'fsf_size' callback */
}};
@@ -127,7 +130,7 @@ const H5AC_class_t H5AC_BT2_INT[1] = {{
H5B2__cache_int_image_len, /* 'image_len' callback */
NULL, /* 'pre_serialize' callback */
H5B2__cache_int_serialize, /* 'serialize' callback */
- NULL, /* 'notify' callback */
+ H5B2__cache_int_notify, /* 'notify' callback */
H5B2__cache_int_free_icr, /* 'free_icr' callback */
NULL, /* 'fsf_size' callback */
}};
@@ -145,7 +148,7 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{
H5B2__cache_leaf_image_len, /* 'image_len' callback */
NULL, /* 'pre_serialize' callback */
H5B2__cache_leaf_serialize, /* 'serialize' callback */
- NULL, /* 'notify' callback */
+ H5B2__cache_leaf_notify, /* 'notify' callback */
H5B2__cache_leaf_free_icr, /* 'free_icr' callback */
NULL, /* 'fsf_size' callback */
}};
@@ -433,6 +436,91 @@ H5B2__cache_hdr_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED le
/*-------------------------------------------------------------------------
+ * Function: H5B2__cache_hdr_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * nfortne2@hdfgroup.org
+ * Apr 24 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B2__cache_hdr_notify(H5AC_notify_action_t action, void *_thing)
+{
+ H5B2_hdr_t *hdr = (H5B2_hdr_t *)_thing;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+
+ /* Check if the file was opened with SWMR-write access */
+ if(hdr->swmr_write) {
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_AFTER_INSERT:
+ case H5AC_NOTIFY_ACTION_AFTER_LOAD:
+ /* do nothing */
+ break;
+
+ case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
+ /* Increment the shadow epoch, forcing new modifications to
+ * internal and leaf nodes to create new shadow copies */
+ hdr->shadow_epoch++;
+ break;
+
+ case H5AC_NOTIFY_ACTION_ENTRY_DIRTIED:
+ case H5AC_NOTIFY_ACTION_ENTRY_CLEANED:
+ case H5AC_NOTIFY_ACTION_CHILD_DIRTIED:
+ case H5AC_NOTIFY_ACTION_CHILD_CLEANED:
+ /* do nothing */
+ break;
+
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* If hdr->parent != NULL, hdr->parent is used to destroy
+ * the flush dependency before the header is evicted.
+ */
+ if(hdr->parent) {
+ /* Sanity check */
+ HDassert(hdr->top_proxy);
+
+ /* Destroy flush dependency on object header proxy */
+ if(H5AC_proxy_entry_remove_child((H5AC_proxy_entry_t *)hdr->parent, (void *)hdr->top_proxy) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency between v2 B-tree and proxy")
+ hdr->parent = NULL;
+ } /* end if */
+
+ /* Detach from 'top' proxy for extensible array */
+ if(hdr->top_proxy) {
+ if(H5AC_proxy_entry_remove_child(hdr->top_proxy, hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency between header and v2 B-tree 'top' proxy")
+ /* Don't reset hdr->top_proxy here, it's destroyed when the header is freed -QAK */
+ } /* end if */
+ break;
+
+ default:
+#ifdef NDEBUG
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, FAIL, "unknown action from metadata cache")
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+ } /* end if */
+ else
+ HDassert(NULL == hdr->parent);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2__cache_hdr_notify() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2__cache_hdr_free_icr
*
* Purpose: Destroy/release an "in core representation" of a data
@@ -573,9 +661,8 @@ H5B2__cache_int_deserialize(const void *_image, size_t H5_ATTR_UNUSED len,
HDassert(udata);
/* Allocate new internal node and reset cache info */
- if(NULL == (internal = H5FL_MALLOC(H5B2_internal_t)))
+ if(NULL == (internal = H5FL_CALLOC(H5B2_internal_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDmemset(&internal->cache_info, 0, sizeof(H5AC_info_t));
/* Increment ref. count on B-tree header */
if(H5B2__hdr_incr(udata->hdr) < 0)
@@ -583,6 +670,8 @@ H5B2__cache_int_deserialize(const void *_image, size_t H5_ATTR_UNUSED len,
/* Share B-tree information */
internal->hdr = udata->hdr;
+ internal->parent = udata->parent;
+ internal->shadow_epoch = udata->hdr->shadow_epoch;
/* Magic number */
if(HDmemcmp(image, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC))
@@ -775,6 +864,80 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5B2__cache_int_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * nfortne2@hdfgroup.org
+ * Apr 25 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B2__cache_int_notify(H5AC_notify_action_t action, void *_thing)
+{
+ H5B2_internal_t *internal = (H5B2_internal_t *)_thing;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /*
+ * Check arguments.
+ */
+ HDassert(internal);
+ HDassert(internal->hdr);
+
+ /* Check if the file was opened with SWMR-write access */
+ if(internal->hdr->swmr_write) {
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_AFTER_INSERT:
+ case H5AC_NOTIFY_ACTION_AFTER_LOAD:
+ /* Create flush dependency on parent */
+ if(H5B2__create_flush_depend((H5AC_info_t *)internal->parent, (H5AC_info_t *)internal) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDEPEND, FAIL, "unable to create flush dependency")
+ break;
+
+ case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
+ case H5AC_NOTIFY_ACTION_ENTRY_DIRTIED:
+ case H5AC_NOTIFY_ACTION_ENTRY_CLEANED:
+ case H5AC_NOTIFY_ACTION_CHILD_DIRTIED:
+ case H5AC_NOTIFY_ACTION_CHILD_CLEANED:
+ /* do nothing */
+ break;
+
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* Destroy flush dependency on parent */
+ if(H5B2__destroy_flush_depend((H5AC_info_t *)internal->parent, (H5AC_info_t *)internal) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency")
+
+ /* Detach from 'top' proxy for v2 B-tree */
+ if(internal->top_proxy) {
+ if(H5AC_proxy_entry_remove_child(internal->top_proxy, internal) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency between internal node and v2 B-tree 'top' proxy")
+ internal->top_proxy = NULL;
+ } /* end if */
+ break;
+
+ default:
+#ifdef NDEBUG
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, FAIL, "unknown action from metadata cache")
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+ } /* end if */
+ else
+ HDassert(NULL == internal->top_proxy);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2__cache_int_notify() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2__cache_int_free_icr
*
* Purpose: Destroy/release an "in core representation" of a data
@@ -915,9 +1078,8 @@ H5B2__cache_leaf_deserialize(const void *_image, size_t H5_ATTR_UNUSED len,
HDassert(udata);
/* Allocate new leaf node and reset cache info */
- if(NULL == (leaf = H5FL_MALLOC(H5B2_leaf_t)))
+ if(NULL == (leaf = H5FL_CALLOC(H5B2_leaf_t)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed")
- HDmemset(&leaf->cache_info, 0, sizeof(H5AC_info_t));
/* Increment ref. count on B-tree header */
if(H5B2__hdr_incr(udata->hdr) < 0)
@@ -925,6 +1087,8 @@ H5B2__cache_leaf_deserialize(const void *_image, size_t H5_ATTR_UNUSED len,
/* Share B-tree header information */
leaf->hdr = udata->hdr;
+ leaf->parent = udata->parent;
+ leaf->shadow_epoch = udata->hdr->shadow_epoch;
/* Magic number */
if(HDmemcmp(image, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC))
@@ -1027,7 +1191,7 @@ H5B2__cache_leaf_image_len(const void *_thing, size_t *image_len)
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_leaf_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len,
+H5B2__cache_leaf_serialize(const H5F_t H5_ATTR_UNUSED *f, void *_image, size_t H5_ATTR_UNUSED len,
void *_thing)
{
H5B2_leaf_t *leaf = (H5B2_leaf_t *)_thing; /* Pointer to the B-tree leaf node */
@@ -1086,6 +1250,80 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5B2__cache_leaf_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * nfortne2@hdfgroup.org
+ * Apr 25 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B2__cache_leaf_notify(H5AC_notify_action_t action, void *_thing)
+{
+ H5B2_leaf_t *leaf = (H5B2_leaf_t *)_thing;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /*
+ * Check arguments.
+ */
+ HDassert(leaf);
+ HDassert(leaf->hdr);
+
+ /* Check if the file was opened with SWMR-write access */
+ if(leaf->hdr->swmr_write) {
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_AFTER_INSERT:
+ case H5AC_NOTIFY_ACTION_AFTER_LOAD:
+ /* Create flush dependency on parent */
+ if(H5B2__create_flush_depend((H5AC_info_t *)leaf->parent, (H5AC_info_t *)leaf) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDEPEND, FAIL, "unable to create flush dependency")
+ break;
+
+ case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
+ case H5AC_NOTIFY_ACTION_ENTRY_DIRTIED:
+ case H5AC_NOTIFY_ACTION_ENTRY_CLEANED:
+ case H5AC_NOTIFY_ACTION_CHILD_DIRTIED:
+ case H5AC_NOTIFY_ACTION_CHILD_CLEANED:
+ /* do nothing */
+ break;
+
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* Destroy flush dependency on parent */
+ if(H5B2__destroy_flush_depend((H5AC_info_t *)leaf->parent, (H5AC_info_t *)leaf) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency")
+
+ /* Detach from 'top' proxy for v2 B-tree */
+ if(leaf->top_proxy) {
+ if(H5AC_proxy_entry_remove_child(leaf->top_proxy, leaf) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency between leaf node and v2 B-tree 'top' proxy")
+ leaf->top_proxy = NULL;
+ } /* end if */
+ break;
+
+ default:
+#ifdef NDEBUG
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, FAIL, "unknown action from metadata cache")
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+ } /* end if */
+ else
+ HDassert(NULL == leaf->top_proxy);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2__cache_leaf_notify() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2__cache_leaf_free_icr
*
* Purpose: Destroy/release an "in core representation" of a data