mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-02-11 16:01:00 +08:00
[svn-r30112] Description:
Move updated flush dependency code in metadata cache from revise_chunks branch to trunk. Also many of the cleanups from r30111 in the revise_chunks branch. Tested on: MacOSX/64 10.11.5 (amazon) w/serial, parallel & production (h5committest forthcoming)
This commit is contained in:
parent
280907a9bf
commit
b8f809981b
107
src/H5AC.c
107
src/H5AC.c
@ -2075,113 +2075,6 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5AC__open_trace_file() */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************** Debugging Functions: ************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* Function: H5AC_get_entry_ptr_from_addr()
|
||||
*
|
||||
* Purpose: Debugging function that attempts to look up an entry in the
|
||||
* cache by its file address, and if found, returns a pointer
|
||||
* to the entry in *entry_ptr_ptr. If the entry is not in the
|
||||
* cache, *entry_ptr_ptr is set to NULL.
|
||||
*
|
||||
* WARNING: This call should be used only in debugging
|
||||
* routines, and it should be avoided when
|
||||
* possible.
|
||||
*
|
||||
* Further, if we ever multi-thread the cache,
|
||||
* this routine will have to be either discarded
|
||||
* or heavily re-worked.
|
||||
*
|
||||
* Finally, keep in mind that the entry whose
|
||||
* pointer is obtained in this fashion may not
|
||||
* be in a stable state.
|
||||
*
|
||||
* Note that this function is only defined if NDEBUG
|
||||
* is not defined.
|
||||
*
|
||||
* As heavy use of this function is almost certainly a
|
||||
* bad idea, the metadata cache tracks the number of
|
||||
* successful calls to this function, and (if
|
||||
* H5C_DO_SANITY_CHECKS is defined) displays any
|
||||
* non-zero count on cache shutdown.
|
||||
*
|
||||
* This function is just a wrapper that calls the H5C
|
||||
* version of the function.
|
||||
*
|
||||
* Return: FAIL if error is detected, SUCCEED otherwise.
|
||||
*
|
||||
* Programmer: John Mainzer, 5/30/14
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
herr_t
|
||||
H5AC_get_entry_ptr_from_addr(const H5F_t *f, haddr_t addr, void **entry_ptr_ptr)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
if(H5C_get_entry_ptr_from_addr(f, addr, entry_ptr_ptr) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_entry_ptr_from_addr() failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5AC_get_entry_ptr_from_addr() */
|
||||
#endif /* NDEBUG */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* Function: H5AC_verify_entry_type()
|
||||
*
|
||||
* Purpose: Debugging function that attempts to look up an entry in the
|
||||
* cache by its file address, and if found, test to see if its
|
||||
* type field contains the expected value.
|
||||
*
|
||||
* If the specified entry is in cache, *in_cache_ptr is set
|
||||
* to TRUE, and *type_ok_ptr is set to TRUE or FALSE
|
||||
* depending on whether the entries type field matches the
|
||||
* expected_type parameter
|
||||
*
|
||||
* If the target entry is not in cache, *in_cache_ptr is
|
||||
* set to FALSE, and *type_ok_ptr is undefined.
|
||||
*
|
||||
* Note that this function is only defined if NDEBUG
|
||||
* is not defined.
|
||||
*
|
||||
* This function is just a wrapper that calls the H5C
|
||||
* version of the function.
|
||||
*
|
||||
* Return: FAIL if error is detected, SUCCEED otherwise.
|
||||
*
|
||||
* Programmer: John Mainzer, 5/30/14
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
herr_t
|
||||
H5AC_verify_entry_type(const H5F_t *f, haddr_t addr, const H5AC_class_t *expected_type,
|
||||
hbool_t *in_cache_ptr, hbool_t *type_ok_ptr)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
if(H5C_verify_entry_type(f, addr, expected_type, in_cache_ptr, type_ok_ptr) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_verify_entry_type() failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5AC_verify_entry_type() */
|
||||
#endif /* NDEBUG */
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/**************************** Private Functions: *************************/
|
||||
|
@ -311,6 +311,7 @@ H5_DLLVAR hid_t H5AC_rawdata_dxpl_id;
|
||||
#define H5AC__TAKE_OWNERSHIP_FLAG H5C__TAKE_OWNERSHIP_FLAG
|
||||
#define H5AC__FLUSH_LAST_FLAG H5C__FLUSH_LAST_FLAG
|
||||
#define H5AC__FLUSH_COLLECTIVELY_FLAG H5C__FLUSH_COLLECTIVELY_FLAG
|
||||
#define H5AC__EVICT_ALLOW_LAST_PINS_FLAG H5C__EVICT_ALLOW_LAST_PINS_FLAG
|
||||
|
||||
|
||||
/* #defines of flags used to report entry status in the
|
||||
@ -380,11 +381,6 @@ H5_DLL herr_t H5AC_add_candidate(H5AC_t * cache_ptr, haddr_t addr);
|
||||
#ifndef NDEBUG /* debugging functions */
|
||||
H5_DLL herr_t H5AC_stats(const H5F_t *f);
|
||||
H5_DLL herr_t H5AC_dump_cache(const H5F_t *f);
|
||||
H5_DLL herr_t H5AC_get_entry_ptr_from_addr(const H5F_t *f, haddr_t addr,
|
||||
void ** entry_ptr_ptr);
|
||||
H5_DLL herr_t H5AC_verify_entry_type(const H5F_t * f, haddr_t addr,
|
||||
const H5AC_class_t * expected_type, hbool_t * in_cache_ptr,
|
||||
hbool_t * type_ok_ptr);
|
||||
#endif /* NDEBUG */ /* end debugging functions */
|
||||
|
||||
#endif /* !_H5ACprivate_H */
|
||||
|
24
src/H5Cpkg.h
24
src/H5Cpkg.h
@ -45,22 +45,13 @@
|
||||
/* Package Private Macros */
|
||||
/**************************/
|
||||
|
||||
/* With the introduction of the fractal heap, it is now possible for
|
||||
* entries to be dirtied, resized, and/or moved in the flush callbacks.
|
||||
* As a result, on flushes, it may be necessary to make multiple passes
|
||||
* through the slist before it is empty. The H5C__MAX_PASSES_ON_FLUSH
|
||||
* #define is used to set an upper limit on the number of passes.
|
||||
* The current value was obtained via personal communication with
|
||||
* Quincey. I have applied a fudge factor of 2.
|
||||
*
|
||||
* -- JRM
|
||||
*/
|
||||
#define H5C__MAX_PASSES_ON_FLUSH 4
|
||||
|
||||
/* Cache configuration settings */
|
||||
#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */
|
||||
#define H5C__H5C_T_MAGIC 0x005CAC0E
|
||||
|
||||
/* Initial allocated size of the "flush_dep_parent" array */
|
||||
#define H5C_FLUSH_DEP_PARENT_INIT 8
|
||||
|
||||
/* Cache client ID for epoch markers */
|
||||
/* Note that H5C__MAX_EPOCH_MARKERS is defined in H5Cprivate.h, not here because
|
||||
* it is needed to dimension arrays in H5C_t.
|
||||
@ -4063,11 +4054,6 @@ if ( ( (entry_ptr) == NULL ) || \
|
||||
* field is intended to allow marking of output of with
|
||||
* the processes mpi rank.
|
||||
*
|
||||
* get_entry_ptr_from_addr_counter: Counter used to track the number of
|
||||
* times the H5C_get_entry_ptr_from_addr() function has been
|
||||
* called successfully. This field is only defined when
|
||||
* NDEBUG is not #defined.
|
||||
*
|
||||
****************************************************************************/
|
||||
struct H5C_t {
|
||||
uint32_t magic;
|
||||
@ -4252,10 +4238,6 @@ struct H5C_t {
|
||||
#endif /* H5C_COLLECT_CACHE_STATS */
|
||||
|
||||
char prefix[H5C__PREFIX_LEN];
|
||||
|
||||
#ifndef NDEBUG
|
||||
int64_t get_entry_ptr_from_addr_counter;
|
||||
#endif /* NDEBUG */
|
||||
};
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
|
@ -97,14 +97,6 @@
|
||||
#define H5C__DEFAULT_MAX_CACHE_SIZE ((size_t)(4 * 1024 * 1024))
|
||||
#define H5C__DEFAULT_MIN_CLEAN_SIZE ((size_t)(2 * 1024 * 1024))
|
||||
|
||||
/* Maximum height of flush dependency relationships between entries. This is
|
||||
* currently tuned to the extensible array (H5EA) data structure, which only
|
||||
* requires 6 levels of dependency (i.e. heights 0-6) (actually, the extensible
|
||||
* array needs 4 levels, plus another 2 levels are needed: one for the layer
|
||||
* under the extensible array and one for the layer above it).
|
||||
*/
|
||||
#define H5C__NUM_FLUSH_DEP_HEIGHTS 6
|
||||
|
||||
/* Values for cache entry magic field */
|
||||
#define H5C__H5C_CACHE_ENTRY_T_MAGIC 0x005CAC0A
|
||||
#define H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC 0xDeadBeef
|
||||
@ -209,6 +201,7 @@
|
||||
#define H5C__TAKE_OWNERSHIP_FLAG 0x0800
|
||||
#define H5C__FLUSH_LAST_FLAG 0x1000
|
||||
#define H5C__FLUSH_COLLECTIVELY_FLAG 0x2000
|
||||
#define H5C__EVICT_ALLOW_LAST_PINS_FLAG 0x4000
|
||||
#define H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG 0x8000
|
||||
|
||||
/* Definitions for cache "tag" property */
|
||||
@ -1473,33 +1466,29 @@ typedef int H5C_ring_t;
|
||||
*
|
||||
* Fields supporting the 'flush dependency' feature:
|
||||
*
|
||||
* Entries in the cache may have a 'flush dependency' on another entry in the
|
||||
* Entries in the cache may have 'flush dependencies' on other entries in the
|
||||
* cache. A flush dependency requires that all dirty child entries be flushed
|
||||
* to the file before a dirty parent entry (of those child entries) can be
|
||||
* flushed to the file. This can be used by cache clients to create data
|
||||
* structures that allow Single-Writer/Multiple-Reader (SWMR) access for the
|
||||
* data structure.
|
||||
*
|
||||
* The leaf child entry will have a "height" of 0, with any parent entries
|
||||
* having a height of 1 greater than the maximum height of any of their child
|
||||
* entries (flush dependencies are allowed to create asymmetric trees of
|
||||
* relationships).
|
||||
* flush_dep_parent: Pointer to the array of flush dependency parent entries
|
||||
* for this entry.
|
||||
*
|
||||
* flush_dep_parent: Pointer to the parent entry for an entry in a flush
|
||||
* dependency relationship.
|
||||
* flush_dep_nparents: Number of flush dependency parent entries for this
|
||||
* entry, i.e. the number of valid elements in flush_dep_parent.
|
||||
*
|
||||
* child_flush_dep_height_rc: An array of reference counts for child entries,
|
||||
* where the number of children of each height is tracked.
|
||||
* flush_dep_parent_nalloc: The number of allocated elements in
|
||||
* flush_dep_parent_nalloc.
|
||||
*
|
||||
* flush_dep_height: The height of the entry, which is one greater than the
|
||||
* maximum height of any of its child entries..
|
||||
* flush_dep_nchildren: Number of flush dependency children for this entry. If
|
||||
* this field is nonzero, then this entry must be pinned and
|
||||
* therefore cannot be evicted.
|
||||
*
|
||||
* pinned_from_client: Whether the entry was pinned by an explicit pin request
|
||||
* from a cache client.
|
||||
*
|
||||
* pinned_from_cache: Whether the entry was pinned implicitly as a
|
||||
* request of being a parent entry in a flush dependency
|
||||
* relationship.
|
||||
* flush_dep_ndirty_children: Number of flush dependency children that are
|
||||
* either dirty or have a nonzero flush_dep_ndirty_children. If
|
||||
* this field is nonzero, then this entry cannot be flushed.
|
||||
*
|
||||
*
|
||||
* Fields supporting the hash table:
|
||||
@ -1644,9 +1633,11 @@ typedef struct H5C_cache_entry_t {
|
||||
H5C_ring_t ring;
|
||||
|
||||
/* fields supporting the 'flush dependency' feature: */
|
||||
struct H5C_cache_entry_t * flush_dep_parent;
|
||||
uint64_t child_flush_dep_height_rc[H5C__NUM_FLUSH_DEP_HEIGHTS];
|
||||
unsigned flush_dep_height;
|
||||
struct H5C_cache_entry_t ** flush_dep_parent;
|
||||
unsigned flush_dep_nparents;
|
||||
unsigned flush_dep_parent_nalloc;
|
||||
unsigned flush_dep_nchildren;
|
||||
unsigned flush_dep_ndirty_children;
|
||||
hbool_t pinned_from_client;
|
||||
hbool_t pinned_from_cache;
|
||||
|
||||
@ -2041,13 +2032,5 @@ H5_DLL herr_t H5C_mark_entries_as_clean(H5F_t *f, hid_t dxpl_id, int32_t ce_arra
|
||||
haddr_t *ce_array_ptr);
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
#ifndef NDEBUG /* debugging functions */
|
||||
H5_DLL herr_t H5C_get_entry_ptr_from_addr(const H5F_t *f, haddr_t addr,
|
||||
void **entry_ptr_ptr);
|
||||
H5_DLL herr_t H5C_verify_entry_type(const H5F_t *f, haddr_t addr,
|
||||
const H5C_class_t *expected_type, hbool_t *in_cache_ptr,
|
||||
hbool_t *type_ok_ptr);
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#endif /* !_H5Cprivate_H */
|
||||
|
||||
|
@ -277,9 +277,9 @@ H5C_get_entry_status(const H5F_t *f,
|
||||
if(is_corked_ptr != NULL)
|
||||
*is_corked_ptr = entry_ptr->is_corked;
|
||||
if(is_flush_dep_parent_ptr != NULL)
|
||||
*is_flush_dep_parent_ptr = (entry_ptr->flush_dep_height > 0);
|
||||
*is_flush_dep_parent_ptr = (entry_ptr->flush_dep_nchildren > 0);
|
||||
if(is_flush_dep_child_ptr != NULL)
|
||||
*is_flush_dep_child_ptr = (entry_ptr->flush_dep_parent != NULL);
|
||||
*is_flush_dep_child_ptr = (entry_ptr->flush_dep_nparents > 0);
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
|
189
src/H5EA.c
189
src/H5EA.c
@ -74,6 +74,11 @@ typedef herr_t (*H5EA__unprotect_func_t)(void *thing, hid_t dxpl_id,
|
||||
/* Local Prototypes */
|
||||
/********************/
|
||||
|
||||
static herr_t
|
||||
H5EA__lookup_elmt(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, hbool_t will_extend,
|
||||
unsigned thing_acc, void **thing, uint8_t **thing_elmt_buf,
|
||||
hsize_t *thing_elmt_idx, H5EA__unprotect_func_t *thing_unprot_func);
|
||||
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@ -133,10 +138,6 @@ H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam, void *ctx_udat
|
||||
H5EA_hdr_t *hdr = NULL; /* The extensible array header information */
|
||||
haddr_t ea_addr; /* Array header address */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
@ -213,9 +214,6 @@ H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata))
|
||||
HDassert(H5F_addr_defined(ea_addr));
|
||||
|
||||
/* Load the array header into memory */
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr);
|
||||
#endif /* QAK */
|
||||
if(NULL == (hdr = H5EA__hdr_protect(f, dxpl_id, ea_addr, ctx_udata, H5AC__READ_ONLY_FLAG)))
|
||||
H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header, address = %llu", (unsigned long long)ea_addr)
|
||||
|
||||
@ -272,10 +270,6 @@ H5EA_get_nelmts(const H5EA_t *ea, hsize_t *nelmts))
|
||||
|
||||
/* Local variables */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
@ -307,10 +301,6 @@ H5EA_get_addr(const H5EA_t *ea, haddr_t *addr))
|
||||
|
||||
/* Local variables */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
@ -325,7 +315,7 @@ END_FUNC(PRIV) /* end H5EA_get_addr() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5EA_lookup_elmt
|
||||
* Function: H5EA__lookup_elmt
|
||||
*
|
||||
* Purpose: Retrieve the metadata object and the element buffer for a
|
||||
* given element in the array.
|
||||
@ -340,9 +330,9 @@ END_FUNC(PRIV) /* end H5EA_get_addr() */
|
||||
*/
|
||||
BEGIN_FUNC(STATIC, ERR,
|
||||
herr_t, SUCCEED, FAIL,
|
||||
H5EA__lookup_elmt(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, unsigned thing_acc,
|
||||
void **thing, uint8_t **thing_elmt_buf, hsize_t *thing_elmt_idx,
|
||||
H5EA__unprotect_func_t *thing_unprot_func))
|
||||
H5EA__lookup_elmt(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, hbool_t will_extend,
|
||||
unsigned thing_acc, void **thing, uint8_t **thing_elmt_buf,
|
||||
hsize_t *thing_elmt_idx, H5EA__unprotect_func_t *thing_unprot_func))
|
||||
|
||||
/* Local variables */
|
||||
H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
|
||||
@ -355,11 +345,6 @@ H5EA__lookup_elmt(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, unsigned thing_a
|
||||
hbool_t stats_changed = FALSE; /* Whether array statistics changed */
|
||||
hbool_t hdr_dirty = FALSE; /* Whether the array header changed */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
@ -383,9 +368,6 @@ HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
|
||||
|
||||
/* Check if we should create the index block */
|
||||
if(!H5F_addr_defined(hdr->idx_blk_addr)) {
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Index block address not defined!\n", FUNC, idx);
|
||||
#endif /* QAK */
|
||||
/* Check if we are allowed to create the thing */
|
||||
if(0 == (thing_acc & H5AC__READ_ONLY_FLAG)) { /* i.e. r/w access */
|
||||
/* Create the index block */
|
||||
@ -397,9 +379,6 @@ HDfprintf(stderr, "%s: Index block address not defined!\n", FUNC, idx);
|
||||
else
|
||||
H5_LEAVE(SUCCEED)
|
||||
} /* end if */
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Index block address is: %a\n", FUNC, hdr->idx_blk_addr);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Protect index block */
|
||||
if(NULL == (iblock = H5EA__iblock_protect(hdr, dxpl_id, thing_acc)))
|
||||
@ -420,26 +399,14 @@ HDfprintf(stderr, "%s: Index block address is: %a\n", FUNC, hdr->idx_blk_addr);
|
||||
|
||||
/* Get super block index where element is located */
|
||||
sblk_idx = H5EA__dblock_sblk_idx(hdr, idx);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sblk_idx = %u, iblock->nsblks = %Zu\n", FUNC, sblk_idx, iblock->nsblks);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Adjust index to offset in super block */
|
||||
elmt_idx = idx - (hdr->cparam.idx_blk_elmts + hdr->sblk_info[sblk_idx].start_idx);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: after adjusting for super block elements, elmt_idx = %Hu\n", FUNC, elmt_idx);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Check for data block containing element address in the index block */
|
||||
if(sblk_idx < iblock->nsblks) {
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Element in data block pointed to by address in index block\n", FUNC);
|
||||
#endif /* QAK */
|
||||
/* Compute the data block index in index block */
|
||||
dblk_idx = (size_t)(hdr->sblk_info[sblk_idx].start_dblk + (elmt_idx / hdr->sblk_info[sblk_idx].dblk_nelmts));
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_idx, iblock->ndblk_addrs);
|
||||
#endif /* QAK */
|
||||
HDassert(dblk_idx < iblock->ndblk_addrs);
|
||||
|
||||
/* Check if the data block has been allocated on disk yet */
|
||||
@ -470,6 +437,13 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i
|
||||
/* Adjust index to offset in data block */
|
||||
elmt_idx %= hdr->sblk_info[sblk_idx].dblk_nelmts;
|
||||
|
||||
/* Check if there is already a dependency on the header */
|
||||
if(will_extend && !dblock->has_hdr_depend) {
|
||||
if(H5EA__create_flush_depend((H5AC_info_t *)hdr, (H5AC_info_t *)dblock) < 0)
|
||||
H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block and header, index = %llu", (unsigned long long)idx)
|
||||
dblock->has_hdr_depend = TRUE;
|
||||
} /* end if */
|
||||
|
||||
/* Set 'thing' info to refer to the data block */
|
||||
*thing = dblock;
|
||||
*thing_elmt_buf = (uint8_t *)dblock->elmts;
|
||||
@ -490,9 +464,6 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i
|
||||
|
||||
/* Create super block */
|
||||
sblk_addr = H5EA__sblock_create(hdr, dxpl_id, iblock, &stats_changed, sblk_idx);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: New super block address is: %a\n", FUNC, sblk_addr);
|
||||
#endif /* QAK */
|
||||
if(!H5F_addr_defined(sblk_addr))
|
||||
H5E_THROW(H5E_CANTCREATE, "unable to create extensible array super block")
|
||||
|
||||
@ -510,9 +481,6 @@ HDfprintf(stderr, "%s: New super block address is: %a\n", FUNC, sblk_addr);
|
||||
|
||||
/* Compute the data block index in super block */
|
||||
dblk_idx = (size_t)(elmt_idx / sblock->dblk_nelmts);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: dblk_idx = %u, sblock->ndblks = %Zu\n", FUNC, dblk_idx, sblock->ndblks);
|
||||
#endif /* QAK */
|
||||
HDassert(dblk_idx < sblock->ndblks);
|
||||
|
||||
/* Check if the data block has been allocated on disk yet */
|
||||
@ -531,21 +499,20 @@ HDfprintf(stderr, "%s: dblk_idx = %u, sblock->ndblks = %Zu\n", FUNC, dblk_idx, s
|
||||
/* Set data block address in index block */
|
||||
sblock->dblk_addrs[dblk_idx] = dblk_addr;
|
||||
sblock_cache_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Create flush dependency on header, if extending the array and one doesn't already exist */
|
||||
if(will_extend && !sblock->has_hdr_depend) {
|
||||
if(H5EA__create_flush_depend((H5AC_info_t *)sblock->hdr, (H5AC_info_t *)sblock) < 0)
|
||||
H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between super block and header, address = %llu", (unsigned long long)sblock->addr)
|
||||
sblock->has_hdr_depend = TRUE;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
else
|
||||
H5_LEAVE(SUCCEED)
|
||||
} /* end if */
|
||||
|
||||
#ifdef QAK
|
||||
if(sblock->dblk_npages)
|
||||
HDfprintf(stderr, "%s: Check 1.0: elmt_idx = %Hu\n", FUNC, elmt_idx);
|
||||
#endif /* QAK */
|
||||
/* Adjust index to offset in data block */
|
||||
elmt_idx %= sblock->dblk_nelmts;
|
||||
#ifdef QAK
|
||||
if(sblock->dblk_npages)
|
||||
HDfprintf(stderr, "%s: Check 2.0: elmt_idx = %Hu\n", FUNC, elmt_idx);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Check if the data block is paged */
|
||||
if(sblock->dblk_npages) {
|
||||
@ -566,14 +533,6 @@ if(sblock->dblk_npages)
|
||||
dblk_page_addr = sblock->dblk_addrs[dblk_idx] +
|
||||
H5EA_DBLOCK_PREFIX_SIZE(sblock) +
|
||||
(page_idx * sblock->dblk_page_size);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sblock->addr = %a\n", FUNC, sblock->addr);
|
||||
HDfprintf(stderr, "%s: sblock->dblk_addrs[%Zu] = %a\n", FUNC, dblk_idx, sblock->dblk_addrs[dblk_idx]);
|
||||
HDfprintf(stderr, "%s: H5EA_DBLOCK_PREFIX_SIZE(sblock) = %u\n", FUNC, (unsigned)H5EA_DBLOCK_PREFIX_SIZE(sblock));
|
||||
HDfprintf(stderr, "%s: sblock->page_init[%Zu] = %t\n", FUNC, page_init_idx, H5VM_bit_get(sblock->page_init, page_init_idx));
|
||||
HDfprintf(stderr, "%s: page_idx = %Zu, elmt_idx = %Hu, dblk_page_addr = %a\n", FUNC, page_idx, elmt_idx, dblk_page_addr);
|
||||
HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Check if page has been initialized yet */
|
||||
if(!H5VM_bit_get(sblock->page_init, page_init_idx)) {
|
||||
@ -595,6 +554,13 @@ HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_
|
||||
if(NULL == (dblk_page = H5EA__dblk_page_protect(hdr, dxpl_id, sblock, dblk_page_addr, thing_acc)))
|
||||
H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block page, address = %llu", (unsigned long long)dblk_page_addr)
|
||||
|
||||
/* Check if there is already a dependency on the header */
|
||||
if(will_extend && !dblk_page->has_hdr_depend) {
|
||||
if(H5EA__create_flush_depend((H5AC_info_t *)hdr, (H5AC_info_t *)dblk_page) < 0)
|
||||
H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block page and header, index = %llu", (unsigned long long)idx)
|
||||
dblk_page->has_hdr_depend = TRUE;
|
||||
} /* end if */
|
||||
|
||||
/* Set 'thing' info to refer to the data block page */
|
||||
*thing = dblk_page;
|
||||
*thing_elmt_buf = (uint8_t *)dblk_page->elmts;
|
||||
@ -606,6 +572,13 @@ HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_
|
||||
if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, thing_acc)))
|
||||
H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)sblock->dblk_addrs[dblk_idx])
|
||||
|
||||
/* Check if there is already a dependency on the header */
|
||||
if(will_extend && !dblock->has_hdr_depend) {
|
||||
if(H5EA__create_flush_depend((H5AC_info_t *)hdr, (H5AC_info_t *)dblock) < 0)
|
||||
H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block and header, index = %llu", (unsigned long long)idx)
|
||||
dblock->has_hdr_depend = TRUE;
|
||||
} /* end if */
|
||||
|
||||
/* Set 'thing' info to refer to the data block */
|
||||
*thing = dblock;
|
||||
*thing_elmt_buf = (uint8_t *)dblock->elmts;
|
||||
@ -615,6 +588,10 @@ HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(*thing != NULL);
|
||||
HDassert(*thing_unprot_func != NULL);
|
||||
|
||||
CATCH
|
||||
/* Reset 'thing' info on error */
|
||||
if(ret_value < 0) {
|
||||
@ -644,7 +621,7 @@ CATCH
|
||||
if(dblk_page && *thing != dblk_page && H5EA__dblk_page_unprotect(dblk_page, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
|
||||
H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array data block page")
|
||||
|
||||
END_FUNC(STATIC) /* end H5EA_lookup_elmt() */
|
||||
END_FUNC(STATIC) /* end H5EA__lookup_elmt() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -670,13 +647,9 @@ H5EA_set(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt))
|
||||
uint8_t *thing_elmt_buf; /* Pointer to the element buffer for the array metadata */
|
||||
hsize_t thing_elmt_idx; /* Index of the element in the element buffer for the array metadata */
|
||||
H5EA__unprotect_func_t thing_unprot_func; /* Function pointer for unprotecting the array metadata */
|
||||
hbool_t will_extend; /* Flag indicating if setting the element will extend the array */
|
||||
unsigned thing_cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting array metadata */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
@ -687,7 +660,8 @@ HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
|
||||
hdr->f = ea->f;
|
||||
|
||||
/* Look up the array metadata containing the element we want to set */
|
||||
if(H5EA__lookup_elmt(ea, dxpl_id, idx, H5AC__NO_FLAGS_SET, &thing, &thing_elmt_buf, &thing_elmt_idx, &thing_unprot_func) < 0)
|
||||
will_extend = (idx >= hdr->stats.stored.max_idx_set);
|
||||
if(H5EA__lookup_elmt(ea, dxpl_id, idx, will_extend, H5AC__NO_FLAGS_SET, &thing, &thing_elmt_buf, &thing_elmt_idx, &thing_unprot_func) < 0)
|
||||
H5E_THROW(H5E_CANTPROTECT, "unable to protect array metadata")
|
||||
|
||||
/* Sanity check */
|
||||
@ -700,10 +674,7 @@ HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
|
||||
thing_cache_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Update max. element set in array, if appropriate */
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: idx = %Hu, hdr->stats.max_idx_set = %Hu\n", FUNC, idx, hdr->stats.max_idx_set);
|
||||
#endif /* QAK */
|
||||
if(idx >= hdr->stats.stored.max_idx_set) {
|
||||
if(will_extend) {
|
||||
/* Update the max index for the array */
|
||||
hdr->stats.stored.max_idx_set = idx + 1;
|
||||
if(H5EA__hdr_modified(hdr) < 0)
|
||||
@ -740,11 +711,6 @@ H5EA_get(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt))
|
||||
void *thing = NULL; /* Pointer to the array metadata containing the array index we are interested in */
|
||||
H5EA__unprotect_func_t thing_unprot_func; /* Function pointer for unprotecting the array metadata */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
@ -753,9 +719,6 @@ HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
|
||||
|
||||
/* Check for element beyond max. element in array */
|
||||
if(idx >= hdr->stats.stored.max_idx_set) {
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Element beyond max. index set, hdr->stats.max_idx_set = %Hu, idx = %Hu\n", FUNC, hdr->stats.max_idx_set, idx);
|
||||
#endif /* QAK */
|
||||
/* Call the class's 'fill' callback */
|
||||
if((hdr->cparam.cls->fill)(elmt, (size_t)1) < 0)
|
||||
H5E_THROW(H5E_CANTSET, "can't set element to class's fill value")
|
||||
@ -764,15 +727,11 @@ HDfprintf(stderr, "%s: Element beyond max. index set, hdr->stats.max_idx_set = %
|
||||
uint8_t *thing_elmt_buf; /* Pointer to the element buffer for the array metadata */
|
||||
hsize_t thing_elmt_idx; /* Index of the element in the element buffer for the array metadata */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Index block address is: %a\n", FUNC, hdr->idx_blk_addr);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Set the shared array header's file context for this operation */
|
||||
hdr->f = ea->f;
|
||||
|
||||
/* Look up the array metadata containing the element we want to set */
|
||||
if(H5EA__lookup_elmt(ea, dxpl_id, idx, H5AC__READ_ONLY_FLAG, &thing, &thing_elmt_buf, &thing_elmt_idx, &thing_unprot_func) < 0)
|
||||
if(H5EA__lookup_elmt(ea, dxpl_id, idx, FALSE, H5AC__READ_ONLY_FLAG, &thing, &thing_elmt_buf, &thing_elmt_idx, &thing_unprot_func) < 0)
|
||||
H5E_THROW(H5E_CANTPROTECT, "unable to protect array metadata")
|
||||
|
||||
/* Check if the thing holding the element has been created yet */
|
||||
@ -815,10 +774,6 @@ H5EA_depend(H5AC_info_t *parent_entry, H5EA_t *ea))
|
||||
/* Local variables */
|
||||
H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
@ -836,49 +791,6 @@ CATCH
|
||||
|
||||
END_FUNC(PRIV) /* end H5EA_depend() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5EA_undepend
|
||||
*
|
||||
* Purpose: Remove a child flush dependency between the extensible array's
|
||||
* header and another piece of metadata in the file.
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@hdfgroup.org
|
||||
* May 27 2009
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
BEGIN_FUNC(PRIV, ERR,
|
||||
herr_t, SUCCEED, FAIL,
|
||||
H5EA_undepend(H5AC_info_t *parent_entry, H5EA_t *ea))
|
||||
|
||||
/* Local variables */
|
||||
H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
HDassert(ea);
|
||||
HDassert(hdr);
|
||||
|
||||
/* Set the shared array header's file context for this operation */
|
||||
hdr->f = ea->f;
|
||||
|
||||
/* Remove flush dependency between parent entry and extensible array header */
|
||||
if(H5EA__destroy_flush_depend(parent_entry, (H5AC_info_t *)hdr) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency on file metadata")
|
||||
|
||||
CATCH
|
||||
|
||||
END_FUNC(PRIV) /* end H5EA_undepend() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5EA_close
|
||||
@ -901,10 +813,6 @@ H5EA_close(H5EA_t *ea, hid_t dxpl_id))
|
||||
hbool_t pending_delete = FALSE; /* Whether the array is pending deletion */
|
||||
haddr_t ea_addr = HADDR_UNDEF; /* Address of array (for deletion) */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
@ -1009,9 +917,6 @@ H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata))
|
||||
HDassert(H5F_addr_defined(ea_addr));
|
||||
|
||||
/* Lock the array header into memory */
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr);
|
||||
#endif /* QAK */
|
||||
if(NULL == (hdr = H5EA__hdr_protect(f, dxpl_id, ea_addr, ctx_udata, H5AC__NO_FLAGS_SET)))
|
||||
H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array header, address = %llu", (unsigned long long)ea_addr)
|
||||
|
||||
|
@ -1179,13 +1179,25 @@ H5EA__cache_sblock_notify(H5AC_notify_action_t action, void *_thing))
|
||||
break;
|
||||
|
||||
case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
|
||||
/* do nothing */
|
||||
/* Destroy flush dependency on extensible array header, if set */
|
||||
if(sblock->has_hdr_depend) {
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)sblock->hdr, (H5AC_info_t *)sblock) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between super block and header, address = %llu", (unsigned long long)sblock->addr)
|
||||
sblock->has_hdr_depend = FALSE;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
|
||||
/* Destroy flush dependency on index block */
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)sblock->parent, (H5AC_info_t *)sblock) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between super block and index block, address = %llu", (unsigned long long)sblock->addr)
|
||||
|
||||
/* Destroy flush dependency on extensible array header, if set */
|
||||
if(sblock->has_hdr_depend) {
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)sblock->hdr, (H5AC_info_t *)sblock) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between super block and header, address = %llu", (unsigned long long)sblock->addr)
|
||||
sblock->has_hdr_depend = FALSE;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1534,13 +1546,25 @@ H5EA__cache_dblock_notify(H5AC_notify_action_t action, void *_thing))
|
||||
break;
|
||||
|
||||
case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
|
||||
/* do nothing */
|
||||
/* Destroy flush dependency on extensible array header, if set */
|
||||
if(dblock->has_hdr_depend) {
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)dblock->hdr, (H5AC_info_t *)dblock) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between direct block and header, address = %llu", (unsigned long long)dblock->addr)
|
||||
dblock->has_hdr_depend = FALSE;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
|
||||
/* Destroy flush dependency on parent */
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)dblock->parent, (H5AC_info_t *)dblock) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block and parent, address = %llu", (unsigned long long)dblock->addr)
|
||||
|
||||
/* Destroy flush dependency on extensible array header, if set */
|
||||
if(dblock->has_hdr_depend) {
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)dblock->hdr, (H5AC_info_t *)dblock) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between direct block and header, address = %llu", (unsigned long long)dblock->addr)
|
||||
dblock->has_hdr_depend = FALSE;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1856,13 +1880,25 @@ H5EA__cache_dblk_page_notify(H5AC_notify_action_t action, void *_thing))
|
||||
break;
|
||||
|
||||
case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
|
||||
/* do nothing */
|
||||
/* Destroy flush dependency on extensible array header, if set */
|
||||
if(dblk_page->has_hdr_depend) {
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)dblk_page->hdr, (H5AC_info_t *)dblk_page) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block page and header, address = %llu", (unsigned long long)dblk_page->addr)
|
||||
dblk_page->has_hdr_depend = FALSE;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
|
||||
/* Destroy flush dependency on parent */
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)dblk_page->parent, (H5AC_info_t *)dblk_page) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block page and parent, address = %llu", (unsigned long long)dblk_page->addr)
|
||||
|
||||
/* Destroy flush dependency on extensible array header, if set */
|
||||
if(dblk_page->has_hdr_depend) {
|
||||
if(H5EA__destroy_flush_depend((H5AC_info_t *)dblk_page->hdr, (H5AC_info_t *)dblk_page) < 0)
|
||||
H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block page and header, address = %llu", (unsigned long long)dblk_page->addr)
|
||||
dblk_page->has_hdr_depend = FALSE;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -156,10 +156,6 @@ H5EA__dblk_page_create(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_sblock_t *parent,
|
||||
/* Local variables */
|
||||
H5EA_dblk_page_t *dblk_page = NULL; /* Extensible array data block page */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called, addr = %a\n", FUNC, addr);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
|
||||
@ -170,9 +166,6 @@ HDfprintf(stderr, "%s: Called, addr = %a\n", FUNC, addr);
|
||||
/* Set info about data block page on disk */
|
||||
dblk_page->addr = addr;
|
||||
dblk_page->size = H5EA_DBLK_PAGE_SIZE(hdr);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: dblk_page->size = %Zu\n", FUNC, dblk_page->size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Clear any elements in data block page to fill value */
|
||||
if((hdr->cparam.cls->fill)(dblk_page->elmts, (size_t)hdr->dblk_page_nelmts) < 0)
|
||||
@ -215,10 +208,6 @@ H5EA__dblk_page_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_sblock_t *parent,
|
||||
/* Local variables */
|
||||
H5EA_dblk_page_cache_ud_t udata; /* Information needed for loading data block page */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
HDassert(H5F_addr_defined(dblk_page_addr));
|
||||
@ -261,10 +250,6 @@ H5EA__dblk_page_unprotect(H5EA_dblk_page_t *dblk_page, hid_t dxpl_id,
|
||||
|
||||
/* Local variables */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(dblk_page);
|
||||
|
||||
@ -296,6 +281,7 @@ H5EA__dblk_page_dest(H5EA_dblk_page_t *dblk_page))
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(dblk_page);
|
||||
HDassert(!dblk_page->has_hdr_depend);
|
||||
|
||||
/* Check if header field has been initialized */
|
||||
if(dblk_page->hdr) {
|
||||
|
@ -169,10 +169,6 @@ H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent,
|
||||
H5EA_dblock_t *dblock = NULL; /* Extensible array data block */
|
||||
haddr_t dblock_addr; /* Extensible array data block address */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called, hdr->dblk_page_nelmts = %Zu, nelmts = %Zu\n", FUNC, hdr->dblk_page_nelmts, nelmts);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
HDassert(stats_changed);
|
||||
@ -184,15 +180,9 @@ HDfprintf(stderr, "%s: Called, hdr->dblk_page_nelmts = %Zu, nelmts = %Zu\n", FUN
|
||||
|
||||
/* Set size of data block on disk */
|
||||
dblock->size = H5EA_DBLOCK_SIZE(dblock);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: dblock->size = %Zu\n", FUNC, dblock->size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Set offset of block in array's address space */
|
||||
dblock->block_off = dblk_off;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Allocate space for the data block on disk */
|
||||
if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
|
||||
@ -262,25 +252,12 @@ H5EA__dblock_sblk_idx(const H5EA_hdr_t *hdr, hsize_t idx))
|
||||
HDassert(hdr);
|
||||
HDassert(idx >= hdr->cparam.idx_blk_elmts);
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Entering - idx = %Hu\n", FUNC, idx);
|
||||
#endif /* QAK */
|
||||
/* Adjust index for elements in index block */
|
||||
idx -= hdr->cparam.idx_blk_elmts;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: after adjusting for index block elements, idx = %Hu\n", FUNC, idx);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Determine the superblock information for the index */
|
||||
H5_CHECK_OVERFLOW(idx, /*From:*/hsize_t, /*To:*/uint64_t);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: hdr->cparam.data_blk_min_elmts = %u\n", FUNC, (unsigned)hdr->cparam.data_blk_min_elmts);
|
||||
#endif /* QAK */
|
||||
sblk_idx = H5VM_log2_gen((uint64_t)((idx / hdr->cparam.data_blk_min_elmts) + 1));
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sblk_idx = %u\n", FUNC, sblk_idx);
|
||||
HDfprintf(stderr, "%s: hdr->sblk_info[%u] = {%Hu, %Zu, %Hu, %Hu}\n", FUNC, sblk_idx, hdr->sblk_info[sblk_idx].ndblks, hdr->sblk_info[sblk_idx].dblk_nelmts, hdr->sblk_info[sblk_idx].start_idx, hdr->sblk_info[sblk_idx].start_dblk);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Set return value */
|
||||
ret_value = sblk_idx;
|
||||
@ -309,10 +286,6 @@ H5EA__dblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent,
|
||||
/* Local variables */
|
||||
H5EA_dblock_cache_ud_t udata; /* Information needed for loading data block */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
HDassert(H5F_addr_defined(dblk_addr));
|
||||
@ -355,10 +328,6 @@ H5EA__dblock_unprotect(H5EA_dblock_t *dblock, hid_t dxpl_id, unsigned cache_flag
|
||||
|
||||
/* Local variables */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(dblock);
|
||||
|
||||
@ -392,10 +361,6 @@ H5EA__dblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent,
|
||||
/* Local variables */
|
||||
H5EA_dblock_t *dblock = NULL; /* Pointer to data block */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
HDassert(parent);
|
||||
@ -420,16 +385,10 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
|
||||
/* Iterate over pages in data block */
|
||||
for(u = 0; u < npages; u++) {
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Expunging data block page from cache\n", FUNC);
|
||||
#endif /* QAK */
|
||||
/* Evict the data block page from the metadata cache */
|
||||
/* (OK to call if it doesn't exist in the cache) */
|
||||
if(H5AC_expunge_entry(hdr->f, dxpl_id, H5AC_EARRAY_DBLK_PAGE, dblk_page_addr, H5AC__NO_FLAGS_SET) < 0)
|
||||
H5E_THROW(H5E_CANTEXPUNGE, "unable to remove array data block page from metadata cache")
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Done expunging data block page from cache\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Advance to next page address */
|
||||
dblk_page_addr += dblk_page_size;
|
||||
@ -463,6 +422,7 @@ H5EA__dblock_dest(H5EA_dblock_t *dblock))
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(dblock);
|
||||
HDassert(!dblock->has_hdr_depend);
|
||||
|
||||
/* Check if shared header field has been initialized */
|
||||
if(dblock->hdr) {
|
||||
|
@ -241,6 +241,7 @@ typedef struct H5EA_sblock_t {
|
||||
|
||||
/* Internal array information (not stored) */
|
||||
H5EA_hdr_t *hdr; /* Shared array header info */
|
||||
hbool_t has_hdr_depend; /* Whether this object has a flush dependency on the header */
|
||||
H5EA_iblock_t *parent; /* Parent object for super block (index block) */
|
||||
haddr_t addr; /* Address of this index block on disk */
|
||||
size_t size; /* Size of index block on disk */
|
||||
@ -265,6 +266,7 @@ typedef struct H5EA_dblock_t {
|
||||
|
||||
/* Internal array information (not stored) */
|
||||
H5EA_hdr_t *hdr; /* Shared array header info */
|
||||
hbool_t has_hdr_depend; /* Whether this object has a flush dependency on the header */
|
||||
void *parent; /* Parent object for data block (index or super block) */
|
||||
haddr_t addr; /* Address of this data block on disk */
|
||||
size_t size; /* Size of data block on disk */
|
||||
@ -284,6 +286,7 @@ typedef struct H5EA_dbk_page_t {
|
||||
|
||||
/* Internal array information (not stored) */
|
||||
H5EA_hdr_t *hdr; /* Shared array header info */
|
||||
hbool_t has_hdr_depend; /* Whether this object has a flush dependency on the header */
|
||||
H5EA_sblock_t *parent; /* Parent object for data block page (super block) */
|
||||
haddr_t addr; /* Address of this data block page on disk */
|
||||
size_t size; /* Size of data block page on disk */
|
||||
|
@ -133,9 +133,6 @@ H5EA__sblock_alloc(H5EA_hdr_t *hdr, H5EA_iblock_t *parent, unsigned sblk_idx))
|
||||
sblock->ndblks = hdr->sblk_info[sblk_idx].ndblks;
|
||||
HDassert(sblock->ndblks);
|
||||
sblock->dblk_nelmts = hdr->sblk_info[sblk_idx].dblk_nelmts;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: hdr->dblk_page_nelmts = %Zu, sblock->ndblks = %Zu, sblock->dblk_nelmts = %Zu\n", FUNC, hdr->dblk_page_nelmts, sblock->ndblks, sblock->dblk_nelmts);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Allocate buffer for data block addresses in super block */
|
||||
if(NULL == (sblock->dblk_addrs = H5FL_SEQ_MALLOC(haddr_t, sblock->ndblks)))
|
||||
@ -199,10 +196,6 @@ H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent,
|
||||
haddr_t sblock_addr; /* Extensible array super block address */
|
||||
haddr_t tmp_addr = HADDR_UNDEF; /* Address value to fill data block addresses with */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
HDassert(stats_changed);
|
||||
@ -213,15 +206,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
|
||||
/* Set size of super block on disk */
|
||||
sblock->size = H5EA_SBLOCK_SIZE(sblock);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sblock->size = %Zu\n", FUNC, sblock->size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Set offset of block in array's address space */
|
||||
sblock->block_off = hdr->sblk_info[sblk_idx].start_idx;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sblock->block_off = %Hu\n", FUNC, sblock->block_off);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Allocate space for the super block on disk */
|
||||
if(HADDR_UNDEF == (sblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_SBLOCK, dxpl_id, (hsize_t)sblock->size)))
|
||||
@ -281,11 +268,6 @@ H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent,
|
||||
/* Local variables */
|
||||
H5EA_sblock_cache_ud_t udata; /* Information needed for loading super block */
|
||||
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
HDassert(H5F_addr_defined(sblk_addr));
|
||||
@ -327,10 +309,6 @@ H5EA__sblock_unprotect(H5EA_sblock_t *sblock, hid_t dxpl_id, unsigned cache_flag
|
||||
|
||||
/* Local variables */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(sblock);
|
||||
|
||||
@ -365,10 +343,6 @@ H5EA__sblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent,
|
||||
H5EA_sblock_t *sblock = NULL; /* Pointer to super block */
|
||||
size_t u; /* Local index variable */
|
||||
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
HDassert(H5F_addr_defined(sblk_addr));
|
||||
@ -415,9 +389,7 @@ H5EA__sblock_dest(H5EA_sblock_t *sblock))
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(sblock);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sblock->hdr->dblk_page_nelmts = %Zu, sblock->ndblks = %Zu, sblock->dblk_nelmts = %Zu\n", FUNC, sblock->hdr->dblk_page_nelmts, sblock->ndblks, sblock->dblk_nelmts);
|
||||
#endif /* QAK */
|
||||
HDassert(!sblock->has_hdr_depend);
|
||||
|
||||
/* Check if shared header field has been initialized */
|
||||
if(sblock->hdr) {
|
||||
|
292
src/H5HFcache.c
292
src/H5HFcache.c
@ -118,13 +118,13 @@ static herr_t H5HF__cache_dblock_free_icr(void *thing);
|
||||
|
||||
/* Debugging Function Prototypes */
|
||||
#ifndef NDEBUG
|
||||
static herr_t H5HF__cache_verify_hdr_descendants_clean(H5F_t *f, hid_t dxpl_id,
|
||||
H5HF_hdr_t *hdr, hbool_t *clean);
|
||||
static herr_t H5HF__cache_verify_iblock_descendants_clean(H5F_t *f, hid_t dxpl_id,
|
||||
static herr_t H5HF__cache_verify_hdr_descendants_clean(H5F_t *f, H5HF_hdr_t *hdr,
|
||||
hbool_t *clean);
|
||||
static herr_t H5HF__cache_verify_iblock_descendants_clean(H5F_t *f,
|
||||
H5HF_indirect_t *iblock, unsigned *iblock_status, hbool_t *clean);
|
||||
static herr_t H5HF__cache_verify_iblocks_dblocks_clean(H5F_t *f,
|
||||
H5HF_indirect_t *iblock, hbool_t *clean, hbool_t *has_dblocks);
|
||||
static herr_t H5HF__cache_verify_descendant_iblocks_clean(H5F_t *f, hid_t dxpl_id,
|
||||
static herr_t H5HF__cache_verify_descendant_iblocks_clean(H5F_t *f,
|
||||
H5HF_indirect_t *iblock, hbool_t *clean, hbool_t *has_iblocks);
|
||||
#endif /* NDEBUG */
|
||||
|
||||
@ -657,7 +657,7 @@ H5HF__cache_hdr_pre_serialize(const H5F_t *f, hid_t dxpl_id, void *_thing,
|
||||
*
|
||||
* Do this with a call to H5HF__cache_verify_hdr_descendants_clean().
|
||||
*/
|
||||
if(H5HF__cache_verify_hdr_descendants_clean((H5F_t *)f, dxpl_id, hdr, &descendants_clean) < 0)
|
||||
if(H5HF__cache_verify_hdr_descendants_clean((H5F_t *)f, hdr, &descendants_clean) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "can't verify hdr descendants clean.")
|
||||
HDassert(descendants_clean);
|
||||
}
|
||||
@ -1165,7 +1165,7 @@ H5HF__cache_iblock_pre_serialize(const H5F_t *f, hid_t dxpl_id, void *_thing,
|
||||
* there is no need to check to see if it is pinned or protected, or to
|
||||
* protect it if it is not.
|
||||
*/
|
||||
if(H5HF__cache_verify_iblock_descendants_clean((H5F_t *)f, dxpl_id, iblock, &iblock_status, &descendants_clean) < 0)
|
||||
if(H5HF__cache_verify_iblock_descendants_clean((H5F_t *)f, iblock, &iblock_status, &descendants_clean) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "can't verify descendants clean.")
|
||||
HDassert(descendants_clean);
|
||||
}
|
||||
@ -2479,8 +2479,8 @@ done:
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
static herr_t
|
||||
H5HF__cache_verify_hdr_descendants_clean(H5F_t *f, hid_t dxpl_id,
|
||||
H5HF_hdr_t * hdr, hbool_t *clean)
|
||||
H5HF__cache_verify_hdr_descendants_clean(H5F_t *f, H5HF_hdr_t *hdr,
|
||||
hbool_t *clean)
|
||||
{
|
||||
haddr_t hdr_addr; /* Address of header */
|
||||
unsigned hdr_status = 0; /* Header cache entry status */
|
||||
@ -2561,122 +2561,11 @@ H5HF__cache_verify_hdr_descendants_clean(H5F_t *f, hid_t dxpl_id,
|
||||
*clean = TRUE;
|
||||
else if(root_iblock_status & H5AC_ES__IS_DIRTY)
|
||||
*clean = FALSE;
|
||||
else { /* must examine children */
|
||||
hbool_t unprotect_root_iblock = FALSE;
|
||||
|
||||
/* At this point, the root iblock may be pinned, protected,
|
||||
* both, or neither, and we may or may not have a pointer
|
||||
* to root iblock in memory.
|
||||
*
|
||||
* Before we call H5HF__cache_verify_iblock_descendants_clean(),
|
||||
* we must ensure that the root iblock is either pinned or
|
||||
* protected or both, and that we have a pointer to it.
|
||||
* Do this as follows:
|
||||
*/
|
||||
if(root_iblock == NULL) { /* we don't have ptr to root iblock */
|
||||
if(0 == (root_iblock_status & H5AC_ES__IS_PROTECTED)) {
|
||||
/* just protect the root iblock -- this will give us
|
||||
* the pointer we need to proceed, and ensure that
|
||||
* it is locked into the metadata cache for the
|
||||
* duration.
|
||||
*
|
||||
* Note that the udata is only used in the load callback.
|
||||
* While the fractal heap makes heavy use of the udata
|
||||
* in this case, since we know that the entry is in cache,
|
||||
* we can pass NULL udata.
|
||||
*/
|
||||
if(NULL == (root_iblock = (H5HF_indirect_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, root_iblock_addr, NULL, H5C__READ_ONLY_FLAG)))
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "H5AC_protect() faild.")
|
||||
unprotect_root_iblock = TRUE;
|
||||
} /* end if */
|
||||
else {
|
||||
/* the root iblock is protected, and we have no
|
||||
* legitimate way of getting a pointer to it.
|
||||
*
|
||||
* We square this circle by using the
|
||||
* H5AC_get_entry_ptr_from_addr() to get the needed
|
||||
* pointer.
|
||||
*
|
||||
* WARNING: This call should be used only in debugging
|
||||
* routines, and it should be avoided there when
|
||||
* possible.
|
||||
*
|
||||
* Further, if we ever multi-thread the cache,
|
||||
* this routine will have to be either discarded
|
||||
* or heavily re-worked.
|
||||
*
|
||||
* Finally, keep in mind that the entry whose
|
||||
* pointer is obtained in this fashion may not
|
||||
* be in a stable state.
|
||||
*
|
||||
* Assuming that the flush dependency code is working
|
||||
* as it should, the only reason for the root iblock to
|
||||
* be unpinned is if none of its children are in cache.
|
||||
* This unfortunately means that if it is protected and
|
||||
* not pinned, the fractal heap is in the process of loading
|
||||
* or inserting one of its children. The obvious implication
|
||||
* is that there is a significant chance that the root
|
||||
* iblock is in an unstable state.
|
||||
*
|
||||
* All this suggests that using H5AC_get_entry_ptr_from_addr()
|
||||
* to obtain the pointer to the protected root iblock is
|
||||
* questionable here. However, since this is test/debugging
|
||||
* code, I expect that we will use this approach until it
|
||||
* causes problems, or we think of a better way.
|
||||
*/
|
||||
if(H5AC_get_entry_ptr_from_addr(f, root_iblock_addr, (void **)(&root_iblock)) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "H5AC_get_entry_ptr_from_addr() failed.")
|
||||
HDassert(root_iblock);
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else { /* root_iblock != NULL */
|
||||
/* we have the pointer to the root iblock. Protect it
|
||||
* if it is neither pinned nor protected -- otherwise we
|
||||
* are ready to go.
|
||||
*/
|
||||
H5HF_indirect_t * iblock = NULL;
|
||||
|
||||
if(((root_iblock_status & H5AC_ES__IS_PINNED) == 0) &&
|
||||
((root_iblock_status & H5AC_ES__IS_PROTECTED) == 0)) {
|
||||
/* the root iblock is neither pinned nor protected -- hence
|
||||
* we must protect it before we proceed
|
||||
*
|
||||
* Note that the udata is only used in the load callback.
|
||||
* While the fractal heap makes heavy use of the udata
|
||||
* in this case, since we know that the entry is in cache,
|
||||
* we can pass NULL udata.
|
||||
*/
|
||||
if(NULL == (iblock = (H5HF_indirect_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, root_iblock_addr, NULL, H5C__READ_ONLY_FLAG)))
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "H5AC_protect() faild.")
|
||||
unprotect_root_iblock = TRUE;
|
||||
HDassert(iblock == root_iblock);
|
||||
} /* end if */
|
||||
} /* end else */
|
||||
|
||||
/* at this point, one way or another, the root iblock is locked
|
||||
* in memory for the duration of the call. Do some sanity checks,
|
||||
* and then call H5HF__cache_verify_iblock_descendants_clean().
|
||||
*/
|
||||
HDassert(hdr->root_iblock->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
|
||||
HDassert(hdr->root_iblock->cache_info.type == H5AC_FHEAP_IBLOCK);
|
||||
|
||||
if(H5HF__cache_verify_iblock_descendants_clean(f, dxpl_id, root_iblock, &root_iblock_status, clean) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "can't verify root iblock & descendants clean.")
|
||||
|
||||
/* unprotect the root indirect block if required */
|
||||
if(unprotect_root_iblock) {
|
||||
HDassert(root_iblock);
|
||||
if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, root_iblock_addr, root_iblock, H5AC__NO_FLAGS_SET) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "H5AC_unprotect() faild.")
|
||||
} /* end if */
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else if((hdr->man_dtable.curr_root_rows == 0) &&
|
||||
(HADDR_UNDEF != hdr->man_dtable.table_addr)) {
|
||||
haddr_t root_dblock_addr;
|
||||
unsigned root_dblock_status = 0;
|
||||
hbool_t in_cache;
|
||||
hbool_t type_ok;
|
||||
|
||||
/* this is scenario 2 -- we have a root dblock */
|
||||
root_dblock_addr = hdr->man_dtable.table_addr;
|
||||
@ -2684,27 +2573,16 @@ H5HF__cache_verify_hdr_descendants_clean(H5F_t *f, hid_t dxpl_id,
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get root dblock status")
|
||||
|
||||
if(root_dblock_status & H5AC_ES__IN_CACHE) {
|
||||
if(H5AC_verify_entry_type(f, root_dblock_addr, &H5AC_FHEAP_DBLOCK[0], &in_cache, &type_ok) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't check dblock type")
|
||||
HDassert(in_cache);
|
||||
if(!type_ok)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "root dblock addr doesn't refer to a dblock?!?")
|
||||
|
||||
/* If a root dblock is in cache, it must have a flush
|
||||
* dependency relationship with the header, and it
|
||||
* may not be the parent in any flush dependency
|
||||
* relationship.
|
||||
*
|
||||
* We don't test this fully, but we will verify that
|
||||
* the root iblock is a child in some flush dependency
|
||||
* relationship.
|
||||
* dependency relationship with the header.
|
||||
*/
|
||||
if(0 == (root_dblock_status & H5AC_ES__IS_FLUSH_DEP_CHILD))
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "root dblock in cache and not a flush dep child.")
|
||||
if(0 != (root_dblock_status & H5AC_ES__IS_FLUSH_DEP_PARENT))
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "root dblock in cache and is a flush dep parent.")
|
||||
|
||||
*clean = ! (root_dblock_status & H5AC_ES__IS_DIRTY);
|
||||
if(root_dblock_status & H5AC_ES__IS_DIRTY)
|
||||
*clean = FALSE;
|
||||
} /* end if */
|
||||
else /* root dblock not in cache */
|
||||
*clean = TRUE;
|
||||
@ -2757,8 +2635,8 @@ done:
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
static herr_t
|
||||
H5HF__cache_verify_iblock_descendants_clean(H5F_t *f, hid_t dxpl_id,
|
||||
H5HF_indirect_t *iblock, unsigned *iblock_status, hbool_t *clean)
|
||||
H5HF__cache_verify_iblock_descendants_clean(H5F_t *f, H5HF_indirect_t *iblock,
|
||||
unsigned *iblock_status, hbool_t *clean)
|
||||
{
|
||||
hbool_t has_dblocks = FALSE;
|
||||
hbool_t has_iblocks = FALSE;
|
||||
@ -2778,12 +2656,9 @@ H5HF__cache_verify_iblock_descendants_clean(H5F_t *f, hid_t dxpl_id,
|
||||
if((*clean) && H5HF__cache_verify_iblocks_dblocks_clean(f, iblock, clean, &has_dblocks) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "can't verify dblocks clean.")
|
||||
|
||||
if((*clean) && H5HF__cache_verify_descendant_iblocks_clean(f, dxpl_id, iblock, clean, &has_iblocks) < 0)
|
||||
if((*clean) && H5HF__cache_verify_descendant_iblocks_clean(f, iblock, clean, &has_iblocks) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "can't verify iblocks clean.")
|
||||
|
||||
if((NULL == iblock_status) && H5AC_get_entry_status(f, iblock->addr, iblock_status) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get iblock status")
|
||||
|
||||
/* verify that flush dependency setup is plausible */
|
||||
if(0 == (*iblock_status & H5AC_ES__IS_FLUSH_DEP_CHILD))
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "iblock is not a flush dep child.")
|
||||
@ -2855,41 +2730,25 @@ H5HF__cache_verify_iblocks_dblocks_clean(H5F_t *f, H5HF_indirect_t *iblock,
|
||||
|
||||
dblock_addr = iblock->ents[i].addr;
|
||||
if(H5F_addr_defined(dblock_addr)) {
|
||||
hbool_t in_cache;
|
||||
hbool_t type_ok;
|
||||
unsigned dblock_status = 0;
|
||||
|
||||
if(H5AC_verify_entry_type(f, dblock_addr, &H5AC_FHEAP_DBLOCK[0], &in_cache, &type_ok) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't check dblock type")
|
||||
if(H5AC_get_entry_status(f, dblock_addr, &dblock_status) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get dblock status")
|
||||
if(dblock_status & H5AC_ES__IN_CACHE) {
|
||||
*has_dblocks = TRUE;
|
||||
|
||||
if(in_cache) { /* dblock is in cache */
|
||||
unsigned dblock_status = 0;
|
||||
|
||||
if(!type_ok)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "dblock addr doesn't refer to a dblock?!?")
|
||||
|
||||
if(H5AC_get_entry_status(f, dblock_addr, &dblock_status) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get dblock status")
|
||||
HDassert(dblock_status & H5AC_ES__IN_CACHE);
|
||||
|
||||
*has_dblocks = TRUE;
|
||||
if(dblock_status & H5AC_ES__IS_DIRTY)
|
||||
*clean = FALSE;
|
||||
*clean = FALSE;
|
||||
|
||||
/* If a child dblock is in cache, it must have a flush
|
||||
* dependency relationship with this iblock, and it
|
||||
* may not be the parent in any flush dependency
|
||||
* relationship.
|
||||
*
|
||||
* We don't test this fully, but we will verify that
|
||||
* the child iblock is a child in some flush dependency
|
||||
* relationship.
|
||||
*/
|
||||
if(0 == (dblock_status & H5AC_ES__IS_FLUSH_DEP_CHILD))
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "dblock in cache and not a flush dep child.")
|
||||
|
||||
if(0 != (dblock_status & H5AC_ES__IS_FLUSH_DEP_PARENT))
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "dblock in cache and is a flush dep parent.")
|
||||
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
@ -2931,8 +2790,8 @@ done:
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
static herr_t
|
||||
H5HF__cache_verify_descendant_iblocks_clean(H5F_t *f, hid_t dxpl_id,
|
||||
H5HF_indirect_t *iblock, hbool_t *clean, hbool_t *has_iblocks)
|
||||
H5HF__cache_verify_descendant_iblocks_clean(H5F_t *f, H5HF_indirect_t *iblock,
|
||||
hbool_t *clean, hbool_t *has_iblocks)
|
||||
{
|
||||
unsigned first_iblock_index;
|
||||
unsigned last_iblock_index;
|
||||
@ -2970,113 +2829,6 @@ H5HF__cache_verify_descendant_iblocks_clean(H5F_t *f, hid_t dxpl_id,
|
||||
*has_iblocks = TRUE;
|
||||
if(child_iblock_status & H5AC_ES__IS_DIRTY)
|
||||
*clean = FALSE;
|
||||
|
||||
/* if the child iblock is in cache and *clean is TRUE,
|
||||
* we must continue to explore down the fractal heap tree
|
||||
* structure to verify that all descendant blocks are either
|
||||
* clean, or not in the metadata cache. We do this with a
|
||||
* recursive call to
|
||||
* H5HF__cache_verify_iblock_descendants_clean().
|
||||
* However, we can't make this call unless the child iblock
|
||||
* is somehow locked into the cache -- typically via either
|
||||
* pinning or protecting.
|
||||
*
|
||||
* If the child iblock is pinned, we can look up its pointer
|
||||
* on the current iblock's pinned child iblock list, and
|
||||
* and use that pointer in the recursive call.
|
||||
*
|
||||
* If the entry is unprotected and unpinned, we simply
|
||||
* protect it.
|
||||
*
|
||||
* If, however, the the child iblock is already protected,
|
||||
* but not pinned, we have a bit of a problem, as we have
|
||||
* no legitimate way of looking up its pointer in memory.
|
||||
*
|
||||
* To solve this problem, I have added a new metadata cache
|
||||
* call to obtain the pointer.
|
||||
*
|
||||
* WARNING: This call should be used only in debugging
|
||||
* routines, and it should be avoided there when
|
||||
* possible.
|
||||
*
|
||||
* Further, if we ever multi-thread the cache,
|
||||
* this routine will have to be either discarded
|
||||
* or heavily re-worked.
|
||||
*
|
||||
* Finally, keep in mind that the entry whose
|
||||
* pointer is obtained in this fashion may not
|
||||
* be in a stable state.
|
||||
*
|
||||
* Assuming that the flush dependency code is working
|
||||
* as it should, the only reason for the child entry to
|
||||
* be unpinned is if none of its children are in cache.
|
||||
* This unfortunately means that if it is protected and
|
||||
* not pinned, the fractal heap is in the process of loading
|
||||
* or inserting one of its children. The obvious implication
|
||||
* is that there is a significant chance that the child
|
||||
* iblock is in an unstable state.
|
||||
*
|
||||
* All this suggests that using the new call to obtain the
|
||||
* pointer to the protected child iblock is questionable
|
||||
* here. However, since this is test/debugging code, I
|
||||
* expect that we will use this approach until it causes
|
||||
* problems, or we think of a better way.
|
||||
*/
|
||||
if(*clean) {
|
||||
H5HF_indirect_t *child_iblock = NULL;
|
||||
hbool_t unprotect_child_iblock = FALSE;
|
||||
|
||||
if(0 == (child_iblock_status & H5AC_ES__IS_PINNED)) {
|
||||
/* child iblock is not pinned */
|
||||
if(0 == (child_iblock_status & H5AC_ES__IS_PROTECTED)) {
|
||||
/* child iblock is unprotected, and unpinned */
|
||||
/* protect it. Note that the udata is only */
|
||||
/* used in the load callback. While the */
|
||||
/* fractal heap makes heavy use of the udata */
|
||||
/* in this case, since we know that the */
|
||||
/* entry is in cache, we can pass NULL udata */
|
||||
|
||||
if(NULL == (child_iblock = (H5HF_indirect_t *) H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock_addr, NULL, H5C__READ_ONLY_FLAG)))
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "H5AC_protect() faild.")
|
||||
unprotect_child_iblock = TRUE;
|
||||
} /* end if */
|
||||
else {
|
||||
/* child iblock is protected -- use */
|
||||
/* H5AC_get_entry_ptr_from_addr() to get a */
|
||||
/* pointer to the entry. This is very slimy -- */
|
||||
/* come up with a better solution. */
|
||||
if(H5AC_get_entry_ptr_from_addr(f, child_iblock_addr, (void **)(&child_iblock)) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "H5AC_get_entry_ptr_from_addr() faild.")
|
||||
HDassert(child_iblock);
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else {
|
||||
/* child iblock is pinned -- look it up in the */
|
||||
/* parent iblocks child_iblocks array. */
|
||||
HDassert(iblock->child_iblocks);
|
||||
child_iblock = iblock->child_iblocks[i - first_iblock_index];
|
||||
} /* end else */
|
||||
|
||||
/* At this point, one way or another we should have
|
||||
* a pointer to the child iblock. Verify that we
|
||||
* that we have the correct one.
|
||||
*/
|
||||
HDassert(child_iblock);
|
||||
HDassert(child_iblock->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
|
||||
HDassert(child_iblock->cache_info.type == H5AC_FHEAP_IBLOCK);
|
||||
HDassert(child_iblock->addr == child_iblock_addr);
|
||||
|
||||
/* now make the recursive call */
|
||||
if(H5HF__cache_verify_iblock_descendants_clean(f, dxpl_id, child_iblock, &child_iblock_status, clean) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_SYSTEM, FAIL, "can't verify child iblock clean.")
|
||||
|
||||
/* if we protected the child iblock, unprotect it now */
|
||||
if(unprotect_child_iblock) {
|
||||
if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock_addr, child_iblock, H5AC__NO_FLAGS_SET) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "H5AC_unprotect() faild.")
|
||||
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
|
3149
test/cache.c
3149
test/cache.c
File diff suppressed because it is too large
Load Diff
@ -206,6 +206,9 @@ static herr_t notify_free_icr(void *thing);
|
||||
|
||||
static herr_t notify_notify(H5C_notify_action_t action, void *thing);
|
||||
|
||||
static void mark_flush_dep_dirty(test_entry_t * entry_ptr);
|
||||
static void mark_flush_dep_clean(test_entry_t * entry_ptr);
|
||||
|
||||
/* Generic callback routines */
|
||||
static herr_t get_load_size(const void *udata_ptr, size_t *image_len_ptr,
|
||||
int32_t entry_type);
|
||||
@ -738,6 +741,8 @@ deserialize(const void *image, size_t len, void *udata, hbool_t *dirty,
|
||||
HDassert(entry->size == len);
|
||||
HDassert((entry->type == VARIABLE_ENTRY_TYPE) || (entry->size == entry_sizes[type]));
|
||||
HDassert(dirty != NULL);
|
||||
HDassert( entry->flush_dep_npar == 0 );
|
||||
HDassert( entry->flush_dep_nchd == 0 );
|
||||
|
||||
/* for now *dirty will always be FALSE */
|
||||
*dirty = FALSE;
|
||||
@ -1334,6 +1339,11 @@ serialize(const H5F_t H5_ATTR_UNUSED *f, void *image_ptr, size_t len, void *thin
|
||||
*/
|
||||
entry->is_dirty = FALSE;
|
||||
|
||||
if(entry->flush_dep_npar > 0) {
|
||||
HDassert(entry->flush_dep_ndirty_chd == 0);
|
||||
mark_flush_dep_clean(entry);
|
||||
} /* end if */
|
||||
|
||||
/* since the entry is about to be written to disk, we can mark it
|
||||
* as initialized.
|
||||
*/
|
||||
@ -2369,11 +2379,9 @@ reset_entries(void)
|
||||
base_addr[j].destroyed = FALSE;
|
||||
base_addr[j].expunged = FALSE;
|
||||
|
||||
base_addr[j].flush_dep_par_type = -1;
|
||||
base_addr[j].flush_dep_par_idx = -1;
|
||||
for ( k = 0; k < H5C__NUM_FLUSH_DEP_HEIGHTS; k++ )
|
||||
base_addr[j].child_flush_dep_height_rc[k] = 0;
|
||||
base_addr[j].flush_dep_height = 0;
|
||||
base_addr[j].flush_dep_npar = 0;
|
||||
base_addr[j].flush_dep_nchd = 0;
|
||||
base_addr[j].flush_dep_ndirty_chd = 0;
|
||||
base_addr[j].pinned_from_client = FALSE;
|
||||
base_addr[j].pinned_from_cache = FALSE;
|
||||
|
||||
@ -2473,12 +2481,16 @@ resize_entry(H5F_t * file_ptr,
|
||||
failure_mssg = "entry to be resized is not pinned or protected.";
|
||||
|
||||
} else {
|
||||
hbool_t was_dirty = entry_ptr->is_dirty;
|
||||
|
||||
entry_ptr->size = new_size;
|
||||
|
||||
result = H5C_resize_entry((void *)entry_ptr, new_size);
|
||||
entry_ptr->is_dirty = TRUE;
|
||||
|
||||
if(entry_ptr->flush_dep_npar > 0 && !was_dirty)
|
||||
mark_flush_dep_dirty(entry_ptr);
|
||||
|
||||
if ( result != SUCCEED ) {
|
||||
|
||||
pass = FALSE;
|
||||
@ -2817,105 +2829,119 @@ verify_entry_status(H5C_t * cache_ptr,
|
||||
|
||||
/* Check flush dependency fields */
|
||||
|
||||
/* Flush dependency parent type & index */
|
||||
if ( pass ) {
|
||||
if ( entry_ptr->flush_dep_par_type != expected[i].flush_dep_par_type ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) flush_dep_par_type actual/expected = %d/%d.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->flush_dep_par_type,
|
||||
expected[i].flush_dep_par_type);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
if ( pass ) {
|
||||
if ( entry_ptr->flush_dep_par_idx != expected[i].flush_dep_par_idx ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) flush_dep_par_idx actual/expected = %d/%d.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->flush_dep_par_idx,
|
||||
expected[i].flush_dep_par_idx);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
if ( ( pass ) && ( in_cache ) && expected[i].flush_dep_par_idx >= 0 ) {
|
||||
test_entry_t * par_base_addr = entries[expected[i].flush_dep_par_type];
|
||||
|
||||
if ( entry_ptr->header.flush_dep_parent != (H5C_cache_entry_t *)&(par_base_addr[expected[i].flush_dep_par_idx]) ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) header flush_dep_parent actual/expected = %p/%p.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
(void *)entry_ptr->header.flush_dep_parent,
|
||||
(void *)&(par_base_addr[expected[i].flush_dep_par_idx]));
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* Flush dependency child ref. counts */
|
||||
for(u = 0; u < H5C__NUM_FLUSH_DEP_HEIGHTS; u++) {
|
||||
if ( pass ) {
|
||||
if ( entry_ptr->child_flush_dep_height_rc[u] != expected[i].child_flush_dep_height_rc[u] ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) child_flush_dep_height_rc[%u] actual/expected = %llu/%llu.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
u,
|
||||
(unsigned long long)(entry_ptr->child_flush_dep_height_rc[u]),
|
||||
(unsigned long long)expected[i].child_flush_dep_height_rc[u]);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
if ( ( pass ) && ( in_cache ) ) {
|
||||
if ( entry_ptr->header.child_flush_dep_height_rc[u] != expected[i].child_flush_dep_height_rc[u] ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) header child_flush_dep_height_rc[%u] actual/expected = %llu/%llu.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
u,
|
||||
(unsigned long long)entry_ptr->header.child_flush_dep_height_rc[u],
|
||||
(unsigned long long)expected[i].child_flush_dep_height_rc[u]);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
|
||||
/* Flush dependency height */
|
||||
/* # of flush dependency parents */
|
||||
if ( pass ) {
|
||||
if ( entry_ptr->flush_dep_height != expected[i].flush_dep_height ) {
|
||||
if ( entry_ptr->flush_dep_npar != expected[i].flush_dep_npar ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) flush_dep_height actual/expected = %u/%u.\n",
|
||||
"%d entry (%d, %d) flush_dep_npar actual/expected = %u/%u.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->flush_dep_height,
|
||||
expected[i].flush_dep_height);
|
||||
entry_ptr->flush_dep_npar,
|
||||
expected[i].flush_dep_npar);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
if ( ( pass ) && ( in_cache ) ) {
|
||||
if ( entry_ptr->header.flush_dep_height != expected[i].flush_dep_height ) {
|
||||
if ( entry_ptr->header.flush_dep_nparents != expected[i].flush_dep_npar ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) header flush_dep_height actual/expected = %u/%u.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->header.flush_dep_height,
|
||||
expected[i].flush_dep_height);
|
||||
"%d entry (%d, %d) header flush_dep_nparents actual/expected = %u/%u.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->header.flush_dep_nparents,
|
||||
expected[i].flush_dep_npar);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* Flush dependency parent type & index. Note this algorithm assumes
|
||||
* that the parents in both arrays are in the same order. */
|
||||
if ( pass ) {
|
||||
for ( u = 0; u < entry_ptr->flush_dep_npar; u++ ) {
|
||||
if ( entry_ptr->flush_dep_par_type[u] != expected[i].flush_dep_par_type[u] ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) flush_dep_par_type[%u] actual/expected = %d/%d.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
u,
|
||||
entry_ptr->flush_dep_par_type[u],
|
||||
expected[i].flush_dep_par_type[u]);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
if ( pass ) {
|
||||
for ( u = 0; u < entry_ptr->flush_dep_npar; u++ ) {
|
||||
if ( entry_ptr->flush_dep_par_idx[u] != expected[i].flush_dep_par_idx[u] ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) flush_dep_par_idx[%u] actual/expected = %d/%d.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
u,
|
||||
entry_ptr->flush_dep_par_idx[u],
|
||||
expected[i].flush_dep_par_idx[u]);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
|
||||
/* # of flush dependency children and dirty children */
|
||||
if ( pass ) {
|
||||
if ( entry_ptr->flush_dep_nchd != expected[i].flush_dep_nchd ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) flush_dep_nchd actual/expected = %u/%u.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->flush_dep_nchd,
|
||||
expected[i].flush_dep_nchd);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
if ( ( pass ) && ( in_cache ) ) {
|
||||
if ( entry_ptr->header.flush_dep_nchildren != expected[i].flush_dep_nchd ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) header flush_dep_nchildren actual/expected = %u/%u.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->header.flush_dep_nchildren,
|
||||
expected[i].flush_dep_nchd);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
if ( pass ) {
|
||||
if ( entry_ptr->flush_dep_ndirty_chd != expected[i].flush_dep_ndirty_chd ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) flush_dep_ndirty_chd actual/expected = %u/%u.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->flush_dep_ndirty_chd,
|
||||
expected[i].flush_dep_ndirty_chd);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
if ( ( pass ) && ( in_cache ) ) {
|
||||
if ( entry_ptr->header.flush_dep_ndirty_children != expected[i].flush_dep_ndirty_chd ) {
|
||||
pass = FALSE;
|
||||
sprintf(msg,
|
||||
"%d entry (%d, %d) header flush_dep_ndirty_children actual/expected = %u/%u.\n",
|
||||
tag,
|
||||
expected[i].entry_type,
|
||||
expected[i].entry_index,
|
||||
entry_ptr->header.flush_dep_ndirty_children,
|
||||
expected[i].flush_dep_ndirty_chd);
|
||||
failure_mssg = msg;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
@ -3656,6 +3682,8 @@ insert_entry(H5F_t * file_ptr,
|
||||
HDassert( entry_ptr->type == type );
|
||||
HDassert( entry_ptr == entry_ptr->self );
|
||||
HDassert( !(entry_ptr->is_protected) );
|
||||
HDassert( entry_ptr->flush_dep_npar == 0 );
|
||||
HDassert( entry_ptr->flush_dep_nchd == 0 );
|
||||
|
||||
insert_pinned = (hbool_t)((flags & H5C__PIN_ENTRY_FLAG) != 0 );
|
||||
|
||||
@ -3742,6 +3770,7 @@ mark_entry_dirty(int32_t type,
|
||||
herr_t result;
|
||||
test_entry_t * base_addr;
|
||||
test_entry_t * entry_ptr;
|
||||
hbool_t was_dirty;
|
||||
|
||||
if ( pass ) {
|
||||
|
||||
@ -3757,8 +3786,12 @@ mark_entry_dirty(int32_t type,
|
||||
HDassert( entry_ptr->header.is_protected ||
|
||||
entry_ptr->header.is_pinned );
|
||||
|
||||
was_dirty = entry_ptr->is_dirty;
|
||||
entry_ptr->is_dirty = TRUE;
|
||||
|
||||
if(entry_ptr->flush_dep_npar > 0 && !was_dirty)
|
||||
mark_flush_dep_dirty(entry_ptr);
|
||||
|
||||
result = H5C_mark_entry_dirty((void *)entry_ptr);
|
||||
|
||||
if ( ( result < 0 ) ||
|
||||
@ -3850,11 +3883,14 @@ move_entry(H5C_t * cache_ptr,
|
||||
}
|
||||
|
||||
if ( ! done ) {
|
||||
hbool_t was_dirty = entry_ptr->is_dirty;
|
||||
|
||||
entry_ptr->is_dirty = TRUE;
|
||||
|
||||
result = H5C_move_entry(cache_ptr, &(types[type]),
|
||||
old_addr, new_addr);
|
||||
if(entry_ptr->flush_dep_npar > 0 && !was_dirty)
|
||||
mark_flush_dep_dirty(entry_ptr);
|
||||
|
||||
result = H5C_move_entry(cache_ptr, &(types[type]), old_addr, new_addr);
|
||||
}
|
||||
|
||||
if ( ! done ) {
|
||||
@ -4243,9 +4279,15 @@ unprotect_entry(H5F_t * file_ptr,
|
||||
HDassert ( ( ! pin_flag_set ) || ( ! (entry_ptr->is_pinned) ) );
|
||||
HDassert ( ( ! unpin_flag_set ) || ( entry_ptr->is_pinned ) );
|
||||
|
||||
if(flags & H5C__DIRTIED_FLAG)
|
||||
if(flags & H5C__DIRTIED_FLAG) {
|
||||
hbool_t was_dirty = entry_ptr->is_dirty;
|
||||
|
||||
entry_ptr->is_dirty = TRUE;
|
||||
|
||||
if(entry_ptr->flush_dep_npar > 0 && !was_dirty)
|
||||
mark_flush_dep_dirty(entry_ptr);
|
||||
} /* end if */
|
||||
|
||||
result = H5C_unprotect(file_ptr, H5AC_ind_read_dxpl_id,
|
||||
entry_ptr->addr, (void *)entry_ptr, flags);
|
||||
|
||||
@ -5722,43 +5764,26 @@ create_flush_dependency(int32_t par_type,
|
||||
|
||||
if ( ( result < 0 ) ||
|
||||
( !par_entry_ptr->header.is_pinned ) ||
|
||||
( !(par_entry_ptr->header.flush_dep_height > 0) ) ) {
|
||||
( !(par_entry_ptr->header.flush_dep_nchildren > 0) ) ) {
|
||||
|
||||
pass = FALSE;
|
||||
failure_mssg = "error in H5C_create_flush_dependency().";
|
||||
} /* end if */
|
||||
|
||||
/* Update information about entries */
|
||||
chd_entry_ptr->flush_dep_par_type = par_type;
|
||||
chd_entry_ptr->flush_dep_par_idx = par_idx;
|
||||
par_entry_ptr->child_flush_dep_height_rc[chd_entry_ptr->flush_dep_height]++;
|
||||
HDassert( chd_entry_ptr->flush_dep_npar < MAX_FLUSH_DEP_PARS );
|
||||
chd_entry_ptr->flush_dep_par_type[chd_entry_ptr->flush_dep_npar] = par_type;
|
||||
chd_entry_ptr->flush_dep_par_idx[chd_entry_ptr->flush_dep_npar] = par_idx;
|
||||
chd_entry_ptr->flush_dep_npar++;
|
||||
par_entry_ptr->flush_dep_nchd++;
|
||||
if(chd_entry_ptr->is_dirty || chd_entry_ptr->flush_dep_ndirty_chd > 0) {
|
||||
HDassert(par_entry_ptr->flush_dep_ndirty_chd < par_entry_ptr->flush_dep_nchd);
|
||||
par_entry_ptr->flush_dep_ndirty_chd++;
|
||||
} /* end if */
|
||||
par_entry_ptr->pinned_from_cache = TRUE;
|
||||
if( !par_is_pinned )
|
||||
par_entry_ptr->is_pinned = TRUE;
|
||||
|
||||
/* Check flush dependency heights */
|
||||
while(chd_entry_ptr->flush_dep_height >= par_entry_ptr->flush_dep_height) {
|
||||
unsigned prev_par_flush_dep_height = par_entry_ptr->flush_dep_height; /* Save the previous height */
|
||||
|
||||
par_entry_ptr->flush_dep_height = chd_entry_ptr->flush_dep_height + 1;
|
||||
|
||||
/* Check for parent entry being in flush dependency relationship */
|
||||
if(par_entry_ptr->flush_dep_par_idx >= 0) {
|
||||
/* Move parent & child entries up the flushd dependency 'chain' */
|
||||
chd_entry_ptr = par_entry_ptr;
|
||||
par_base_addr = entries[chd_entry_ptr->flush_dep_par_type];
|
||||
par_entry_ptr = &(par_base_addr[chd_entry_ptr->flush_dep_par_idx]);
|
||||
|
||||
/* Adjust the ref. counts in new parent */
|
||||
HDassert(par_entry_ptr->child_flush_dep_height_rc[prev_par_flush_dep_height] > 0);
|
||||
par_entry_ptr->child_flush_dep_height_rc[prev_par_flush_dep_height]--;
|
||||
par_entry_ptr->child_flush_dep_height_rc[chd_entry_ptr->flush_dep_height]++;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
return;
|
||||
|
||||
} /* create_flush_dependency() */
|
||||
|
||||
|
||||
@ -5793,18 +5818,16 @@ destroy_flush_dependency(int32_t par_type,
|
||||
test_entry_t * par_entry_ptr; /* Parent entry */
|
||||
test_entry_t * chd_base_addr; /* Base entry of child's entry array */
|
||||
test_entry_t * chd_entry_ptr; /* Child entry */
|
||||
unsigned chd_flush_dep_height; /* Child flush dep. height */
|
||||
unsigned i; /* Local index variable */
|
||||
|
||||
/* Get parent entry */
|
||||
par_base_addr = entries[par_type];
|
||||
par_entry_ptr = &(par_base_addr[par_idx]);
|
||||
|
||||
/* Sanity check parent entry */
|
||||
HDassert( par_entry_ptr->index == par_idx );
|
||||
HDassert( par_entry_ptr->type == par_type );
|
||||
HDassert( par_entry_ptr->is_pinned );
|
||||
HDassert( par_entry_ptr->pinned_from_cache );
|
||||
HDassert( par_entry_ptr->flush_dep_height > 0 );
|
||||
HDassert( par_entry_ptr->flush_dep_nchd > 0 );
|
||||
HDassert( par_entry_ptr == par_entry_ptr->self );
|
||||
|
||||
/* Get parent entry */
|
||||
@ -5814,7 +5837,7 @@ destroy_flush_dependency(int32_t par_type,
|
||||
/* Sanity check child entry */
|
||||
HDassert( chd_entry_ptr->index == chd_idx );
|
||||
HDassert( chd_entry_ptr->type == chd_type );
|
||||
HDassert( chd_entry_ptr->flush_dep_height < par_entry_ptr->flush_dep_height );
|
||||
HDassert( chd_entry_ptr->flush_dep_npar > 0 );
|
||||
HDassert( chd_entry_ptr == chd_entry_ptr->self );
|
||||
|
||||
if ( H5C_destroy_flush_dependency(par_entry_ptr, chd_entry_ptr) < 0 ) {
|
||||
@ -5823,55 +5846,123 @@ destroy_flush_dependency(int32_t par_type,
|
||||
} /* end if */
|
||||
|
||||
/* Update information about entries */
|
||||
chd_entry_ptr->flush_dep_par_type = -1;
|
||||
chd_entry_ptr->flush_dep_par_idx = -1;
|
||||
par_entry_ptr->child_flush_dep_height_rc[chd_entry_ptr->flush_dep_height]--;
|
||||
|
||||
/* Check flush dependency heights */
|
||||
chd_flush_dep_height = chd_entry_ptr->flush_dep_height;
|
||||
while( 0 == par_entry_ptr->child_flush_dep_height_rc[chd_flush_dep_height] ) {
|
||||
unsigned prev_par_flush_dep_height = par_entry_ptr->flush_dep_height; /* Save the previous height */
|
||||
int i; /* Local index variable */
|
||||
|
||||
/* Check for new flush dependency height of parent */
|
||||
for(i = (H5C__NUM_FLUSH_DEP_HEIGHTS - 1); i >= 0; i--)
|
||||
if(par_entry_ptr->child_flush_dep_height_rc[i] > 0)
|
||||
break;
|
||||
|
||||
HDassert((i + 1) <= (int)prev_par_flush_dep_height);
|
||||
|
||||
if((unsigned)(i + 1) < prev_par_flush_dep_height) {
|
||||
par_entry_ptr->flush_dep_height = (unsigned)(i + 1);
|
||||
if(i < 0) {
|
||||
par_entry_ptr->pinned_from_cache = FALSE;
|
||||
par_entry_ptr->is_pinned = par_entry_ptr->pinned_from_client;
|
||||
} /* end if */
|
||||
|
||||
/* Check for parent entry being in flush dependency relationship */
|
||||
if(par_entry_ptr->flush_dep_par_idx >= 0) {
|
||||
/* Move parent & child entries up the flushd dependency 'chain' */
|
||||
chd_entry_ptr = par_entry_ptr;
|
||||
par_base_addr = entries[chd_entry_ptr->flush_dep_par_type];
|
||||
par_entry_ptr = &(par_base_addr[chd_entry_ptr->flush_dep_par_idx]);
|
||||
|
||||
/* Adjust the ref. counts in new parent */
|
||||
HDassert(par_entry_ptr->child_flush_dep_height_rc[prev_par_flush_dep_height] > 0);
|
||||
par_entry_ptr->child_flush_dep_height_rc[prev_par_flush_dep_height]--;
|
||||
par_entry_ptr->child_flush_dep_height_rc[chd_entry_ptr->flush_dep_height]++;
|
||||
chd_flush_dep_height = prev_par_flush_dep_height;
|
||||
} /* end if */
|
||||
else
|
||||
break;
|
||||
} /* end if */
|
||||
else
|
||||
for(i=0; i<chd_entry_ptr->flush_dep_npar; i++)
|
||||
if(chd_entry_ptr->flush_dep_par_type[i] == par_type
|
||||
&& chd_entry_ptr->flush_dep_par_idx[i] == par_idx)
|
||||
break;
|
||||
} /* end while */
|
||||
HDassert(i < chd_entry_ptr->flush_dep_npar);
|
||||
if(i < chd_entry_ptr->flush_dep_npar - 1)
|
||||
HDmemmove(&chd_entry_ptr->flush_dep_par_type[i],
|
||||
&chd_entry_ptr->flush_dep_par_type[i+1],
|
||||
(chd_entry_ptr->flush_dep_npar - i - 1)
|
||||
* sizeof(chd_entry_ptr->flush_dep_par_type[0]));
|
||||
if(i < chd_entry_ptr->flush_dep_npar - 1)
|
||||
HDmemmove(&chd_entry_ptr->flush_dep_par_idx[i],
|
||||
&chd_entry_ptr->flush_dep_par_idx[i+1],
|
||||
(chd_entry_ptr->flush_dep_npar - i - 1)
|
||||
* sizeof(chd_entry_ptr->flush_dep_par_idx[0]));
|
||||
chd_entry_ptr->flush_dep_npar--;
|
||||
par_entry_ptr->flush_dep_nchd--;
|
||||
if(par_entry_ptr->flush_dep_nchd == 0) {
|
||||
par_entry_ptr->pinned_from_cache = FALSE;
|
||||
par_entry_ptr->is_pinned = par_entry_ptr->pinned_from_client;
|
||||
} /* end if */
|
||||
if(chd_entry_ptr->is_dirty || chd_entry_ptr->flush_dep_ndirty_chd > 0) {
|
||||
HDassert(par_entry_ptr->flush_dep_ndirty_chd > 0);
|
||||
par_entry_ptr->flush_dep_ndirty_chd--;
|
||||
if(!par_entry_ptr->is_dirty
|
||||
&& par_entry_ptr->flush_dep_ndirty_chd == 0)
|
||||
mark_flush_dep_clean(par_entry_ptr);
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
return;
|
||||
|
||||
} /* destroy_flush_dependency() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: mark_flush_dep_dirty()
|
||||
*
|
||||
* Purpose: Recursively propagate the flush_dep_ndirty_children flag
|
||||
* up the dependency chain in response to entry either
|
||||
* becoming dirty or having its flush_dep_ndirty_children
|
||||
* increased from 0.
|
||||
*
|
||||
* Return: <none>
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* 12/4/12
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
mark_flush_dep_dirty(test_entry_t * entry_ptr)
|
||||
{
|
||||
/* Sanity checks */
|
||||
HDassert(entry_ptr);
|
||||
|
||||
/* Iterate over the parent entries */
|
||||
if(entry_ptr->flush_dep_npar) {
|
||||
test_entry_t *par_base_addr; /* Base entry of parent's entry array */
|
||||
test_entry_t *par_entry_ptr; /* Parent entry */
|
||||
unsigned u; /* Local index variable */
|
||||
|
||||
for(u = 0; u < entry_ptr->flush_dep_npar; u++) {
|
||||
/* Get parent entry */
|
||||
par_base_addr = entries[entry_ptr->flush_dep_par_type[u]];
|
||||
par_entry_ptr = &(par_base_addr[entry_ptr->flush_dep_par_idx[u]]);
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(par_entry_ptr->flush_dep_ndirty_chd
|
||||
< par_entry_ptr->flush_dep_nchd);
|
||||
|
||||
/* Adjust the parent's number of dirty children */
|
||||
par_entry_ptr->flush_dep_ndirty_chd++;
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
} /* end mark_flush_dep_dirty() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: mark_flush_dep_clean()
|
||||
*
|
||||
* Purpose: Recursively propagate the flush_dep_ndirty_children flag
|
||||
* up the dependency chain in response to entry either
|
||||
* becoming clean or having its flush_dep_ndirty_children
|
||||
* reduced to 0.
|
||||
*
|
||||
* Return: <none>
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* 12/4/12
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
mark_flush_dep_clean(test_entry_t * entry_ptr)
|
||||
{
|
||||
/* Sanity checks */
|
||||
HDassert(entry_ptr);
|
||||
HDassert(!entry_ptr->is_dirty && entry_ptr->flush_dep_ndirty_chd == 0);
|
||||
|
||||
/* Iterate over the parent entries */
|
||||
if(entry_ptr->flush_dep_npar) {
|
||||
test_entry_t *par_base_addr; /* Base entry of parent's entry array */
|
||||
test_entry_t *par_entry_ptr; /* Parent entry */
|
||||
unsigned u; /* Local index variable */
|
||||
|
||||
for(u = 0; u < entry_ptr->flush_dep_npar; u++) {
|
||||
/* Get parent entry */
|
||||
par_base_addr = entries[entry_ptr->flush_dep_par_type[u]];
|
||||
par_entry_ptr = &(par_base_addr[entry_ptr->flush_dep_par_idx[u]]);
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(par_entry_ptr->flush_dep_ndirty_chd > 0);
|
||||
|
||||
/* Adjust the parent's number of dirty children */
|
||||
par_entry_ptr->flush_dep_ndirty_chd--;
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
} /* end mark_flush_dep_clean() */
|
||||
|
||||
|
||||
/*** H5AC level utility functions ***/
|
||||
|
||||
|
@ -152,6 +152,9 @@
|
||||
* cache entry.
|
||||
*/
|
||||
|
||||
#define MAX_FLUSH_DEP_PARS 8 /* Maximum number of flush dependency
|
||||
* parents in the test */
|
||||
|
||||
typedef struct flush_op
|
||||
{
|
||||
int op_code; /* integer op code indicating the
|
||||
@ -340,13 +343,11 @@ typedef struct test_entry_t
|
||||
hbool_t expunged; /* entry has been expunged since the
|
||||
* last time it was reset.
|
||||
*/
|
||||
int flush_dep_par_type; /* Entry type of flush dependency parent */
|
||||
int flush_dep_par_idx; /* Index of flush dependency parent */
|
||||
uint64_t child_flush_dep_height_rc[H5C__NUM_FLUSH_DEP_HEIGHTS];
|
||||
/* flush dependency heights of flush
|
||||
* dependency children
|
||||
*/
|
||||
unsigned flush_dep_height; /* flush dependency height of entry */
|
||||
int flush_dep_par_type[MAX_FLUSH_DEP_PARS]; /* Entry types of flush dependency parents */
|
||||
int flush_dep_par_idx[MAX_FLUSH_DEP_PARS]; /* Indices of flush dependency parents */
|
||||
unsigned flush_dep_npar; /* Number of flush dependency parents */
|
||||
unsigned flush_dep_nchd; /* Number of flush dependency children */
|
||||
unsigned flush_dep_ndirty_chd; /* Number of dirty flush dependency children (including granchildren, etc.) */
|
||||
hbool_t pinned_from_client; /* entry was pinned by client call */
|
||||
hbool_t pinned_from_cache; /* entry was pinned by cache internally */
|
||||
unsigned flush_order; /* Order that entry was flushed in */
|
||||
@ -520,13 +521,11 @@ struct expected_entry_status
|
||||
hbool_t deserialized;
|
||||
hbool_t serialized;
|
||||
hbool_t destroyed;
|
||||
int flush_dep_par_type; /* Entry type of flush dependency parent */
|
||||
int flush_dep_par_idx; /* Index of flush dependency parent */
|
||||
uint64_t child_flush_dep_height_rc[H5C__NUM_FLUSH_DEP_HEIGHTS];
|
||||
/* flush dependency heights of flush
|
||||
* dependency children
|
||||
*/
|
||||
unsigned flush_dep_height; /* flush dependency height of entry */
|
||||
int flush_dep_par_type[MAX_FLUSH_DEP_PARS]; /* Entry types of flush dependency parents */
|
||||
int flush_dep_par_idx[MAX_FLUSH_DEP_PARS]; /* Indices of flush dependency parents */
|
||||
unsigned flush_dep_npar; /* Number of flush dependency parents */
|
||||
unsigned flush_dep_nchd; /* Number of flush dependency children */
|
||||
unsigned flush_dep_ndirty_chd; /* Number of dirty flush dependency children */
|
||||
int flush_order; /* flush order of entry */
|
||||
unsigned char is_corked; /* cork status of entry */
|
||||
};
|
||||
|
@ -666,7 +666,8 @@ test_userblock_offset(const char *env_h5_drvr, hid_t fapl)
|
||||
|
||||
f = HDopen(filename, O_RDONLY, 0);
|
||||
HDlseek(f, (off_t)offset, SEEK_SET);
|
||||
HDread(f, rdata, sizeof(int)*DSET_DIM1*DSET_DIM2);
|
||||
if(HDread(f, rdata, sizeof(int)*DSET_DIM1*DSET_DIM2) < 0)
|
||||
goto error;
|
||||
|
||||
/* Check that the values read are the same as the values written */
|
||||
for(i = 0; i < DSET_DIM1; i++) {
|
||||
|
@ -88,7 +88,7 @@ void pause_proc(void)
|
||||
}
|
||||
printf("waiting(%ds) for file %s ...\n", time_int, greenlight);
|
||||
fflush(stdout);
|
||||
HDsleep(time_int);
|
||||
HDsleep(time_int);
|
||||
}
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user