diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5C.c | 268 | ||||
-rw-r--r-- | src/H5Dproxy.c | 612 | ||||
-rw-r--r-- | src/H5Oflush.c | 60 | ||||
-rw-r--r-- | src/H5Oprivate.h | 1 | ||||
-rw-r--r-- | src/H5SMcache.c | 3 |
5 files changed, 143 insertions, 801 deletions
@@ -9224,21 +9224,17 @@ H5C_make_space_in_cache(H5F_t * f, prev_is_dirty = prev_ptr->is_dirty; } - if ( (entry_ptr->type)->id == H5C__EPOCH_MARKER_TYPE) { - /* Skip epoch markers. Set result to SUCCEED to avoid - * triggering the error code below. - */ - didnt_flush_entry = TRUE; - result = SUCCEED; - } else if (entry_ptr->is_corked && entry_ptr->is_dirty) { + if (entry_ptr->is_corked && entry_ptr->is_dirty) { + /* Skip "dirty" corked entries. Set result to SUCCEED to avoid * triggering the error code below. */ ++num_corked_entries; didnt_flush_entry = TRUE; result = SUCCEED; - } else { + + } else if ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE) { didnt_flush_entry = FALSE; @@ -9294,7 +9290,14 @@ H5C_make_space_in_cache(H5F_t * f, total_entries_scanned++; #endif /* H5C_COLLECT_CACHE_STATS */ - } + } else { + + /* Skip epoch markers. Set result to SUCCEED to avoid + * triggering the error code below. + */ + didnt_flush_entry = TRUE; + result = SUCCEED; + } if ( result < 0 ) { @@ -10120,9 +10123,9 @@ done: /*------------------------------------------------------------------------- * - * Function: H5C_flush_tagged_entries + * Function: H5C_evict_tagged_entries * - * Purpose: Flushes all entries with the specified tag to disk. + * Purpose: Evicts all entries with the specified tag from cache * * Return: FAIL if error is detected, SUCCEED otherwise. * @@ -10132,13 +10135,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5C_flush_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, haddr_t tag) +H5C_evict_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, haddr_t tag) { /* Variable Declarations */ + herr_t status; + H5C_cache_entry_t * entry_ptr = NULL; + H5C_cache_entry_t * next_entry_ptr = NULL; + int i; + hbool_t evicted_entries_last_pass; + hbool_t pinned_entries_need_evicted; + hbool_t first_flush = TRUE; + H5C_t *cache_ptr = NULL; - herr_t result; - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; + /* Function Enter Macro */ FUNC_ENTER_NOAPI(FAIL) /* Assertions */ @@ -10148,65 +10159,84 @@ H5C_flush_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_ /* Get cache pointer */ cache_ptr = f->shared->cache; - /* Mark all entries with specified tag */ - if ( (result = H5C_mark_tagged_entries(cache_ptr, tag, FALSE)) < 0 ) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't mark tagged entries") + HDassert( cache_ptr != NULL ); + HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); - /* Flush all marked entries */ - if(H5C_flush_marked_entries(f, primary_dxpl_id, secondary_dxpl_id, cache_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush marked entries") + /* Start evicting entries */ + do { -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5C_flush_tagged_entries */ + /* Reset pinned/evicted trackers */ + pinned_entries_need_evicted = FALSE; + evicted_entries_last_pass = FALSE; - -/*------------------------------------------------------------------------- - * - * Function: H5C_evict_tagged_entries - * - * Purpose: Evicts all entries with the specified tag to disk. - * - * Return: FAIL if error is detected, SUCCEED otherwise. - * - * Programmer: Mike McGreevy - * August 19, 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5C_evict_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, haddr_t tag) -{ - /* Variables */ - H5C_t *cache_ptr = NULL; - herr_t result; - herr_t ret_value = SUCCEED; + /* Iterate through entries in the index. */ + for (i = 0; i < H5C__HASH_TABLE_LEN; i++) { - /* Function Enter Macro */ - FUNC_ENTER_NOAPI(FAIL) + next_entry_ptr = cache_ptr->index[i]; - /* Assertions */ - HDassert(f); - HDassert(f->shared); + while ( next_entry_ptr != NULL ) { - /* Get cache pointer */ - cache_ptr = f->shared->cache; + entry_ptr = next_entry_ptr; + next_entry_ptr = entry_ptr->ht_next; - /* Mark all entries with specified tag */ - if ( (result = H5C_mark_tagged_entries(cache_ptr, tag, TRUE)) < 0 ) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't mark tagged entries") + if(( entry_ptr->tag == tag ) || + ( entry_ptr->globality == H5C_GLOBALITY_MAJOR)) { - /* Evict all marked entries */ - if ( (result = H5C_evict_marked_entries(f, - primary_dxpl_id, - secondary_dxpl_id, - cache_ptr)) < 0 ) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't evict marked entries") + /* This entry will need to be evicted */ + + if ( entry_ptr->is_protected ) { + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict protected entry"); + } else if (entry_ptr->is_dirty) { + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict dirty entry"); + } else if (entry_ptr->is_pinned) { + + /* Can't evict at this time, but let's note that we hit a pinned + entry and we'll loop back around again (as evicting other + entries will hopefully unpin this entry) */ + + pinned_entries_need_evicted = TRUE; + + } else { + + /* Evict the Entry */ + + status = H5C_flush_single_entry(f, + primary_dxpl_id, + secondary_dxpl_id, + entry_ptr->type, + entry_ptr->addr, + H5C__FLUSH_INVALIDATE_FLAG | H5C__FLUSH_CLEAR_ONLY_FLAG, + &first_flush, + TRUE); + + if ( status < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "Entry eviction failed.") + + } + + evicted_entries_last_pass = TRUE; + + } /* end if */ + + } /* end if */ + + } /* end while */ + + } /* end for */ + + /* Keep doing this until we have stopped evicted entries */ + } while ((evicted_entries_last_pass == TRUE)); + + /* If we stop evicting entries and pinned entries still need evicted, + then we have a problem. */ + if (pinned_entries_need_evicted) { + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Pinned entries still need evicted?!"); + } /* end if */ done: - - /* Function Leave Macro */ - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(ret_value); } /* H5C_evict_tagged_entries */ @@ -10307,113 +10337,45 @@ done: /*------------------------------------------------------------------------- * - * Function: H5C_evict_marked_entries + * Function: H5C_flush_tagged_entries * - * Purpose: Evicts all marked entries in the cache. + * Purpose: Flushes all entries with the specified tag to disk. * * Return: FAIL if error is detected, SUCCEED otherwise. * * Programmer: Mike McGreevy - * July 16, 2010 + * August 19, 2010 * *------------------------------------------------------------------------- */ -static herr_t -H5C_evict_marked_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, H5C_t * cache_ptr) -{ +herr_t +H5C_flush_tagged_entries(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, haddr_t tag) +{ /* Variable Declarations */ - herr_t status; - herr_t ret_value = SUCCEED; - H5C_cache_entry_t * entry_ptr = NULL; - H5C_cache_entry_t * next_entry_ptr = NULL; - int i; - hbool_t evicted_entries_last_pass; - hbool_t pinned_entries_need_evicted; - hbool_t first_flush = TRUE; + H5C_t *cache_ptr = NULL; + herr_t result; + herr_t ret_value = SUCCEED; - /* Function Enter Macro */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI(FAIL) /* Assertions */ - HDassert( cache_ptr != NULL ); - HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); - - /* Start evicting entries */ - do { - - /* Reset pinned/evicted trackers */ - pinned_entries_need_evicted = FALSE; - evicted_entries_last_pass = FALSE; - - /* Iterate through entries in the index. */ - for (i = 0; i < H5C__HASH_TABLE_LEN; i++) { - - next_entry_ptr = cache_ptr->index[i]; - - while ( next_entry_ptr != NULL ) { - - entry_ptr = next_entry_ptr; - next_entry_ptr = entry_ptr->ht_next; - - if ( entry_ptr->flush_marker == TRUE ) { - - /* This entry will need to be evicted */ - - if ( entry_ptr->is_protected ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict protected entry"); - } else if (entry_ptr->is_dirty) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict dirty entry"); - } else if (entry_ptr->is_pinned) { - - /* Can't evict at this time, but let's note that we hit a pinned - entry and we'll loop back around again (as evicting other - entries will hopefully unpin this entry) */ - - pinned_entries_need_evicted = TRUE; - - } else { - - /* Evict the Entry */ - - status = H5C_flush_single_entry(f, - primary_dxpl_id, - secondary_dxpl_id, - entry_ptr->type, - entry_ptr->addr, - H5C__FLUSH_INVALIDATE_FLAG | H5C__FLUSH_CLEAR_ONLY_FLAG, - &first_flush, - TRUE); - - if ( status < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ - "Entry eviction failed.") - - } - - evicted_entries_last_pass = TRUE; - - } /* end if */ - - } /* end if */ - - } /* end while */ + HDassert(f); + HDassert(f->shared); - } /* end for */ + /* Get cache pointer */ + cache_ptr = f->shared->cache; - /* Keep doing this until we have stopped evicted entries */ - } while ((evicted_entries_last_pass == TRUE)); + /* Mark all entries with specified tag */ + if((result = H5C_mark_tagged_entries(cache_ptr, tag, FALSE)) < 0 ) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't mark tagged entries") - /* If we stop evicting entries and pinned entries still need evicted, - then we have a problem. */ - if (pinned_entries_need_evicted) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Pinned entries still need evicted?!"); - } /* end if */ + /* Flush all marked entries */ + if(H5C_flush_marked_entries(f, primary_dxpl_id, secondary_dxpl_id, cache_ptr) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush marked entries") done: - FUNC_LEAVE_NOAPI(ret_value); - -} /* H5C_evict_marked_entries */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_flush_tagged_entries */ /*------------------------------------------------------------------------- diff --git a/src/H5Dproxy.c b/src/H5Dproxy.c deleted file mode 100644 index 3db3cb7..0000000 --- a/src/H5Dproxy.c +++ /dev/null @@ -1,612 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the files COPYING and Copyright.html. COPYING can be found at the root * - * of the source code distribution tree; Copyright.html can be found at the * - * root level of an installed copy of the electronic HDF5 document set and * - * is linked from the top-level documents page. It can also be found at * - * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/*------------------------------------------------------------------------- - * - * Created: H5Dproxy.c - * May 19 2009 - * Quincey Koziol <koziol@hdfgroup.org> - * - * Purpose: Implement dataset's metadata cache proxy cache methods. - * - * Note: Chunk proxies exist only to make integrating the chunk - * cache with the metadata cache's flush dependencies - * easier and less coupled than directly tying them - * together. - * - * Chunk proxies never exist on disk (hence their lack of - * a 'load' callback) and their 'flush' callback just - * triggers a flush of the chunk it's a a proxy for. - * - *------------------------------------------------------------------------- - */ - -/****************/ -/* Module Setup */ -/****************/ - -#define H5D_PACKAGE /*suppress error about including H5Dpkg */ - - -/***********/ -/* Headers */ -/***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Dpkg.h" /* Dataset functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5MFprivate.h" /* File memory management */ - - -/****************/ -/* Local Macros */ -/****************/ - - -/******************/ -/* Local Typedefs */ -/******************/ - - -/********************/ -/* Package Typedefs */ -/********************/ - - -/********************/ -/* Local Prototypes */ -/********************/ - -/* Local routines */ -static herr_t H5D__chunk_proxy_destroy(H5D_chunk_proxy_t *proxy); - -/* Metadata cache (H5AC) callbacks */ -static H5D_chunk_proxy_t *H5D__cache_proxy_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata); -static herr_t H5D__cache_proxy_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5D_chunk_proxy_t *proxy, unsigned UNUSED * flags_ptr); -static herr_t H5D__cache_proxy_dest(H5F_t *f, H5D_chunk_proxy_t *proxy); -static herr_t H5D__cache_proxy_clear(H5F_t *f, H5D_chunk_proxy_t *proxy, hbool_t destroy); -static herr_t H5D__cache_proxy_size(const H5F_t *f, const H5D_chunk_proxy_t *proxy, size_t *size_ptr); - - -/*********************/ -/* Package Variables */ -/*********************/ - -/* H5D chunk proxy inherits cache-like properties from H5AC */ -const H5AC_class_t H5AC_CHUNK_PROXY[1] = {{ - H5AC_CHUNK_PROXY_ID, - (H5AC_load_func_t)H5D__cache_proxy_load, - (H5AC_flush_func_t)H5D__cache_proxy_flush, - (H5AC_dest_func_t)H5D__cache_proxy_dest, - (H5AC_clear_func_t)H5D__cache_proxy_clear, - (H5AC_notify_func_t)NULL, - (H5AC_size_func_t)H5D__cache_proxy_size, -}}; - - -/*****************************/ -/* Library Private Variables */ -/*****************************/ - - -/*******************/ -/* Local Variables */ -/*******************/ - -/* Declare a free list to manage H5D_chunk_proxy_t objects */ -H5FL_DEFINE_STATIC(H5D_chunk_proxy_t); - - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_load - * - * Purpose: Loads a chunk proxy from the disk. - * - * Note: This routine should never be invoked - * - * Return: Success: Pointer to a new chunk proxy - * Failure: NULL - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 21 2009 - * - *------------------------------------------------------------------------- - */ -static H5D_chunk_proxy_t * -H5D__cache_proxy_load(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr, - const void UNUSED *udata) -{ - H5D_chunk_proxy_t *ret_value; /* Return value */ - - FUNC_ENTER_STATIC - - /* This routine should never be invoked! */ - HDassert(0 && "H5D__cache_proxy_load called!?!"); - HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, NULL, "unable to load chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5D__cache_proxy_load() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_flush - * - * Purpose: Proxy for flushing a chunk in chunk cache under control - * of the metadata cache. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 19 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__cache_proxy_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, - H5D_chunk_proxy_t *proxy, unsigned UNUSED * flags_ptr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC -#ifdef QAK -HDfprintf(stderr, "%s: Flushing chunk proxy, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy); -#endif /* QAK */ - - /* check arguments */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); - HDassert(proxy); - - if(proxy->cache_info.is_dirty) { - H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ - H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ - - /* Fill the DXPL cache values for later use */ - if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") - - /* Flush the chunk for the proxy */ - /* (This must be safe from actually performing I/O when the chunk is - * clean - QAK, 5/21/2009) - */ - if(H5D__chunk_flush_entry(proxy->dset, dxpl_id, dxpl_cache, proxy->ent, FALSE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "can't flush chunk via proxy") - - /* Mark the chunk proxy as clean now */ - proxy->cache_info.is_dirty = FALSE; - } /* end if */ - - if(destroy) - if(H5D__cache_proxy_dest(f, proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to destroy chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5D__cache_proxy_flush() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_dest - * - * Purpose: Destroys a chunk proxy in memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 19 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__cache_proxy_dest(H5F_t UNUSED *f, H5D_chunk_proxy_t *proxy) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* - * Check arguments. - */ - HDassert(proxy); - - /* Free the chunk proxy itself */ - if(H5D__chunk_proxy_destroy(proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to destroy chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__cache_proxy_dest() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_clear - * - * Purpose: Mark a chunk proxy in memory as non-dirty. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 19 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__cache_proxy_clear(H5F_t *f, H5D_chunk_proxy_t *proxy, hbool_t destroy) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* - * Check arguments. - */ - HDassert(proxy); - - /* Reset the dirty flag. */ - proxy->cache_info.is_dirty = FALSE; - - if(destroy) - if(H5D__cache_proxy_dest(f, proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to destroy chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__cache_proxy_clear() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__cache_proxy_size - * - * Purpose: Compute the size in bytes of a chunk proxy - * on disk, and return it in *size_ptr. On failure, - * the value of *size_ptr is undefined. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * May 19 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__cache_proxy_size(const H5F_t UNUSED *f, const H5D_chunk_proxy_t UNUSED *proxy, - size_t *size_ptr) -{ - FUNC_ENTER_STATIC_NOERR - - /* check arguments */ - HDassert(f); - HDassert(proxy); - HDassert(size_ptr); - - /* Chunk proxies are represented as 1 byte in cache */ - /* (would be 0 bytes, but cache won't allow it currently -QAK, 5/19/09) */ - *size_ptr = 1; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5D__cache_proxy_size() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_create - * - * Purpose: Create a proxy for the chunk and insert it into the metadata cache. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, May 19, 2009 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_create(H5D_t *dset, hid_t dxpl_id, H5D_chunk_ud_t *udata, - H5D_rdcc_ent_t *ent) -{ - H5D_chunk_proxy_t *proxy = NULL; /* Chunk proxy */ - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - htri_t supported; /* Return value from "support" callback */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(dset); - HDassert(ent); - HDassert(dset->shared->layout.storage.u.chunk.ops->support); - - /* Get a temp. address for chunk proxy */ - if(HADDR_UNDEF == (ent->proxy_addr = H5MF_alloc_tmp(dset->oloc.file, (hsize_t)1))) - HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "file allocation failed for chunk proxy") -#ifdef QAK -HDfprintf(stderr, "%s: ent->proxy_addr = %a\n", FUNC, ent->proxy_addr); -#endif /* QAK */ - - /* Create chunk proxy object & initialize fields to zero */ - if(NULL == (proxy = H5FL_CALLOC(H5D_chunk_proxy_t))) - HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate chunk proxy") - ent->proxy = proxy; - - /* Point chunk proxy to chunk cache entry it's representing and dataset - * it's related to - */ - proxy->dset = dset; - proxy->ent = ent; - - /* Insert chunk proxy into metadata cache, pinned */ - if(H5AC_insert_entry(dset->oloc.file, dxpl_id, H5AC_CHUNK_PROXY, ent->proxy_addr, proxy, H5AC__PIN_ENTRY_FLAG) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't add chunk proxy to cache") - - /* Compose chunked index info struct */ - idx_info.f = dset->oloc.file; - idx_info.dxpl_id = dxpl_id; - idx_info.pline = &(dset->shared->dcpl_cache.pline); - idx_info.layout = &(dset->shared->layout.u.chunk); - idx_info.storage = &(dset->shared->layout.storage.u.chunk); - - /* Create a flush dependency between the proxy (as the child) and the - * metadata object in the index (as the parent). - */ - if((supported = (dset->shared->layout.storage.u.chunk.ops->support)(&idx_info, (H5D_chunk_ud_t *)udata, (H5AC_info_t *)proxy)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency for chunk proxy") - proxy->supported = (hbool_t)supported; - -done: - if(ret_value < 0) { - if(proxy) - proxy = H5FL_FREE(H5D_chunk_proxy_t, proxy); - ent->proxy_addr = HADDR_UNDEF; - ent->proxy = NULL; - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_create() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_remove - * - * Purpose: Remove a proxy for the chunk from the metadata cache. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, May 19, 2009 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_remove(const H5D_t *dset, hid_t dxpl_id, H5D_rdcc_ent_t *ent) -{ - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - H5D_chunk_ud_t udata; /* User-data for chunk */ - H5D_chunk_proxy_t *proxy = NULL; /* Chunk proxy */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(dset); - HDassert(ent); - HDassert(dset->shared->layout.storage.u.chunk.ops->unsupport); -#ifdef QAK -HDfprintf(stderr, "%s: ent->proxy_addr = %a\n", FUNC, ent->proxy_addr); -#endif /* QAK */ - - /* Protect the chunk proxy */ - if(NULL == (proxy = (H5D_chunk_proxy_t *)H5AC_protect(dset->oloc.file, dxpl_id, H5AC_CHUNK_PROXY, ent->proxy_addr, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect chunk proxy"); - - /* Compose chunked index info struct */ - idx_info.f = dset->oloc.file; - idx_info.dxpl_id = dxpl_id; - idx_info.pline = &(dset->shared->dcpl_cache.pline); - idx_info.layout = &(dset->shared->layout.u.chunk); - idx_info.storage = &(dset->shared->layout.storage.u.chunk); - - /* Compose user-data for chunk */ - udata.common.layout = &(dset->shared->layout.u.chunk); - udata.common.storage = &(dset->shared->layout.storage.u.chunk); - udata.common.offset = ent->offset; - udata.common.rdcc = &(dset->shared->cache.chunk); - /* Non-"common" data is not actually needed, except to provide a space to - * store this information if it is to be filled in as a side-effect of the - * unsupport callback (i.e. in H5D_btree_found) */ - - /* Remove flush dependency between the proxy (as the child) and the - * metadata object in the index (as the parent). - */ - if(proxy->supported) { - if((dset->shared->layout.storage.u.chunk.ops->unsupport)(&idx_info, &udata, (H5AC_info_t *)proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to remove flush dependency for chunk proxy") - proxy->supported = FALSE; - } /* end if */ - - /* Unpin & delete chunk proxy from metadata cache, taking ownership of it */ - if(H5AC_unprotect(dset->oloc.file, dxpl_id, H5AC_CHUNK_PROXY, ent->proxy_addr, proxy, (H5AC__UNPIN_ENTRY_FLAG | H5AC__DELETED_FLAG | H5AC__TAKE_OWNERSHIP_FLAG)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to release chunk proxy"); - - /* Reset information in chunk cache entry */ - ent->proxy_addr = HADDR_UNDEF; - ent->proxy = NULL; - - /* Release the chunk proxy object */ - if(H5D__chunk_proxy_destroy(proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to destroy chunk proxy") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_remove() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_mark - * - * Purpose: Mark a proxy for the chunk in the metadata cache as clean or - * dirty. - * - * Note: Currently, this code does not mark a chunk proxy as clean in - * the metadata cache. Doing so would require that this routine - * be invoked collectively when operating in parallel I/O mode - * and it's possible that this routine can be invoked during - * indepedent raw data I/O. - * - * So, the chunk proxy's dirty state in the metadata cache may - * be out of sync with the chunk itself, but only in the direction - * of being dirty when the chunk itself is clean. We'll call - * call the 'flush' callback for the chunk proxies more often - * than necessary, but as long as the chunk entry flushing - * routine doesn't actually flush the chunk when it's clean, - * there won't be too much overhead. - QAK, 5/21/2009 - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, May 19, 2009 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_mark(H5D_rdcc_ent_t *ent, hbool_t dirty) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(ent); -#ifdef QAK -HDfprintf(stderr, "%s: ent->proxy_addr = %a, dirty = %t\n", FUNC, ent->proxy_addr, dirty); -#endif /* QAK */ - - /* Check whether to mark the proxy as dirty */ - if(dirty) { - if(H5AC_mark_entry_dirty(ent->proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTMARKDIRTY, FAIL, "can't mark chunk proxy entry in metadata cache as dirty") - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_mark() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_destroy - * - * Purpose: Destroy a chunk proxy object - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, May 21, 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__chunk_proxy_destroy(H5D_chunk_proxy_t *proxy) -{ - FUNC_ENTER_STATIC_NOERR - - HDassert(proxy); - - /* Free the chunk proxy object */ - proxy->dset = NULL; - proxy->ent = NULL; - proxy = H5FL_FREE(H5D_chunk_proxy_t, proxy); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5D__chunk_proxy_destroy() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_create_flush_dep - * - * Purpose: Creates a flush dependency between the specified chunk - * (child) and parent, if not already present. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Neil Fortner - * 21 Sept 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_create_flush_dep(H5D_rdcc_ent_t *ent, void *parent) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(ent); - HDassert(parent); - - /* If the proxy already has a parent, do nothing. */ - if(!(ent->proxy->supported)) { - /* Create the flush dependency */ - if(H5AC_create_flush_dependency(parent, ent->proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency") - ent->proxy->supported = TRUE; - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_create_flush_dep() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_proxy_update_flush_dep - * - * Purpose: Updates the flush dependency of the specified chunk from - * old_parent to new_parent, if the dependency exists. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Neil Fortner - * 7 Sept 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__chunk_proxy_update_flush_dep(H5D_rdcc_ent_t *ent, void *old_parent, - void *new_parent) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - HDassert(ent); - HDassert(old_parent); - HDassert(new_parent); - - /* It is guaranteed that the proxy has a parent, because the dependency - * should always be present if the parent object exists in the index, and - * this should only be called when updating the parent object */ - HDassert(ent->proxy->supported); - - /* Update the flush dependencies */ - if(H5AC_destroy_flush_dependency(old_parent, ent->proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency") - if(H5AC_create_flush_dependency(new_parent, ent->proxy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_proxy_update_flush_dep() */ - diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 20e9c2d..3b6a3e6 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -42,6 +42,11 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Objects */ +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5O_oh_tag(const H5O_loc_t *oloc, hid_t dxpl_id, haddr_t *tag); + /*************/ /* Functions */ /*************/ @@ -109,14 +114,18 @@ done: herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id) { + haddr_t tag = 0; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* Private function */ - if(H5O_flush_metadata(oloc, H5AC_dxpl_id) < 0) + if(H5O_oh_tag(oloc, H5AC_dxpl_id, &tag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object metadata") + /* Flush metadata based on tag value of the object */ + if(H5F_flush_tagged_metadata(oloc->file, tag, H5AC_dxpl_id)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") + /* Check to invoke callback */ if(H5F_object_flush_cb(oloc->file, obj_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to do object flush callback") @@ -126,24 +135,23 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_flush_metadata + * Function: H5O_oh_tag * - * Purpose: Flush any metadata associated with this object. + * Purpose: Get object header's address--tag value for the object * - * Return: Success: Non-negative - * Failure: Negative + * Return: Success: Non-negative + * Failure: Negative * * Programmer: Mike McGreevy * May 19, 2010 * *------------------------------------------------------------------------- */ -herr_t -H5O_flush_metadata(const H5O_loc_t *oloc, hid_t dxpl_id) +static herr_t +H5O_oh_tag(const H5O_loc_t *oloc, hid_t dxpl_id, haddr_t *tag) { H5O_t *oh = NULL; /* Object header */ herr_t ret_value = SUCCEED; /* Return value */ - haddr_t tag = 0; FUNC_ENTER_NOAPI(FAIL) @@ -155,7 +163,7 @@ H5O_flush_metadata(const H5O_loc_t *oloc, hid_t dxpl_id) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object's object header") /* Get object header's address (i.e. the tag value for this object) */ - if (HADDR_UNDEF == (tag = H5O_OH_GET_ADDR(oh))) + if (HADDR_UNDEF == (*tag = H5O_OH_GET_ADDR(oh))) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get address of object header") /* Unprotect object header before attempting to flush it */ @@ -165,17 +173,13 @@ H5O_flush_metadata(const H5O_loc_t *oloc, hid_t dxpl_id) /* Reset object header pointer */ oh = NULL; - /* Flush metadata based on tag value of the object */ - if (H5F_flush_tagged_metadata(oloc->file, tag, dxpl_id)<0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") - done: /* Unprotect object header on failure */ if(oh && H5O_unprotect(oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_flush_metadata() */ +} /* end H5O_oh_tag() */ /*------------------------------------------------------------------------- @@ -245,10 +249,10 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) obj_loc.path = &obj_path; H5G_loc_reset(&obj_loc); - if((H5O_refresh_metadata_close(oid, oloc, &obj_loc, H5AC_dxpl_id)) < 0) + if((H5O_refresh_metadata_close(oid, oloc, &obj_loc, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") - if((H5O_refresh_metadata_reopen(oid, &obj_loc, H5AC_dxpl_id)) < 0) + if((H5O_refresh_metadata_reopen(oid, &obj_loc, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") done: @@ -285,24 +289,12 @@ H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t FUNC_ENTER_NOAPI(FAIL) - /* Get the object's object header */ - if(NULL == (oh = H5O_protect(&oloc, dxpl_id, H5AC_READ))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object's object header") - /* Make deep local copy of object's location information */ H5G_loc(oid, &tmp_loc); H5G_loc_copy(obj_loc, &tmp_loc, H5_COPY_DEEP); - /* Get object header's address (i.e. the tag value for this object) */ - if(HADDR_UNDEF == (tag = H5O_OH_GET_ADDR(oh))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get address of object header") - - /* Unprotect object header before attempting to flush it */ - if(oh && H5O_unprotect(&oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") - - /* Reset object header pointer */ - oh = NULL; + if(H5O_oh_tag(&oloc, dxpl_id, &tag) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to get object header address") /* Get cork status of the object with tag */ if(H5AC_cork(oloc.file, tag, H5AC__GET_CORKED, &corked) < 0) @@ -312,9 +304,9 @@ H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t if(H5I_dec_ref(oid) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to close object") - /* Flush the object's metadata before evicting it */ - if(H5O_flush_metadata(&oloc, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush object's metadata") + /* Flush metadata based on tag value of the object */ + if(H5F_flush_tagged_metadata(oloc.file, tag, dxpl_id)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") /* Evict the object's tagged metadata */ if(H5F_evict_tagged_metadata(oloc.file, tag, dxpl_id)<0) diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 2c4f7ac..1d79ab5 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -832,7 +832,6 @@ H5_DLL herr_t H5O_msg_lock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id); /* Object metadata flush/evict routines */ -H5_DLL herr_t H5O_flush_metadata(const H5O_loc_t *oloc, hid_t dxpl_id); H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id); H5_DLL herr_t H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id); diff --git a/src/H5SMcache.c b/src/H5SMcache.c index d4052ef..0a8921a 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -214,7 +214,8 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void H5_ATTR_UNUSED *udat /* Address of the index's heap */ H5F_addr_decode(f, &p, &(table->indexes[u].heap_addr)); - /* Compute the size of a list index for this SOHM index */ + /* Compute the size of a list index for this SOHM index */ + table->indexes[u].list_size = H5SM_LIST_SIZE(f, table->indexes[u].list_max); } /* end for */ /* Already decoded and compared stored checksum earlier, when reading */ |