summaryrefslogtreecommitdiffstats
path: root/src/H5MF.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5MF.c')
-rw-r--r--src/H5MF.c150
1 files changed, 129 insertions, 21 deletions
diff --git a/src/H5MF.c b/src/H5MF.c
index e708ab8..4b0668f 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -487,6 +487,7 @@ HDfprintf(stderr, "%s: Check 1.6, freeing node\n", FUNC);
udata.dxpl_id = dxpl_id;
udata.alloc_type = alloc_type;
udata.allow_sect_absorb = TRUE;
+ udata.allow_eoa_shrink_only = FALSE;
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 1.7, re-adding node, node->sect_info.size = %Hu\n", FUNC, node->sect_info.size);
@@ -692,6 +693,7 @@ HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, a
udata.dxpl_id = dxpl_id;
udata.alloc_type = alloc_type;
udata.allow_sect_absorb = TRUE;
+ udata.allow_eoa_shrink_only = FALSE;
/* If size of section freed is larger than threshold, add it to the free space manager */
if(size >= f->shared->fs_threshold) {
@@ -823,6 +825,11 @@ H5MF_sects_dump(f, dxpl_id, stderr);
* Programmer: Quincey Koziol
* Monday, October 6, 2003
*
+ * Modifications:
+ * Vailin Choi; July 2012
+ * As the default free-list mapping is changed to H5FD_FLMAP_DICHOTOMY,
+ * checks are added to account for the last section of each free-space manager
+ * and the remaining space in the two aggregators are at EOF.
*-------------------------------------------------------------------------
*/
herr_t
@@ -836,6 +843,8 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id, hsize_t *tot_space, hsize_t *meta_si
hsize_t tot_fs_size = 0; /* Amount of all free space managed */
hsize_t tot_meta_size = 0; /* Amount of metadata for free space managers */
H5FD_mem_t type; /* Memory type for iteration */
+ H5FD_mem_t fs_started[H5FD_MEM_NTYPES]; /* Indicate whether the free-space manager has been started */
+ hbool_t eoa_shrank; /* Whether an EOA shrink occurs */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -859,14 +868,15 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id, hsize_t *tot_space, hsize_t *meta_si
/* Iterate over all the free space types that have managers and get each free list's space */
for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
- hbool_t fs_started = FALSE;
+
+ fs_started[type] = FALSE;
/* Check if the free space for the file has been initialized */
if(!f->shared->fs_man[type] && H5F_addr_defined(f->shared->fs_addr[type])) {
if(H5MF_alloc_open(f, dxpl_id, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
HDassert(f->shared->fs_man[type]);
- fs_started = TRUE;
+ fs_started[type] = TRUE;
} /* end if */
/* Check if there's free space of this type */
@@ -884,32 +894,54 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id, hsize_t *tot_space, hsize_t *meta_si
tot_fs_size += type_fs_size;
tot_meta_size += type_meta_size;
} /* end if */
+ } /* end for */
- /* Close the free space manager, if we opened it here */
- if(fs_started)
+ /* Iterate until no more EOA shrink occurs */
+ do {
+ eoa_shrank = FALSE;
+
+ /* Check the last section of each free-space manager */
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+ haddr_t sect_addr = HADDR_UNDEF;
+ hsize_t sect_size = 0;
+
+ if(f->shared->fs_man[type]) {
+ if(H5FS_sect_query_last_sect(f->shared->fs_man[type], &sect_addr, &sect_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query last section on merge list")
+
+ /* Deduct space from previous accumulation if the section is at EOA */
+ if(H5F_addr_eq(sect_addr + sect_size, eoa)) {
+ eoa = sect_addr;
+ eoa_shrank = TRUE;
+ tot_fs_size -= sect_size;
+ } /* end if */
+ } /* end if */
+ } /* end for */
+
+ /* Check the metadata and raw data aggregators */
+ if(ma_size > 0 && H5F_addr_eq(ma_addr + ma_size, eoa)) {
+ eoa = ma_addr;
+ eoa_shrank = TRUE;
+ ma_size = 0;
+ } /* end if */
+ if(sda_size > 0 && H5F_addr_eq(sda_addr + sda_size, eoa)) {
+ eoa = sda_addr;
+ eoa_shrank = TRUE;
+ sda_size = 0;
+ } /* end if */
+ } while(eoa_shrank);
+
+ /* Close the free-space managers if they were opened earlier in this routine */
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+ if(fs_started[type])
if(H5MF_alloc_close(f, dxpl_id, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't close file free space")
} /* end for */
- /* Check for aggregating metadata allocations */
- if(ma_size > 0) {
- /* Add in the reserved space for metadata to the available free space */
- /* (if it's not at the tail of the file) */
- if(H5F_addr_ne(ma_addr + ma_size, eoa))
- tot_fs_size += ma_size;
- } /* end if */
-
- /* Check for aggregating small data allocations */
- if(sda_size > 0) {
- /* Add in the reserved space for metadata to the available free space */
- /* (if it's not at the tail of the file) */
- if(H5F_addr_ne(sda_addr + sda_size, eoa))
- tot_fs_size += sda_size;
- } /* end if */
-
/* Set the value(s) to return */
+ /* (The metadata & small data aggregators count as free space now, since they aren't at EOA) */
if(tot_space)
- *tot_space = tot_fs_size;
+ *tot_space = tot_fs_size + ma_size + sda_size;
if(meta_size)
*meta_size = tot_meta_size;
@@ -961,6 +993,7 @@ HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUN
udata.dxpl_id = dxpl_id;
udata.alloc_type = alloc_type;
udata.allow_sect_absorb = FALSE; /* Force section to be absorbed into aggregator */
+ udata.allow_eoa_shrink_only = FALSE;
/* Call the "can shrink" callback for the section */
if((ret_value = H5MF_sect_simple_can_shrink((const H5FS_section_info_t *)node, &udata)) < 0)
@@ -984,6 +1017,66 @@ HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
/*-------------------------------------------------------------------------
+ * Function: H5MF_close_shrink_eoa
+ *
+ * Purpose: Shrink the EOA while closing
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, July 7, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_close_shrink_eoa(H5F_t *f, hid_t dxpl_id)
+{
+ H5FD_mem_t type; /* Memory type for iteration */
+ hbool_t eoa_shrank; /* Whether an EOA shrink occurs */
+ htri_t status; /* Status value */
+ H5MF_sect_ud_t udata; /* User data for callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* check args */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Construct user data for callbacks */
+ udata.f = f;
+ udata.dxpl_id = dxpl_id;
+ udata.allow_sect_absorb = FALSE;
+ udata.allow_eoa_shrink_only = TRUE;
+
+ /* Iterate until no more EOA shrinking occurs */
+ do {
+ eoa_shrank = FALSE;
+
+ /* Check the last section of each free-space manager */
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+ if(f->shared->fs_man[type]) {
+ udata.alloc_type = type;
+ if((status = H5FS_sect_try_shrink_eoa(f, dxpl_id, f->shared->fs_man[type], &udata)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa")
+ else if(status > 0)
+ eoa_shrank = TRUE;
+ } /* end if */
+ } /* end for */
+
+ /* check the two aggregators */
+ if((status = H5MF_aggrs_try_shrink_eoa(f, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa")
+ else if(status > 0)
+ eoa_shrank = TRUE;
+ } while(eoa_shrank);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_close_shrink_eoa() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5MF_close
*
* Purpose: Close the free space tracker(s) for a file
@@ -993,6 +1086,12 @@ HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
* Programmer: Quincey Koziol
* Tuesday, January 22, 2008
*
+ * Modifications:
+ * Vailin Choi; July 2012
+ * As the default free-list mapping is changed to H5FD_FLMAP_DICHOTOMY,
+ * modifications are needed to shrink EOA if the last section of each free-space manager
+ * and the remaining space in the two aggregators are at EOA.
+
*-------------------------------------------------------------------------
*/
herr_t
@@ -1017,6 +1116,10 @@ HDfprintf(stderr, "%s: Entering\n", FUNC);
if(H5MF_free_aggrs(f, dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators")
+ /* Trying shrinking the EOA for the file */
+ if(H5MF_close_shrink_eoa(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
+
/* Making free-space managers persistent for superblock version >= 2 */
if(f->shared->sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2
&& f->shared->fs_strategy == H5F_FILE_SPACE_ALL_PERSIST) {
@@ -1164,6 +1267,11 @@ HDfprintf(stderr, "%s: Before deleting free space manager\n", FUNC);
if(H5MF_free_aggrs(f, dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators")
+ /* Trying shrinking the EOA for the file */
+ /* (in case any free space is now at the EOA) */
+ if(H5MF_close_shrink_eoa(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
+
done:
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", FUNC);