diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2016-06-13 17:49:39 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2016-06-13 17:49:39 (GMT) |
commit | 7a9e13afdb134bafc070cf8bd2087a84fd0d2334 (patch) | |
tree | c16578adf13fb9312870afff86332ad190add859 /src/H5C.c | |
parent | 1db1d99883397d92dc6984841fecfc391c52676d (diff) | |
download | hdf5-7a9e13afdb134bafc070cf8bd2087a84fd0d2334.zip hdf5-7a9e13afdb134bafc070cf8bd2087a84fd0d2334.tar.gz hdf5-7a9e13afdb134bafc070cf8bd2087a84fd0d2334.tar.bz2 |
[svn-r30068] Description:
Bring metadata cache corking to trunk.
Tested on:
MacOSX/64 10.11.5 (amazon) w/serial, parallel & production
(h5committest forthcoming)
Diffstat (limited to 'src/H5C.c')
-rw-r--r-- | src/H5C.c | 185 |
1 files changed, 177 insertions, 8 deletions
@@ -209,6 +209,9 @@ H5FL_DEFINE_STATIC(H5C_t); /* Declare extern free list to manage the H5C_collective_write_t struct */ H5FL_EXTERN(H5C_collective_write_t); +/* Declare a free list to manage corked object addresses */ +H5FL_DEFINE_STATIC(haddr_t); + /*------------------------------------------------------------------------- @@ -276,6 +279,11 @@ H5C_create(size_t max_cache_size, HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list.") } + if ( (cache_ptr->cork_list_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list for corked object addresses.") + } + /* If we get this far, we should succeed. Go ahead and initialize all * the fields. */ @@ -451,6 +459,9 @@ done: if ( cache_ptr->slist_ptr != NULL ) H5SL_close(cache_ptr->slist_ptr); + if ( cache_ptr->cork_list_ptr != NULL ) + H5SL_close(cache_ptr->cork_list_ptr); + cache_ptr->magic = 0; cache_ptr = H5FL_FREE(H5C_t, cache_ptr); @@ -650,6 +661,34 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr, /*------------------------------------------------------------------------- + * Function: H5C_free_cork_list_cb + * + * Purpose: Callback function to free the list of object addresses + * on the skip list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5C_free_cork_list_cb(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data) +{ + haddr_t *addr = (haddr_t *)_item; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(addr); + + /* Release the item */ + addr = H5FL_FREE(haddr_t, addr); + + FUNC_LEAVE_NOAPI(0) +} /* H5C_free_cork_list_cb() */ + + +/*------------------------------------------------------------------------- * Function: H5C_dest * * Purpose: Flush all data to disk and destroy the cache. @@ -694,6 +733,11 @@ H5C_dest(H5F_t * f, hid_t dxpl_id) cache_ptr->slist_ptr = NULL; } /* end if */ + if(cache_ptr->cork_list_ptr != NULL) { + H5SL_destroy(cache_ptr->cork_list_ptr, H5C_free_cork_list_cb, NULL); + cache_ptr->cork_list_ptr = NULL; + } /* end if */ + /* Only display count of number of calls to H5C_get_entry_ptr_from_add() * if NDEBUG is undefined, and H5C_DO_SANITY_CHECKS is defined. Need * this as the print statement will upset windows, and we frequently @@ -1267,6 +1311,10 @@ H5C_insert_entry(H5F_t * f, if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Cannot tag metadata entry") + /* Set the entry's cork status */ + if(H5C_cork(cache_ptr, entry_ptr->tag, H5C__GET_CORKED, &entry_ptr->is_corked) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Cannot retrieve entry's cork status") + entry_ptr->is_protected = FALSE; entry_ptr->is_read_only = FALSE; entry_ptr->ro_ref_count = 0; @@ -2241,6 +2289,10 @@ H5C_protect(H5F_t * f, if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, NULL, "Cannot tag metadata entry") + /* Set the entry's cork status */ + if(H5C_cork(cache_ptr, entry_ptr->tag, H5C__GET_CORKED, &entry_ptr->is_corked) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "Cannot retrieve entry's cork status") + /* If the entry is very large, and we are configured to allow it, * we may wish to perform a flash cache size increase. */ @@ -3606,7 +3658,7 @@ H5C_dump_cache(H5C_t * cache_ptr, HDfprintf(stdout, "\n\nDump of metadata cache \"%s\".\n", cache_name); HDfprintf(stdout, - "Num: Addr: Len: Type: Prot: Pinned: Dirty:\n"); + "Num: Addr: Tag: Len: Type: Prot: Pinned: Dirty: Corked:\n"); i = 0; @@ -3626,14 +3678,16 @@ H5C_dump_cache(H5C_t * cache_ptr, HDassert( entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ); HDfprintf(stdout, - "%s%d 0x%08llx 0x%3llx %2d %d %d %d\n", + "%s%d 0x%16llx 0x%3llx 0x%3llx %2d %d %d %d %d\n", cache_ptr->prefix, i, (long long)(entry_ptr->addr), + (long long)(entry_ptr->tag), (long long)(entry_ptr->size), (int)(entry_ptr->type->id), (int)(entry_ptr->is_protected), (int)(entry_ptr->is_pinned), - (int)(entry_ptr->is_dirty)); + (int)(entry_ptr->is_dirty), + (int)(entry_ptr->is_corked)); /* increment node_ptr before we delete its target */ node_ptr = H5SL_next(node_ptr); @@ -5423,6 +5477,8 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f, ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE ) && ( bytes_evicted < eviction_size_limit ) ) { + hbool_t corked = FALSE; + HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); HDassert( ! (entry_ptr->is_protected) ); HDassert( ! (entry_ptr->is_read_only) ); @@ -5436,7 +5492,10 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f, prev_is_dirty = prev_ptr->is_dirty; } - if ( entry_ptr->is_dirty ) { + /* dirty corked entry is skipped */ + if(entry_ptr->is_corked && entry_ptr->is_dirty) + corked = TRUE; + else if ( entry_ptr->is_dirty ) { /* reset entries_removed_counter and * last_entry_removed_ptr prior to the call to @@ -5467,7 +5526,10 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f, if ( prev_ptr != NULL ) { - if ( ( restart_scan ) + if(corked) /* dirty corked entry is skipped */ + entry_ptr = prev_ptr; + + else if ( ( restart_scan ) || ( prev_ptr->is_dirty != prev_is_dirty ) || @@ -8046,6 +8108,7 @@ H5C_make_space_in_cache(H5F_t * f, H5C_cache_entry_t * entry_ptr; H5C_cache_entry_t * prev_ptr; H5C_cache_entry_t * next_ptr; + int32_t num_corked_entries = 0; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -8102,7 +8165,13 @@ H5C_make_space_in_cache(H5F_t * f, prev_is_dirty = prev_ptr->is_dirty; } - if ( ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE ) && + if (entry_ptr->is_corked && entry_ptr->is_dirty) { + + /* Skip "dirty" corked entries. */ + ++num_corked_entries; + didnt_flush_entry = TRUE; + + } else if ( ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE ) && ( ! entry_ptr->flush_in_progress ) ) { didnt_flush_entry = FALSE; @@ -8250,12 +8319,14 @@ H5C_make_space_in_cache(H5F_t * f, } #endif /* H5C_COLLECT_CACHE_STATS */ + + /* NEED: work on a better assert for corked entries */ HDassert( ( entries_examined > (2 * initial_list_len) ) || ( (cache_ptr->pl_size + cache_ptr->pel_size + cache_ptr->min_clean_size) > cache_ptr->max_cache_size ) || ( ( cache_ptr->clean_index_size + empty_space ) - >= cache_ptr->min_clean_size ) ); - + >= cache_ptr->min_clean_size ) || + ( ( num_corked_entries ))); #if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS HDassert( ( entries_examined > (2 * initial_list_len) ) || @@ -8976,6 +9047,104 @@ done: /*------------------------------------------------------------------------- + * + * Function: H5C_cork + * + * Purpose: To cork/uncork/get cork status of an object depending on "action": + * H5C__SET_CORK: + * To cork the object + * Return error if the object is already corked + * H5C__UNCORK: + * To uncork the obejct + * Return error if the object is not corked + * H5C__GET_CORKED: + * To retrieve the cork status of an object in + * the parameter "corked" + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_cork(H5C_t * cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked) +{ + haddr_t *ptr; /* Points to an address */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Assertions */ + HDassert(cache_ptr != NULL); + HDassert(H5F_addr_defined(obj_addr)); + HDassert(action == H5C__SET_CORK || action == H5C__UNCORK || action == H5C__GET_CORKED); + + /* Search the list of corked object addresses in the cache */ + ptr = (haddr_t *)H5SL_search(cache_ptr->cork_list_ptr, &obj_addr); + + if(H5C__GET_CORKED == action) { + HDassert(corked); + if(ptr != NULL && *ptr == obj_addr) + *corked = TRUE; + else + *corked = FALSE; + } /* end if */ + else { + hbool_t is_corked; /* Cork status for an entry */ + + /* Sanity check */ + HDassert(H5C__SET_CORK == action || H5C__UNCORK == action); + + /* Perform appropriate action */ + if(H5C__SET_CORK == action) { + haddr_t *addr_ptr = NULL; /* Points to an address */ + + if(ptr != NULL && *ptr == obj_addr) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't cork an already corked object") + + /* Allocate address */ + if(NULL == (addr_ptr = H5FL_MALLOC(haddr_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Insert into the list */ + *addr_ptr = obj_addr; + if(H5SL_insert(cache_ptr->cork_list_ptr, addr_ptr, addr_ptr) < 0) { + addr_ptr = H5FL_FREE(haddr_t, addr_ptr); + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't insert address into cork list") + } /* end if */ + + /* Set the entry's cork status */ + is_corked = TRUE; + } /* end if */ + else { + if(ptr == NULL) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't uncork an object that is not corked ") + + /* Remove the object address from the list */ + ptr = (haddr_t *)H5SL_remove(cache_ptr->cork_list_ptr, &obj_addr); + if(ptr == NULL || *ptr != obj_addr) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't remove address from list") + + /* Free address */ + ptr = H5FL_FREE(haddr_t, ptr); + + /* Set the entry's cork status */ + is_corked = FALSE; + } /* end else */ + + /* Mark existing cache entries with tag (obj_addr) to the cork status */ + if(H5C__mark_tagged_entries_cork(cache_ptr, obj_addr, is_corked) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't mark cork status on entry") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_cork() */ + + +/*------------------------------------------------------------------------- * Function: H5C__generate_image * * Purpose: Serialize an entry and generate its image. |