summaryrefslogtreecommitdiffstats
path: root/src/H5FS.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2012-08-11 21:27:58 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2012-08-11 21:27:58 (GMT)
commitd20da589dd51cf3fe184bffce8851bd5d032e7f4 (patch)
tree7a04d4ec975064ba805fbc83ed56426ee1ac4469 /src/H5FS.c
parent3552beb08b10a9037691905b5dec644428a9ac35 (diff)
downloadhdf5-d20da589dd51cf3fe184bffce8851bd5d032e7f4.zip
hdf5-d20da589dd51cf3fe184bffce8851bd5d032e7f4.tar.gz
hdf5-d20da589dd51cf3fe184bffce8851bd5d032e7f4.tar.bz2
[svn-r22668] Description:
Have free space manager use temporary address space for storing the section info, until the file is flushed or closed. Tested on: Mac OSX/64 10.7.4 (amazon) w/debug, gcc 4.7.x, C++, FORTRAN & threadsafe (h5committest forthcoming)
Diffstat (limited to 'src/H5FS.c')
-rw-r--r--src/H5FS.c129
1 files changed, 101 insertions, 28 deletions
diff --git a/src/H5FS.c b/src/H5FS.c
index fc1285f..7c09beb 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -284,6 +284,50 @@ HDfprintf(stderr, "%s: Deleting free space manager, fs_addr = %a\n", FUNC, fs_ad
cache_udata.cls_init_udata = NULL;
cache_udata.addr = fs_addr;
+#ifdef H5FS_DEBUG
+{
+ unsigned fspace_status = 0; /* Free space section info's status in the metadata cache */
+
+ /* Sanity check */
+ HDassert(H5F_addr_defined(fs_addr));
+
+ /* Check the free space section info's status in the metadata cache */
+ if(H5AC_get_entry_status(f, fs_addr, &fspace_status) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space section info")
+
+ HDfprintf(stderr, "%s: fspace_status = %0x: ", FUNC, fspace_status);
+ if(fspace_status) {
+ hbool_t printed = FALSE;
+
+ if(fspace_status & H5AC_ES__IN_CACHE) {
+ HDfprintf(stderr, "H5AC_ES__IN_CACHE");
+ printed = TRUE;
+ } /* end if */
+ if(fspace_status & H5AC_ES__IS_DIRTY) {
+ HDfprintf(stderr, "%sH5AC_ES__IS_DIRTY", (printed ? " | " : ""));
+ printed = TRUE;
+ } /* end if */
+ if(fspace_status & H5AC_ES__IS_PROTECTED) {
+ HDfprintf(stderr, "%sH5AC_ES__IS_PROTECTED", (printed ? " | " : ""));
+ printed = TRUE;
+ } /* end if */
+ if(fspace_status & H5AC_ES__IS_PINNED) {
+ HDfprintf(stderr, "%sH5AC_ES__IS_PINNED", (printed ? " | " : ""));
+ printed = TRUE;
+ } /* end if */
+ if(fspace_status & H5AC_ES__IS_FLUSH_DEP_PARENT) {
+ HDfprintf(stderr, "%sH5AC_ES__IS_FLUSH_DEP_PARENT", (printed ? " | " : ""));
+ printed = TRUE;
+ } /* end if */
+ if(fspace_status & H5AC_ES__IS_FLUSH_DEP_CHILD) {
+ HDfprintf(stderr, "%sH5AC_ES__IS_FLUSH_DEP_CHILD", (printed ? " | " : ""));
+ printed = TRUE;
+ } /* end if */
+ } /* end if */
+ HDfprintf(stderr, "\n");
+}
+#endif /* H5FS_DEBUG */
+
/* Protect the free space header */
if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &cache_udata, H5AC_WRITE)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, FAIL, "unable to protect free space header")
@@ -324,9 +368,14 @@ HDfprintf(stderr, "%s: Done expunging free space section info from cache\n", FUN
#endif /* H5FS_DEBUG */
} /* end if */
else {
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Deleting free space section info from file\n", FUNC);
+#endif /* H5FS_DEBUG */
/* Release the space in the file */
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+ if(!H5F_IS_TMP_ADDR(f, fspace->sect_addr)) {
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+ } /* end if */
} /* end else */
} /* end if */
@@ -387,8 +436,14 @@ HDfprintf(stderr, "%s: Real sections to store in file\n", FUNC);
HDassert(fspace->sect_size > 0);
/* Allocate space for the section info in file */
- if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
- HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
+ if(H5F_USE_TMP_SPACE(f)) {
+ if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc_tmp(f, fspace->sect_size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
+ } /* end if */
+ else {
+ if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
+ } /* end if */
fspace->alloc_sect_size = (size_t)fspace->sect_size;
/* Mark free space header as dirty */
@@ -430,19 +485,9 @@ HDfprintf(stderr, "%s: Section info allocated though\n", FUNC);
HDfprintf(stderr, "%s: Section info is for file free space\n", FUNC);
#endif /* H5FS_DEBUG */
/* Try to shrink the file or absorb the section info into a block aggregator */
- if((status = H5MF_try_shrink(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size)) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for absorbing section info")
- else if(status == FALSE) {
- /* Section info can't "go away", but it's free. Allow
- * header to record it
- */
-#ifdef H5FS_DEBUG
-HDfprintf(stderr, "%s: Section info can't 'go away', header will own it\n", FUNC);
-#endif /* H5FS_DEBUG */
- } /* end if */
- else {
+ if(H5F_IS_TMP_ADDR(f, fspace->sect_addr)) {
#ifdef H5FS_DEBUG
-HDfprintf(stderr, "%s: Section info went 'go away'\n", FUNC);
+HDfprintf(stderr, "%s: Section info in temp. address space went 'go away'\n", FUNC);
#endif /* H5FS_DEBUG */
/* Reset section info in header */
fspace->sect_addr = HADDR_UNDEF;
@@ -451,6 +496,30 @@ HDfprintf(stderr, "%s: Section info went 'go away'\n", FUNC);
/* Mark free space header as dirty */
if(H5AC_mark_entry_dirty(fspace) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+ } /* end if */
+ else {
+ if((status = H5MF_try_shrink(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for absorbing section info")
+ else if(status == FALSE) {
+ /* Section info can't "go away", but it's free. Allow
+ * header to record it
+ */
+#ifdef H5FS_DEBUG
+ HDfprintf(stderr, "%s: Section info can't 'go away', header will own it\n", FUNC);
+#endif /* H5FS_DEBUG */
+ } /* end if */
+ else {
+#ifdef H5FS_DEBUG
+ HDfprintf(stderr, "%s: Section info went 'go away'\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Reset section info in header */
+ fspace->sect_addr = HADDR_UNDEF;
+ fspace->alloc_sect_size = 0;
+
+ /* Mark free space header as dirty */
+ if(H5AC_mark_entry_dirty(fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+ } /* end else */
} /* end else */
} /* end if */
else {
@@ -469,10 +538,12 @@ HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC);
HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
/* Free previous serialized sections disk space */
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections")
- } /* end if */
- } /* end else */
+ if(!H5F_IS_TMP_ADDR(f, old_sect_addr)) {
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections")
+ } /* end if */
+ } /* end else */
+ } /* end if */
/* Destroy section info */
if(H5FS_sinfo_dest(fspace->sinfo) < 0)
@@ -802,11 +873,11 @@ H5FS_alloc_sect(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id)
HDassert(fspace);
if(!H5F_addr_defined(fspace->sect_addr) && fspace->sinfo && fspace->serial_sect_count > 0) {
- /* Allocate space for section info from aggregator/vfd */
- /* (The original version called H5MF_alloc(), but that may cause sect_size to change again) */
- if(HADDR_UNDEF == (fspace->sect_addr = H5MF_aggr_vfd_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
- HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for section info")
-
+ /* Allocate space for section info from aggregator/vfd (or temp. address space) */
+ /* (The original version called H5MF_alloc(), but that may cause sect_size to change again) */
+ /* (This routine is only called during file close operations, so don't allocate from temp. address space) */
+ if(HADDR_UNDEF == (fspace->sect_addr = H5MF_aggr_vfd_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for section info")
fspace->alloc_sect_size = fspace->sect_size;
/* Mark free-space header as dirty */
@@ -882,8 +953,10 @@ H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id)
fspace->alloc_sect_size = 0;
/* Free space for the free-space manager section info */
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, saved_addr, saved_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+ if(!H5F_IS_TMP_ADDR(f, saved_addr)) {
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, saved_addr, saved_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+ } /* end if */
/* Mark free-space manager header as dirty */
if(H5FS_dirty(fspace) < 0)
@@ -1120,7 +1193,7 @@ herr_t
H5FS_assert(const H5FS_t *fspace)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
-#ifndef QAK
+#ifdef QAK
HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", "H5FS_assert", fspace->tot_sect_count);
#endif /* QAK */