mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
[svn-r16618] Description:
Modify metadata cache flush dependency feature to allow it to work with entries that are pinned through the cache API calls. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.6 (amazon) in debug mode Mac OS X/32 10.5.6 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
This commit is contained in:
parent
eb070568b0
commit
bbe430429d
232
src/H5C.c
232
src/H5C.c
@ -4881,6 +4881,7 @@ H5C_insert_entry(H5F_t * f,
|
||||
entry_ptr->ro_ref_count = 0;
|
||||
|
||||
entry_ptr->is_pinned = insert_pinned;
|
||||
entry_ptr->pinned_from_client = insert_pinned;
|
||||
|
||||
/* newly inserted entries are assumed to be dirty */
|
||||
entry_ptr->is_dirty = TRUE;
|
||||
@ -5971,6 +5972,56 @@ done:
|
||||
|
||||
} /* H5C_resize_pinned_entry() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5C_pin_entry_from_client()
|
||||
*
|
||||
* Purpose: Internal routine to pin a cache entry from a client action.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* 3/26/09
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
static herr_t
|
||||
H5C_pin_entry_from_client(H5C_t * cache_ptr,
|
||||
H5C_cache_entry_t * entry_ptr)
|
||||
#else
|
||||
static herr_t
|
||||
H5C_pin_entry_from_client(H5C_t UNUSED * cache_ptr,
|
||||
H5C_cache_entry_t * entry_ptr)
|
||||
#endif
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5C_pin_entry_from_client)
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert( cache_ptr );
|
||||
HDassert( entry_ptr );
|
||||
|
||||
/* Check if the entry is already pinned */
|
||||
if(entry_ptr->is_pinned) {
|
||||
/* Check if the entry was pinned through an explicit pin from a client */
|
||||
if(entry_ptr->pinned_from_client)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Entry is already pinned")
|
||||
} /* end if */
|
||||
else {
|
||||
entry_ptr->is_pinned = TRUE;
|
||||
|
||||
H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr)
|
||||
} /* end else */
|
||||
|
||||
/* Mark that the entry was pinned through an explicit pin from a client */
|
||||
entry_ptr->pinned_from_client = TRUE;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5C_pin_entry_from_client() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5C_pin_protected_entry()
|
||||
@ -6000,47 +6051,32 @@ done:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
herr_t
|
||||
H5C_pin_protected_entry(H5C_t * cache_ptr,
|
||||
void * thing)
|
||||
#else
|
||||
herr_t
|
||||
H5C_pin_protected_entry(H5C_t UNUSED * cache_ptr,
|
||||
void * thing)
|
||||
#endif
|
||||
{
|
||||
H5C_cache_entry_t * entry_ptr; /* Pointer to entry to pin */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5C_cache_entry_t * entry_ptr;
|
||||
|
||||
FUNC_ENTER_NOAPI(H5C_pin_protected_entry, FAIL)
|
||||
|
||||
HDassert( cache_ptr );
|
||||
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
|
||||
HDassert( thing );
|
||||
|
||||
entry_ptr = (H5C_cache_entry_t *)thing;
|
||||
|
||||
HDassert( entry_ptr );
|
||||
HDassert( H5F_addr_defined(entry_ptr->addr) );
|
||||
|
||||
if ( ! ( entry_ptr->is_protected ) ) {
|
||||
|
||||
/* Only protected entries can be pinned */
|
||||
if(!entry_ptr->is_protected)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Entry isn't protected")
|
||||
}
|
||||
|
||||
if ( entry_ptr->is_pinned ) {
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Entry is already pinned")
|
||||
}
|
||||
|
||||
entry_ptr->is_pinned = TRUE;
|
||||
|
||||
H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr)
|
||||
/* Pin the entry from a client */
|
||||
if(H5C_pin_entry_from_client(cache_ptr, entry_ptr) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Can't pin entry by client")
|
||||
|
||||
done:
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
||||
} /* H5C_pin_protected_entry() */
|
||||
|
||||
|
||||
@ -7669,6 +7705,58 @@ H5C_stats__reset(H5C_t UNUSED * cache_ptr)
|
||||
|
||||
} /* H5C_stats__reset() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5C_unpin_entry_from_client()
|
||||
*
|
||||
* Purpose: Internal routine to unpin a cache entry from a client action.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* 3/24/09
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5C_unpin_entry_from_client(H5C_t * cache_ptr,
|
||||
H5C_cache_entry_t * entry_ptr,
|
||||
hbool_t update_rp)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5C_unpin_entry_from_client)
|
||||
|
||||
/* Sanity checking */
|
||||
HDassert( cache_ptr );
|
||||
HDassert( entry_ptr );
|
||||
|
||||
/* Error checking (should be sanity checks?) */
|
||||
if(!entry_ptr->is_pinned)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Entry isn't pinned")
|
||||
if(!entry_ptr->pinned_from_client)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Entry wasn't pinned by cache client")
|
||||
|
||||
/* If requested, update the replacement policy if the entry is not protected */
|
||||
if(update_rp && !entry_ptr->is_protected)
|
||||
H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, FAIL)
|
||||
|
||||
/* Check if the entry is not pinned from a flush dependency */
|
||||
if(!entry_ptr->pinned_from_cache) {
|
||||
/* Unpin the entry now */
|
||||
entry_ptr->is_pinned = FALSE;
|
||||
|
||||
/* Update the stats for an unpin operation */
|
||||
H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr)
|
||||
} /* end if */
|
||||
|
||||
/* Mark the entry as explicitly unpinned by the client */
|
||||
entry_ptr->pinned_from_client = FALSE;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5C_unpin_entry_from_client() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5C_unpin_entry()
|
||||
@ -7687,35 +7775,24 @@ herr_t
|
||||
H5C_unpin_entry(H5C_t * cache_ptr,
|
||||
void * thing)
|
||||
{
|
||||
H5C_cache_entry_t * entry_ptr; /* Pointer to entry to unpin */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5C_cache_entry_t * entry_ptr;
|
||||
|
||||
FUNC_ENTER_NOAPI(H5C_unpin_entry, FAIL)
|
||||
|
||||
/* Sanity checking */
|
||||
HDassert( cache_ptr );
|
||||
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
|
||||
HDassert( thing );
|
||||
|
||||
entry_ptr = (H5C_cache_entry_t *)thing;
|
||||
HDassert( entry_ptr );
|
||||
|
||||
if ( ! ( entry_ptr->is_pinned ) ) {
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Entry isn't pinned")
|
||||
}
|
||||
|
||||
if ( ! ( entry_ptr->is_protected ) ) {
|
||||
|
||||
H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, FAIL)
|
||||
}
|
||||
|
||||
entry_ptr->is_pinned = FALSE;
|
||||
|
||||
H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr)
|
||||
/* Unpin the entry */
|
||||
if(H5C_unpin_entry_from_client(cache_ptr, entry_ptr, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Can't unpin entry from client")
|
||||
|
||||
done:
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
||||
} /* H5C_unpin_entry() */
|
||||
|
||||
|
||||
@ -7846,7 +7923,6 @@ H5C_unprotect(H5F_t * f,
|
||||
unsigned int flags,
|
||||
size_t new_size)
|
||||
{
|
||||
/* const char * fcn_name = "H5C_unprotect()"; */
|
||||
hbool_t deleted;
|
||||
hbool_t dirtied;
|
||||
hbool_t set_flush_marker;
|
||||
@ -7938,23 +8014,15 @@ H5C_unprotect(H5F_t * f,
|
||||
/* Pin or unpin the entry as requested. */
|
||||
if ( pin_entry ) {
|
||||
|
||||
if ( entry_ptr->is_pinned ) {
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, \
|
||||
"Entry already pinned???")
|
||||
}
|
||||
entry_ptr->is_pinned = TRUE;
|
||||
H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr)
|
||||
/* Pin the entry from a client */
|
||||
if(H5C_pin_entry_from_client(cache_ptr, entry_ptr) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Can't pin entry by client")
|
||||
|
||||
} else if ( unpin_entry ) {
|
||||
|
||||
if ( ! ( entry_ptr->is_pinned ) ) {
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, \
|
||||
"Entry already unpinned???")
|
||||
}
|
||||
entry_ptr->is_pinned = FALSE;
|
||||
H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr)
|
||||
/* Unpin the entry from a client */
|
||||
if(H5C_unpin_entry_from_client(cache_ptr, entry_ptr, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Can't unpin entry by client")
|
||||
|
||||
}
|
||||
|
||||
@ -8071,23 +8139,15 @@ H5C_unprotect(H5F_t * f,
|
||||
/* Pin or unpin the entry as requested. */
|
||||
if ( pin_entry ) {
|
||||
|
||||
if ( entry_ptr->is_pinned ) {
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, \
|
||||
"Entry already pinned???")
|
||||
}
|
||||
entry_ptr->is_pinned = TRUE;
|
||||
H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr)
|
||||
/* Pin the entry from a client */
|
||||
if(H5C_pin_entry_from_client(cache_ptr, entry_ptr) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Can't pin entry by client")
|
||||
|
||||
} else if ( unpin_entry ) {
|
||||
|
||||
if ( ! ( entry_ptr->is_pinned ) ) {
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, \
|
||||
"Entry already unpinned???")
|
||||
}
|
||||
entry_ptr->is_pinned = FALSE;
|
||||
H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr)
|
||||
/* Unpin the entry from a client */
|
||||
if(H5C_unpin_entry_from_client(cache_ptr, entry_ptr, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Can't unpin entry by client")
|
||||
|
||||
}
|
||||
|
||||
@ -8675,21 +8735,21 @@ H5C_create_flush_dependency(H5C_t UNUSED * cache_ptr, void * parent_thing,
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Combined flush dependency height too large")
|
||||
}
|
||||
|
||||
/* Check for parent already pinned */
|
||||
if(parent_entry->is_pinned) {
|
||||
/* Verify that the parent entry was pinned through a flush dependency relationship */
|
||||
if(0 == parent_entry->flush_dep_height)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Parent entry wasn't pinned through flush dependency")
|
||||
} /* end if */
|
||||
else {
|
||||
/* Check for parent not pinned */
|
||||
if(!parent_entry->is_pinned) {
|
||||
/* Sanity check */
|
||||
HDassert(parent_entry->flush_dep_height == 0);
|
||||
HDassert(!parent_entry->pinned_from_client);
|
||||
HDassert(!parent_entry->pinned_from_cache);
|
||||
|
||||
/* Pin the parent entry */
|
||||
parent_entry->is_pinned = TRUE;
|
||||
H5C__UPDATE_STATS_FOR_PIN(cache_ptr, parent_entry)
|
||||
} /* end else */
|
||||
|
||||
/* Mark the entry as pinned from the cache's action (possibly redundantly) */
|
||||
parent_entry->pinned_from_cache = TRUE;
|
||||
|
||||
/* Increment ref. count for parent's flush dependency children heights */
|
||||
parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height]++;
|
||||
|
||||
@ -8811,12 +8871,24 @@ H5C_destroy_flush_dependency(H5C_t * cache_ptr, void *parent_thing,
|
||||
* parent of _any_ child flush dependencies).
|
||||
*/
|
||||
if(0 == parent_entry->flush_dep_height) {
|
||||
if(!parent_entry->is_protected)
|
||||
H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, parent_entry, FAIL)
|
||||
/* Sanity check */
|
||||
HDassert(parent_entry->pinned_from_cache);
|
||||
|
||||
/* Unpin parent entry */
|
||||
parent_entry->is_pinned = FALSE;
|
||||
H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, parent_entry)
|
||||
/* Check if we should unpin parent entry now */
|
||||
if(!parent_entry->pinned_from_client) {
|
||||
/* Update the replacement policy if the entry is not protected */
|
||||
if(!parent_entry->is_protected)
|
||||
H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, parent_entry, FAIL)
|
||||
|
||||
/* Unpin the entry now */
|
||||
parent_entry->is_pinned = FALSE;
|
||||
|
||||
/* Update the stats for an unpin operation */
|
||||
H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, parent_entry)
|
||||
} /* end if */
|
||||
|
||||
/* Mark the entry as unpinned from the cache's action */
|
||||
parent_entry->pinned_from_cache = FALSE;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
|
@ -378,6 +378,37 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr,
|
||||
* 'dest' callback routine.
|
||||
*
|
||||
*
|
||||
* Fields supporting the 'flush dependency' feature:
|
||||
*
|
||||
* Entries in the cache may have a 'flush dependency' on another entry 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 parent entry for an entry in a flush
|
||||
* dependency relationship.
|
||||
*
|
||||
* 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_height: The height of the entry, which is one greater than the
|
||||
* maximum height of any of its child entries..
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* Fields supporting the hash table:
|
||||
*
|
||||
* Fields in the cache are indexed by a more or less conventional hash table.
|
||||
@ -504,11 +535,13 @@ typedef struct H5C_cache_entry_t
|
||||
hbool_t destroy_in_progress;
|
||||
hbool_t free_file_space_on_destroy;
|
||||
|
||||
/* fields supporting the 'flush dependency height': */
|
||||
/* 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;
|
||||
hbool_t pinned_from_client;
|
||||
hbool_t pinned_from_cache;
|
||||
|
||||
/* fields supporting the hash table: */
|
||||
|
||||
|
195
test/cache.c
195
test/cache.c
@ -31214,6 +31214,145 @@ check_flush_deps(void)
|
||||
if ( !pass ) CACHE_ERROR("verify_entry_status failed")
|
||||
}
|
||||
|
||||
/* Test Case #6a - Make certain that flush dependency relationship with parent
|
||||
* already pinned works (unpin ater destroying flush dependency)
|
||||
*/
|
||||
|
||||
/* Create flush dependency between entries 0 (child) & 1 (parent) */
|
||||
{
|
||||
protect_entry(cache_ptr, entry_type, 1);
|
||||
if ( !pass ) CACHE_ERROR("protect_entry failed")
|
||||
|
||||
pin_entry(cache_ptr, entry_type, 1);
|
||||
if ( !pass ) CACHE_ERROR("pin_entry failed")
|
||||
|
||||
create_flush_dependency(cache_ptr, entry_type, 1, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("create_flush_dependency failed")
|
||||
|
||||
/* Change expected values, and verify the status of the entries
|
||||
* after creating flush dependency
|
||||
*/
|
||||
expected[0].flush_dep_par_type = entry_type;
|
||||
expected[0].flush_dep_par_idx = 1;
|
||||
expected[1].is_protected = TRUE;
|
||||
expected[1].is_pinned = TRUE;
|
||||
expected[1].child_flush_dep_height_rc[0] = 1;
|
||||
expected[1].flush_dep_height = 1;
|
||||
|
||||
/* Verify the status */
|
||||
verify_entry_status(cache_ptr, /* H5C_t * cache_ptr */
|
||||
(int)0, /* int tag */
|
||||
(int)5, /* int num_entries */
|
||||
expected); /* struct expected_entry_staus[] */
|
||||
if ( !pass ) CACHE_ERROR("verify_entry_status failed")
|
||||
}
|
||||
|
||||
/* Unpin entry & destroy flush dependency between entries 0 (child) & 1 (parent) */
|
||||
{
|
||||
destroy_flush_dependency(cache_ptr, entry_type, 1, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("destroy_flush_dependency failed")
|
||||
|
||||
unpin_entry(cache_ptr, entry_type, 1);
|
||||
if ( !pass ) CACHE_ERROR("unpin_entry failed")
|
||||
|
||||
unprotect_entry(cache_ptr, /* H5C_t * cache_ptr */
|
||||
entry_type, /* int32_t type */
|
||||
1, /* int32_t idx */
|
||||
FALSE, /* int32_t dirty */
|
||||
H5C__NO_FLAGS_SET); /* unsigned int flags */
|
||||
if ( !pass ) CACHE_ERROR("unprotect_entry failed")
|
||||
|
||||
/* Change expected values, and verify the status of the entries
|
||||
* after destroy flush dependency
|
||||
*/
|
||||
expected[0].flush_dep_par_type = -1;
|
||||
expected[0].flush_dep_par_idx = -1;
|
||||
expected[1].is_protected = FALSE;
|
||||
expected[1].is_pinned = FALSE;
|
||||
expected[1].child_flush_dep_height_rc[0] = 0;
|
||||
expected[1].flush_dep_height = 0;
|
||||
|
||||
/* Verify the status */
|
||||
verify_entry_status(cache_ptr, /* H5C_t * cache_ptr */
|
||||
(int)0, /* int tag */
|
||||
(int)5, /* int num_entries */
|
||||
expected); /* struct expected_entry_staus[] */
|
||||
if ( !pass ) CACHE_ERROR("verify_entry_status failed")
|
||||
}
|
||||
|
||||
/* Test Case #6b - Make certain that flush dependency relationship with parent
|
||||
* already pinned works (unpin before destroying flush dependency)
|
||||
*/
|
||||
|
||||
/* Create flush dependency between entries 0 (child) & 1 (parent) */
|
||||
{
|
||||
protect_entry(cache_ptr, entry_type, 1);
|
||||
if ( !pass ) CACHE_ERROR("protect_entry failed")
|
||||
|
||||
pin_entry(cache_ptr, entry_type, 1);
|
||||
if ( !pass ) CACHE_ERROR("pin_entry failed")
|
||||
|
||||
create_flush_dependency(cache_ptr, entry_type, 1, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("create_flush_dependency failed")
|
||||
|
||||
/* Change expected values, and verify the status of the entries
|
||||
* after creating flush dependency
|
||||
*/
|
||||
expected[0].flush_dep_par_type = entry_type;
|
||||
expected[0].flush_dep_par_idx = 1;
|
||||
expected[1].is_protected = TRUE;
|
||||
expected[1].is_pinned = TRUE;
|
||||
expected[1].child_flush_dep_height_rc[0] = 1;
|
||||
expected[1].flush_dep_height = 1;
|
||||
|
||||
/* Verify the status */
|
||||
verify_entry_status(cache_ptr, /* H5C_t * cache_ptr */
|
||||
(int)0, /* int tag */
|
||||
(int)5, /* int num_entries */
|
||||
expected); /* struct expected_entry_staus[] */
|
||||
if ( !pass ) CACHE_ERROR("verify_entry_status failed")
|
||||
}
|
||||
|
||||
/* Unpin entry & destroy flush dependency between entries 0 (child) & 1 (parent) */
|
||||
{
|
||||
unpin_entry(cache_ptr, entry_type, 1);
|
||||
if ( !pass ) CACHE_ERROR("unpin_entry failed")
|
||||
|
||||
/* Verify the status */
|
||||
verify_entry_status(cache_ptr, /* H5C_t * cache_ptr */
|
||||
(int)0, /* int tag */
|
||||
(int)5, /* int num_entries */
|
||||
expected); /* struct expected_entry_staus[] */
|
||||
if ( !pass ) CACHE_ERROR("verify_entry_status failed")
|
||||
|
||||
destroy_flush_dependency(cache_ptr, entry_type, 1, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("destroy_flush_dependency failed")
|
||||
|
||||
unprotect_entry(cache_ptr, /* H5C_t * cache_ptr */
|
||||
entry_type, /* int32_t type */
|
||||
1, /* int32_t idx */
|
||||
FALSE, /* int32_t dirty */
|
||||
H5C__NO_FLAGS_SET); /* unsigned int flags */
|
||||
if ( !pass ) CACHE_ERROR("unprotect_entry failed")
|
||||
|
||||
/* Change expected values, and verify the status of the entries
|
||||
* after destroy flush dependency
|
||||
*/
|
||||
expected[0].flush_dep_par_type = -1;
|
||||
expected[0].flush_dep_par_idx = -1;
|
||||
expected[1].is_protected = FALSE;
|
||||
expected[1].is_pinned = FALSE;
|
||||
expected[1].child_flush_dep_height_rc[0] = 0;
|
||||
expected[1].flush_dep_height = 0;
|
||||
|
||||
/* Verify the status */
|
||||
verify_entry_status(cache_ptr, /* H5C_t * cache_ptr */
|
||||
(int)0, /* int tag */
|
||||
(int)5, /* int num_entries */
|
||||
expected); /* struct expected_entry_staus[] */
|
||||
if ( !pass ) CACHE_ERROR("verify_entry_status failed")
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
if(cache_ptr)
|
||||
@ -31257,7 +31396,7 @@ check_flush_deps_err(void)
|
||||
/* Loop over test cases, check for various errors in configuring flush
|
||||
* dependencies. Verify that all performs as expected.
|
||||
*/
|
||||
for(test_count = 0; test_count < 11; test_count++) {
|
||||
for(test_count = 0; test_count < 9; test_count++) {
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t result; /* Generic return value */
|
||||
|
||||
@ -31421,36 +31560,14 @@ check_flush_deps_err(void)
|
||||
if ( !pass ) CACHE_ERROR("unprotect_entry failed")
|
||||
break;
|
||||
|
||||
/* Verify that parent entry isn't already pinned */
|
||||
case 4:
|
||||
protect_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("protect_entry failed")
|
||||
|
||||
pin_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("pin_entry failed")
|
||||
|
||||
result = H5C_create_flush_dependency(cache_ptr, &((entries[entry_type])[0]), &((entries[entry_type])[1]));
|
||||
if( result != FAIL ) CACHE_ERROR("Creating dependency when parent is pinned")
|
||||
|
||||
unpin_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("unpin_entry failed")
|
||||
|
||||
unprotect_entry(cache_ptr, /* H5C_t * cache_ptr */
|
||||
entry_type, /* int32_t type */
|
||||
0, /* int32_t idx */
|
||||
FALSE, /* int32_t dirty */
|
||||
H5C__NO_FLAGS_SET); /* unsigned int flags */
|
||||
if ( !pass ) CACHE_ERROR("unprotect_entry failed")
|
||||
break;
|
||||
|
||||
/* Verify that parent entry must be protected */
|
||||
case 5:
|
||||
case 4:
|
||||
result = H5C_destroy_flush_dependency(cache_ptr, &((entries[entry_type])[0]), &((entries[entry_type])[1]));
|
||||
if( result != FAIL ) CACHE_ERROR("Destroying [non-existant] dependency when parent isn't protected")
|
||||
break;
|
||||
|
||||
/* Verify that parent entry has flush dependency */
|
||||
case 6:
|
||||
case 5:
|
||||
protect_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("protect_entry failed")
|
||||
|
||||
@ -31465,30 +31582,8 @@ check_flush_deps_err(void)
|
||||
if ( !pass ) CACHE_ERROR("unprotect_entry failed")
|
||||
break;
|
||||
|
||||
/* Verify that parent entry is still pinned */
|
||||
case 7:
|
||||
protect_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("protect_entry failed")
|
||||
|
||||
create_flush_dependency(cache_ptr, entry_type, 0, entry_type, 1);
|
||||
if ( !pass ) CACHE_ERROR("create_flush_dependency failed")
|
||||
|
||||
unpin_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("unpin_entry failed")
|
||||
|
||||
result = H5C_destroy_flush_dependency(cache_ptr, &((entries[entry_type])[0]), &((entries[entry_type])[1]));
|
||||
if( result != FAIL ) CACHE_ERROR("Destroying dependency when parent isn't in relationship")
|
||||
|
||||
unprotect_entry(cache_ptr, /* H5C_t * cache_ptr */
|
||||
entry_type, /* int32_t type */
|
||||
0, /* int32_t idx */
|
||||
FALSE, /* int32_t dirty */
|
||||
H5C__NO_FLAGS_SET); /* unsigned int flags */
|
||||
if ( !pass ) CACHE_ERROR("unprotect_entry failed")
|
||||
break;
|
||||
|
||||
/* Verify that child entry is in flush dependency relationship */
|
||||
case 8:
|
||||
case 6:
|
||||
protect_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("protect_entry failed")
|
||||
|
||||
@ -31510,7 +31605,7 @@ check_flush_deps_err(void)
|
||||
break;
|
||||
|
||||
/* Verify that parent has child entries at this height */
|
||||
case 9:
|
||||
case 7:
|
||||
protect_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("protect_entry failed")
|
||||
|
||||
@ -31565,7 +31660,7 @@ check_flush_deps_err(void)
|
||||
|
||||
|
||||
/* Verify that child entry is child of parent */
|
||||
case 10:
|
||||
case 8:
|
||||
protect_entry(cache_ptr, entry_type, 0);
|
||||
if ( !pass ) CACHE_ERROR("protect_entry failed")
|
||||
|
||||
|
@ -1663,6 +1663,8 @@ reset_entries(void)
|
||||
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].pinned_from_client = FALSE;
|
||||
base_addr[j].pinned_from_cache = FALSE;
|
||||
|
||||
base_addr[j].flush_order = 0;
|
||||
|
||||
@ -2279,8 +2281,6 @@ verify_entry_status(H5C_t * cache_ptr,
|
||||
|
||||
i++;
|
||||
} /* while */
|
||||
if(!pass)
|
||||
HDfprintf(stderr, "failure_mssg = '%s'\n", failure_mssg);
|
||||
|
||||
return;
|
||||
|
||||
@ -2680,14 +2680,15 @@ insert_entry(H5C_t * cache_ptr,
|
||||
if ( insert_pinned ) {
|
||||
|
||||
HDassert( entry_ptr->header.is_pinned );
|
||||
entry_ptr->is_pinned = TRUE;
|
||||
|
||||
} else {
|
||||
|
||||
HDassert( ! ( entry_ptr->header.is_pinned ) );
|
||||
entry_ptr->is_pinned = FALSE;
|
||||
|
||||
}
|
||||
entry_ptr->is_pinned = insert_pinned;
|
||||
entry_ptr->pinned_from_client = insert_pinned;
|
||||
|
||||
HDassert( entry_ptr->header.is_dirty );
|
||||
HDassert( ((entry_ptr->header).type)->id == type );
|
||||
}
|
||||
@ -3201,7 +3202,7 @@ pin_entry(H5C_t * cache_ptr,
|
||||
HDassert( entry_ptr->type == type );
|
||||
HDassert( entry_ptr == entry_ptr->self );
|
||||
HDassert( entry_ptr->is_protected );
|
||||
HDassert( !(entry_ptr->is_pinned) );
|
||||
HDassert( !(entry_ptr->pinned_from_client) );
|
||||
|
||||
result = H5C_pin_protected_entry(cache_ptr, (void *)entry_ptr);
|
||||
|
||||
@ -3217,7 +3218,9 @@ pin_entry(H5C_t * cache_ptr,
|
||||
|
||||
} else {
|
||||
|
||||
entry_ptr->pinned_from_client = TRUE;
|
||||
entry_ptr->is_pinned = TRUE;
|
||||
|
||||
}
|
||||
} /* end if */
|
||||
|
||||
@ -3269,12 +3272,15 @@ unpin_entry(H5C_t * cache_ptr,
|
||||
HDassert( entry_ptr == entry_ptr->self );
|
||||
HDassert( entry_ptr->cache_ptr == cache_ptr );
|
||||
HDassert( entry_ptr->header.is_pinned );
|
||||
HDassert( entry_ptr->header.pinned_from_client );
|
||||
HDassert( entry_ptr->is_pinned );
|
||||
HDassert( entry_ptr->pinned_from_client );
|
||||
|
||||
result = H5C_unpin_entry(cache_ptr, (void *)entry_ptr);
|
||||
|
||||
if ( ( result < 0 ) ||
|
||||
( entry_ptr->header.is_pinned ) ||
|
||||
( entry_ptr->header.pinned_from_client ) ||
|
||||
( entry_ptr->header.is_pinned && !entry_ptr->header.pinned_from_cache ) ||
|
||||
( entry_ptr->header.type != &(types[type]) ) ||
|
||||
( entry_ptr->size != entry_ptr->header.size ) ||
|
||||
( entry_ptr->addr != entry_ptr->header.addr ) ) {
|
||||
@ -3284,7 +3290,9 @@ unpin_entry(H5C_t * cache_ptr,
|
||||
|
||||
}
|
||||
|
||||
entry_ptr->is_pinned = FALSE;
|
||||
entry_ptr->pinned_from_client = FALSE;
|
||||
|
||||
entry_ptr->is_pinned = entry_ptr->pinned_from_cache;
|
||||
|
||||
HDassert( ((entry_ptr->header).type)->id == type );
|
||||
|
||||
@ -3430,12 +3438,14 @@ unprotect_entry(H5C_t * cache_ptr,
|
||||
if ( pin_flag_set ) {
|
||||
|
||||
HDassert ( entry_ptr->header.is_pinned );
|
||||
entry_ptr->pinned_from_client = TRUE;
|
||||
entry_ptr->is_pinned = TRUE;
|
||||
|
||||
} else if ( unpin_flag_set ) {
|
||||
|
||||
HDassert ( ! ( entry_ptr->header.is_pinned ) );
|
||||
entry_ptr->is_pinned = FALSE;
|
||||
HDassert ( entry_ptr->header.is_pinned == entry_ptr->header.pinned_from_cache );
|
||||
entry_ptr->pinned_from_client = FALSE;
|
||||
entry_ptr->is_pinned = entry_ptr->pinned_from_cache;
|
||||
|
||||
}
|
||||
}
|
||||
@ -3592,12 +3602,14 @@ unprotect_entry_with_size_change(H5C_t * cache_ptr,
|
||||
if ( pin_flag_set ) {
|
||||
|
||||
HDassert ( entry_ptr->header.is_pinned );
|
||||
entry_ptr->pinned_from_client = TRUE;
|
||||
entry_ptr->is_pinned = TRUE;
|
||||
|
||||
} else if ( unpin_flag_set ) {
|
||||
|
||||
HDassert ( ! ( entry_ptr->header.is_pinned ) );
|
||||
entry_ptr->is_pinned = FALSE;
|
||||
HDassert ( entry_ptr->header.is_pinned == entry_ptr->header.pinned_from_cache );
|
||||
entry_ptr->pinned_from_client = FALSE;
|
||||
entry_ptr->is_pinned = entry_ptr->pinned_from_cache;
|
||||
|
||||
}
|
||||
}
|
||||
@ -4979,6 +4991,7 @@ create_flush_dependency(H5C_t * cache_ptr,
|
||||
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]++;
|
||||
par_entry_ptr->pinned_from_cache = TRUE;
|
||||
if( !par_is_pinned )
|
||||
par_entry_ptr->is_pinned = TRUE;
|
||||
|
||||
@ -5051,6 +5064,7 @@ destroy_flush_dependency(H5C_t * cache_ptr,
|
||||
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 == par_entry_ptr->self );
|
||||
|
||||
@ -5089,8 +5103,10 @@ destroy_flush_dependency(H5C_t * cache_ptr,
|
||||
|
||||
if((unsigned)(i + 1) < prev_par_flush_dep_height) {
|
||||
par_entry_ptr->flush_dep_height = (unsigned)(i + 1);
|
||||
if(i < 0)
|
||||
par_entry_ptr->is_pinned = FALSE;
|
||||
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) {
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "h5test.h"
|
||||
|
||||
/* Macro to make error reporting easier */
|
||||
#define CACHE_ERROR(s) {failure_mssg = "Line #" H5_TOSTRING(__LINE__) ": " s ; goto done;}
|
||||
#define CACHE_ERROR(s) {failure_mssg = "Line #" H5_TOSTRING(__LINE__) ": " s ; pass = FALSE; goto done;}
|
||||
|
||||
#define NO_CHANGE -1
|
||||
|
||||
@ -306,6 +306,8 @@ typedef struct test_entry_t
|
||||
* dependency children
|
||||
*/
|
||||
unsigned flush_dep_height; /* flush dependency height of entry */
|
||||
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 */
|
||||
} test_entry_t;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user