From 2ab1d8cc0c91d691e7b0778d49d1c596c9a21d16 Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Mon, 13 Aug 2012 19:33:19 -0500 Subject: [svn-r22677] Changes needed to make the default free-list mapping from H5FD_FLMAP_SINGLE to H5FD_FLMAP_DICHOTOMY. Also changed H5O_copy_search_comm_dt_check() to use H5O_obj_class() to get object type instead of H5O_get_info(...TRUE...) saving time in traversing metadata. --- src/H5FDcore.c | 2 +- src/H5FDdirect.c | 2 +- src/H5FDfamily.c | 2 +- src/H5FDlog.c | 2 +- src/H5FDmpio.c | 2 +- src/H5FDmpiposix.c | 2 +- src/H5FDsec2.c | 2 +- src/H5FDstdio.c | 2 +- src/H5FSprivate.h | 2 + src/H5FSsection.c | 111 +++++++++++++++ src/H5MF.c | 151 +++++++++++++++++--- src/H5MFaggr.c | 161 +++++++++++++++++++-- src/H5MFpkg.h | 1 + src/H5MFprivate.h | 1 + src/H5MFsection.c | 4 + src/H5Ocopy.c | 16 ++- test/mf.c | 401 +++++++++++++++++++++++++++++++++++++---------------- test/tfile.c | 12 +- 18 files changed, 702 insertions(+), 174 deletions(-) diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 5080dfc..094011c 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -182,7 +182,7 @@ static const H5FD_class_t H5FD_core_g = { H5FD_core_truncate, /*truncate */ NULL, /*lock */ NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ + H5FD_FLMAP_DICHOTOMY /*fl_map */ }; diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index 2c01b47..941fb74 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -203,7 +203,7 @@ static const H5FD_class_t H5FD_direct_g = { H5FD_direct_truncate, /*truncate */ NULL, /*lock */ NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ + H5FD_FLMAP_DICHOTOMY /*fl_map */ }; /* Declare a free list to manage the H5FD_direct_t struct */ diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 736efb8..68061a6 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -146,7 +146,7 @@ static const H5FD_class_t H5FD_family_g = { H5FD_family_truncate, /*truncate */ NULL, /*lock */ NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ + H5FD_FLMAP_DICHOTOMY /*fl_map */ }; diff --git a/src/H5FDlog.c b/src/H5FDlog.c index bd53658..9d318dd 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -231,7 +231,7 @@ static const H5FD_class_t H5FD_log_g = { H5FD_log_truncate, /*truncate */ NULL, /*lock */ NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ + H5FD_FLMAP_DICHOTOMY /*fl_map */ }; /* Declare a free list to manage the H5FD_log_t struct */ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 058324e..fe73328 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -125,7 +125,7 @@ static const H5FD_class_mpi_t H5FD_mpio_g = { H5FD_mpio_truncate, /*truncate */ NULL, /*lock */ NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ + H5FD_FLMAP_DICHOTOMY /*fl_map */ }, /* End of superclass information */ H5FD_mpio_mpi_rank, /*get_rank */ H5FD_mpio_mpi_size, /*get_size */ diff --git a/src/H5FDmpiposix.c b/src/H5FDmpiposix.c index 74eb566..8f8d6d7 100644 --- a/src/H5FDmpiposix.c +++ b/src/H5FDmpiposix.c @@ -234,7 +234,7 @@ static const H5FD_class_mpi_t H5FD_mpiposix_g = { H5FD_mpiposix_truncate, /*truncate */ NULL, /*lock */ NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ + H5FD_FLMAP_DICHOTOMY /*fl_map */ }, /* End of superclass information */ H5FD_mpiposix_mpi_rank, /*get_rank */ H5FD_mpiposix_mpi_size, /*get_size */ diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 868d4a4..877fae6 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -189,7 +189,7 @@ static const H5FD_class_t H5FD_sec2_g = { H5FD_sec2_truncate, /*truncate */ NULL, /*lock */ NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ + H5FD_FLMAP_DICHOTOMY /*fl_map */ }; /* Declare a free list to manage the H5FD_sec2_t struct */ diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index ca0bb6d..68c952f 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -224,7 +224,7 @@ static const H5FD_class_t H5FD_stdio_g = { H5FD_stdio_truncate, /* truncate */ NULL, /* lock */ NULL, /* unlock */ - H5FD_FLMAP_SINGLE /* fl_map */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }; diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h index 5fb8361..cbcb36a 100644 --- a/src/H5FSprivate.h +++ b/src/H5FSprivate.h @@ -195,6 +195,8 @@ H5_DLL herr_t H5FS_sect_stats(const H5FS_t *fspace, hsize_t *tot_space, hsize_t *nsects); H5_DLL herr_t H5FS_sect_change_class(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned new_class); +H5_DLL htri_t H5FS_sect_try_shrink_eoa(const H5F_t *f, hid_t dxpl_id, const H5FS_t *fspace, void *op_data); +H5_DLL herr_t H5FS_sect_query_last_sect(const H5FS_t *fspace, haddr_t *sect_addr, hsize_t *sect_size); /* Statistics routine */ H5_DLL herr_t H5FS_stat_info(const H5F_t *f, const H5FS_t *frsp, H5FS_stat_t *stats); diff --git a/src/H5FSsection.c b/src/H5FSsection.c index 8959d7c..0aa007e 100644 --- a/src/H5FSsection.c +++ b/src/H5FSsection.c @@ -2309,3 +2309,114 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a, sect->type = %u\n", "H } /* end H5FS_sect_assert() */ #endif /* H5FS_DEBUG_ASSERT */ + +/*------------------------------------------------------------------------- + * Function: H5FS_sect_try_shrink_eoa + * + * Purpose: To shrink the last section on the merge list if the section + * is at EOF. + * + * Return: Success: non-negative (TRUE/FALSE) + * Failure: negative + * + * Programmer: Vailin Choi + * + *------------------------------------------------------------------------- + */ +htri_t +H5FS_sect_try_shrink_eoa(const H5F_t *f, hid_t dxpl_id, const H5FS_t *fspace, void *op_data) +{ + hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */ + hbool_t section_removed = FALSE; /* Whether a section was removed */ + htri_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check arguments. */ + HDassert(fspace); + + if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_WRITE) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info") + sinfo_valid = TRUE; + + if(fspace->sinfo && fspace->sinfo->merge_list) { + H5SL_node_t *last_node; /* Last node in merge list */ + + /* Check for last node in the merge list */ + if(NULL != (last_node = H5SL_last(fspace->sinfo->merge_list))) { + H5FS_section_info_t *tmp_sect; /* Temporary free space section */ + H5FS_section_class_t *tmp_sect_cls; /* Temporary section's class */ + + /* Get the pointer to the last section, from the last node */ + tmp_sect = (H5FS_section_info_t *)H5SL_item(last_node); + HDassert(tmp_sect); + tmp_sect_cls = &fspace->sect_cls[tmp_sect->type]; + if(tmp_sect_cls->can_shrink) { + /* Check if the section can be shrunk away */ + if((ret_value = (*tmp_sect_cls->can_shrink)(tmp_sect, op_data)) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTSHRINK, FAIL, "can't check for shrinking container") + if(ret_value > 0) { + HDassert(tmp_sect_cls->shrink); + + /* Remove section from free space manager */ + if(H5FS_sect_remove_real(fspace, tmp_sect) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures") + section_removed = TRUE; + + /* Shrink away section */ + if((*tmp_sect_cls->shrink)(&tmp_sect, op_data) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't shrink free space container") + } /* end if */ + } /* end if */ + } /* end if */ + } /* end if */ + +done: + /* Release the section info */ + if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, section_removed) < 0) + HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5FS_sect_try_shrink_eoa() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_sect_query_last_sect + * + * Purpose: Retrieve info about the last section on the merge list + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_sect_query_last_sect(const H5FS_t *fspace, haddr_t *sect_addr, hsize_t *sect_size) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Check arguments. */ + HDassert(fspace); + + if(fspace->sinfo && fspace->sinfo->merge_list) { + H5SL_node_t *last_node; /* Last node in merge list */ + + /* Check for last node in the merge list */ + if(NULL != (last_node = H5SL_last(fspace->sinfo->merge_list))) { + H5FS_section_info_t *tmp_sect; /* Temporary free space section */ + + /* Get the pointer to the last section, from the last node */ + tmp_sect = (H5FS_section_info_t *)H5SL_item(last_node); + HDassert(tmp_sect); + if(sect_addr) + *sect_addr = tmp_sect->addr; + if(sect_size) + *sect_size = tmp_sect->size; + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5FS_sect_query_last_sect() */ + diff --git a/src/H5MF.c b/src/H5MF.c index e154889..57002c8 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -480,6 +480,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); @@ -680,6 +681,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; /* Add to the free space for the file */ #ifdef H5MF_ALLOC_DEBUG_MORE @@ -796,6 +798,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 @@ -809,6 +816,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) @@ -832,14 +841,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 */ @@ -857,32 +867,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 */ + + /* 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], §_addr, §_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 */ - /* Close the free space manager, if we opened it here */ - if(fs_started) + /* 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; @@ -934,6 +966,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) @@ -957,6 +990,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 @@ -966,6 +1059,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 @@ -983,13 +1082,16 @@ HDfprintf(stderr, "%s: Entering\n", FUNC); HDassert(f); HDassert(f->shared); HDassert(f->shared->lf); - HDassert(f->shared->sblock); /* Free the space in aggregators */ /* (for space not at EOF, it may be put into free space managers) */ 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") + /* 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)) { #ifdef H5MF_ALLOC_DEBUG_MORE @@ -1045,6 +1147,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); diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c index ad91e45..6a799da 100644 --- a/src/H5MFaggr.c +++ b/src/H5MFaggr.c @@ -57,6 +57,8 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5MF_aggr_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, + H5F_blk_aggr_t *aggr); /*********************/ @@ -231,15 +233,14 @@ HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_siz if(H5F_addr_gt((eoa + size), f->shared->tmp_addr)) HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space") + /* Release "other" aggregator, if it exists, is at the end of the allocated space, + * has allocated more than one block and the unallocated space is greater than its + * allocation block size. + */ if ((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) && - ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) { - - if(H5FD_free(f->shared->lf, dxpl_id, other_alloc_type, f, other_aggr->addr, other_aggr->size) < 0) + (other_aggr->tot_size > other_aggr->size) && ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) { + if(H5MF_aggr_free(f, dxpl_id, other_alloc_type, other_aggr) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block") - - other_aggr->addr = 0; - other_aggr->tot_size = 0; - other_aggr->size = 0; } /* end if */ /* Allocate space from the VFD (i.e. at the end of the file) */ @@ -275,14 +276,14 @@ HDfprintf(stderr, "%s: Allocating block\n", FUNC); if(H5F_addr_gt((eoa + aggr->alloc_size), f->shared->tmp_addr)) HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space") + /* Release "other" aggregator, if it exists, is at the end of the allocated space, + * has allocated more than one block and the unallocated space is greater than its + * allocation block size. + */ if((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) && - ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) { - - if(H5FD_free(f->shared->lf, dxpl_id, other_alloc_type, f, other_aggr->addr, other_aggr->size) < 0) + (other_aggr->tot_size > other_aggr->size) && ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) { + if(H5MF_aggr_free(f, dxpl_id, other_alloc_type, other_aggr) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block") - other_aggr->addr = 0; - other_aggr->tot_size = 0; - other_aggr->size = 0; } /* end if */ /* Allocate space from the VFD (i.e. at the end of the file) */ @@ -633,8 +634,10 @@ H5MF_aggr_query(const H5F_t *f, const H5F_blk_aggr_t *aggr, haddr_t *addr, /* Check if this aggregator is active */ if(f->shared->feature_flags & aggr->feature_flag) { - *addr = aggr->addr; - *size = aggr->size; + if(addr) + *addr = aggr->addr; + if(size) + *size = aggr->size; } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) @@ -766,3 +769,131 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5MF_free_aggrs() */ + +/*------------------------------------------------------------------------- + * Function: H5MF_aggr_can_shrink_eoa + * + * Purpose: Check if the remaining space in the aggregator is at EOA + * + * Return: Success: non-negative (TRUE/FALSE) + * Failure: negative + * + * Programmer: Vailin Choi + * + *------------------------------------------------------------------------- + */ +static htri_t +H5MF_aggr_can_shrink_eoa(H5F_t *f, H5FD_mem_t type, H5F_blk_aggr_t *aggr) +{ + haddr_t eoa = HADDR_UNDEF; /* EOA for the file */ + htri_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(f); + HDassert(aggr); + HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA); + + /* Get the EOA for the file */ + if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, type))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "Unable to get eoa") + + /* Check if the aggregator is at EOA */ + if(aggr->size > 0 && H5F_addr_defined(aggr->addr)) + ret_value = H5F_addr_eq(eoa, aggr->addr + aggr->size); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5MF_aggr_can_shrink_eoa() */ + + +/*------------------------------------------------------------------------- + * Function: H5MF_aggr_free + * + * Purpose: Free the aggregator's space in the file. + * + * Note: Does _not_ put the space on a free list + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi + * + *------------------------------------------------------------------------- + */ +static herr_t +H5MF_aggr_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, H5F_blk_aggr_t *aggr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(f); + HDassert(f->shared->lf); + HDassert(aggr); + HDassert(H5F_addr_defined(aggr->addr)); + HDassert(aggr->size > 0); + HDassert(H5F_INTENT(f) & H5F_ACC_RDWR); + HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA); + HDassert(f->shared->feature_flags & aggr->feature_flag); + + /* Free the remaining space at EOA in the aggregator */ + if(H5FD_free(f->shared->lf, dxpl_id, type, f, aggr->addr, aggr->size) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't free aggregation block") + + /* Reset the aggregator */ + aggr->tot_size = 0; + aggr->addr = HADDR_UNDEF; + aggr->size = 0; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5MF_aggr_free() */ + + +/*------------------------------------------------------------------------- + * Function: H5MF_aggrs_try_shrink_eoa + * + * Purpose: Check the metadata & small block aggregators to see if + * EOA shrink is possible; if so, shrink each aggregator + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi + * + *------------------------------------------------------------------------- + */ +htri_t +H5MF_aggrs_try_shrink_eoa(H5F_t *f, hid_t dxpl_id) +{ + htri_t ma_status; /* Whether the metadata aggregator can shrink the EOA */ + htri_t sda_status; /* Whether the small data aggregator can shrink the EOA */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(f); + HDassert(f->shared); + + if((ma_status = H5MF_aggr_can_shrink_eoa(f, H5FD_MEM_DEFAULT, &(f->shared->meta_aggr))) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query metadata aggregator stats") + if(ma_status > 0) + if(H5MF_aggr_free(f, dxpl_id, H5FD_MEM_DEFAULT, &(f->shared->meta_aggr)) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa") + + if((sda_status = H5MF_aggr_can_shrink_eoa(f, H5FD_MEM_DRAW, &(f->shared->sdata_aggr))) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query small data aggregator stats") + if(sda_status > 0) + if(H5MF_aggr_free(f, dxpl_id, H5FD_MEM_DRAW, &(f->shared->sdata_aggr)) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa") + + ret_value = (ma_status || sda_status); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MF_aggrs_try_shrink_eoa() */ + diff --git a/src/H5MFpkg.h b/src/H5MFpkg.h index 25785ae..2071a0a 100644 --- a/src/H5MFpkg.h +++ b/src/H5MFpkg.h @@ -122,6 +122,7 @@ typedef struct H5MF_sect_ud_t { hid_t dxpl_id; /* DXPL for VFD operations */ H5FD_mem_t alloc_type; /* Type of memory being allocated */ hbool_t allow_sect_absorb; /* Whether sections are allowed to absorb a block aggregator */ + hbool_t allow_eoa_shrink_only; /* Whether shrinking eoa is allowed only for the section */ /* Up */ H5MF_shrink_type_t shrink; /* Type of shrink operation to perform */ diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 3f2a427..97c7aa3 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -79,6 +79,7 @@ H5_DLL haddr_t H5MF_alloc_tmp(H5F_t *f, hsize_t size); /* 'block aggregator' routines */ H5_DLL herr_t H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id); +H5_DLL htri_t H5MF_aggrs_try_shrink_eoa(H5F_t *f, hid_t dxpl_id); /* Debugging routines */ #ifdef H5MF_DEBUGGING diff --git a/src/H5MFsection.c b/src/H5MFsection.c index 89b2219..0572def 100644 --- a/src/H5MFsection.c +++ b/src/H5MFsection.c @@ -328,6 +328,10 @@ HDfprintf(stderr, "%s: section {%a, %Hu}, shrinks file, eoa = %a\n", FUNC, sect- HGOTO_DONE(TRUE) } /* end if */ else { + /* Shrinking can't occur if the 'eoa_shrink_only' flag is set and we're not shrinking the EOA */ + if(udata->allow_eoa_shrink_only) + HGOTO_DONE(FALSE) + /* Check if this section is allowed to merge with metadata aggregation block */ if(udata->f->shared->fs_aggr_merge[udata->alloc_type] & H5F_FS_MERGE_METADATA) { htri_t status; /* Status from aggregator adjoin */ diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index bc71948..9dd253d 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -1555,6 +1555,10 @@ done: * Programmer: Neil Fortner * Nov 3 2011 * + * Modifications: + * Vailin Choi; August 2012 + * Use H5O_obj_class to get object type instead of + * H5O_get_info(...TRUE....) saving time in traversing metadata. *------------------------------------------------------------------------- */ static herr_t @@ -1564,8 +1568,8 @@ H5O_copy_search_comm_dt_check(H5O_loc_t *obj_oloc, H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */ haddr_t *addr = NULL; /* Destination address */ hbool_t obj_inserted = FALSE; /* Object inserted into skip list */ - H5O_info_t oinfo; /* Object info */ H5A_attr_iter_op_t attr_op; /* Attribute iteration operator */ + const H5O_obj_class_t *obj_class = NULL; /* Type of object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1576,13 +1580,13 @@ H5O_copy_search_comm_dt_check(H5O_loc_t *obj_oloc, HDassert(udata->dst_dt_list); HDassert(udata->dst_root_loc); - /* Get the object's info */ - if(H5O_get_info(obj_oloc, udata->dxpl_id, TRUE, &oinfo) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object info") + /* Get pointer to object class for this object */ + if((obj_class = H5O_obj_class(obj_oloc, udata->dxpl_id)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") /* Check if the object is a datatype, a dataset using a committed * datatype, or contains an attribute using a committed datatype */ - if(oinfo.type == H5O_TYPE_NAMED_DATATYPE) { + if(obj_class->type == H5O_TYPE_NAMED_DATATYPE) { /* Allocate key */ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") @@ -1607,7 +1611,7 @@ H5O_copy_search_comm_dt_check(H5O_loc_t *obj_oloc, obj_inserted = TRUE; } /* end if */ } /* end if */ - else if(oinfo.type == H5O_TYPE_DATASET) { + else if(obj_class->type == H5O_TYPE_DATASET) { /* Allocate key */ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") diff --git a/test/mf.c b/test/mf.c index e3c3082..38d8378 100644 --- a/test/mf.c +++ b/test/mf.c @@ -108,12 +108,19 @@ static unsigned test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t /* * Verify statistics for the free-space manager + * + * Modifications: + * Vailin Choi; July 2012 + * To ensure "f" and "frsp" are valid pointers */ static int check_stats(const H5F_t *f, const H5FS_t *frsp, frspace_state_t *state) { H5FS_stat_t frspace_stats; /* Statistics about the heap */ + HDassert(f); + HDassert(frsp); + /* Get statistics for free-space and verify they are correct */ if(H5FS_stat_info(f, frsp, &frspace_stats) < 0) FAIL_STACK_ERROR @@ -1052,6 +1059,10 @@ error: * The block is allocated from file allocation * Deallocate the block which will be returned to free-space manager * (the space is shrunk and freed since it is at end of file) + * + * Modifications: + * Vailin Choi; July 2012 + * Initialize the new field "allow_eoa_shrink_only" for user data. */ static unsigned test_mf_fs_alloc_free(hid_t fapl) @@ -1117,6 +1128,7 @@ test_mf_fs_alloc_free(hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space manager */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -1203,6 +1215,7 @@ test_mf_fs_alloc_free(hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space manager */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -1287,6 +1300,7 @@ test_mf_fs_alloc_free(hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space manager */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -1402,6 +1416,10 @@ error: * Try to extend the allocated block by 50 from the free-space_manager: * Fail: section A does not adjoin section B (70+20 != address of section B) even though * the requested-size (50) equal to size of section B (50) + * + * Modifications: + * Vailin Choi; July 2012 + * Initialize the new field "allow_eoa_shrink_only" for user data. */ static unsigned test_mf_fs_extend(hid_t fapl) @@ -1468,6 +1486,7 @@ test_mf_fs_extend(hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space manager */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -1585,6 +1604,7 @@ test_mf_fs_extend(hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -1697,6 +1717,7 @@ test_mf_fs_extend(hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -1809,6 +1830,7 @@ test_mf_fs_extend(hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A of size=20 to free-space */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -1938,6 +1960,10 @@ error: * which will absorb meta_aggr to the section: * section size + remaining size of aggregator is > aggr->alloc_size, * section is allowed to absorb an aggregator (allow_sect_absorb is true) + * + * Modifications: + * Vailin Choi; July 2012 + * Initialize the new field "allow_eoa_shrink_only" for user data. */ static unsigned test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl) @@ -2001,6 +2027,7 @@ test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* When adding, meta_aggr is absorbed onto the beginning of the section */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -2073,6 +2100,7 @@ test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* When adding, meta_aggr is absorbed onto the end of the section */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -3114,7 +3142,7 @@ test_mf_aggr_alloc7(const char *env_h5_drvr, hid_t fapl) /* sdata_aggr info is reset to 0 */ H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); - if (sdata_addr != 0) TEST_ERROR + if (sdata_addr != HADDR_UNDEF) TEST_ERROR if (sdata_size != 0) TEST_ERROR /* Verify that meta_aggr's unused space of 1968 is freed to free-space */ @@ -3462,15 +3490,18 @@ error: * * Test 2: H5MF_alloc() block A from meta_aggr * H5MF_alloc() block B from sdata_aggr - * H5MF_try_shrink() block B should merge it onto the end of meta_aggr - * because H5F_FS_MERGE_METADATA|H5F_FS_MERGE_RAWDATA is on for - * sec2 driver's FLMAP_SINGLE + * H5MF_try_shrink() block B should merge it back to the end of sdata_aggr + * because sec2 driver is FLMAP_DICHOTOMY by default * * Test 3: H5MF_alloc() block A from meta_aggr * H5MF_alloc() block B from meta_aggr * H5MF_alloc() block C from meta_aggr * H5MF_try_shrink() block B should fail since it does not adjoin the * beginning nor the end of meta_aggr + * + * Modifications: + * Vailin Choi; July 2012 + * Changes due to the switch to H5FD_FLMAP_DICHOTOMY */ static unsigned test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl) @@ -3482,7 +3513,7 @@ test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl) H5FD_mem_t type, stype; haddr_t addr1, addr2, addr3, saddr1; haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; - haddr_t sdata_addr=HADDR_UNDEF, new_sdata_addr=HADDR_UNDEF; + haddr_t new_sdata_addr=HADDR_UNDEF; hsize_t ma_size=0, new_ma_size=0; hsize_t sdata_size=0, new_sdata_size=0; hbool_t contig_addr_vfd; /* Whether VFD used has a contigous address space */ @@ -3574,20 +3605,20 @@ test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl) stype = H5FD_MEM_DRAW; saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); - H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), NULL, &sdata_size); /* should succeed */ if(H5MF_try_shrink(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE50) <= 0) TEST_ERROR H5MF_aggr_query(f, &(f->shared->sdata_aggr), &new_sdata_addr, &new_sdata_size); - if (new_sdata_addr != sdata_addr) TEST_ERROR - if (new_sdata_size != sdata_size) TEST_ERROR + if (new_sdata_addr != saddr1) TEST_ERROR + if (new_sdata_size != sdata_size + TEST_BLOCK_SIZE50) TEST_ERROR /* meta_aggr info should be updated because the block is absorbed into the meta_aggr */ H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); if (new_ma_addr != ma_addr) TEST_ERROR - if (new_ma_size != (ma_size+TEST_BLOCK_SIZE50)) TEST_ERROR + if (new_ma_size != (ma_size)) TEST_ERROR H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); @@ -3985,6 +4016,10 @@ error: * Allocate a block of size=40 * The free-space manager is unable to fulfill the request * The block is allocated from file allocation and should be aligned + * + * Modifications: + * Vailin Choi; July 2012 + * Initialize the new field "allow_eoa_shrink_only" for user data. */ static unsigned test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) @@ -4044,6 +4079,7 @@ test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space manager */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -4113,6 +4149,7 @@ test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space manager */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -4202,6 +4239,7 @@ test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; udata.alloc_type = type; udata.allow_sect_absorb = TRUE; + udata.allow_eoa_shrink_only = FALSE; /* Add section A to free-space manager */ if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) @@ -4583,8 +4621,7 @@ error: * request-size < aggr->alloc_size * fragment size > (aggr->alloc_size - request-size) * Result: - * A block of aggr->alloc_size + (fragment size - (aggr->alloc_size - request-size)) - * is extended from file allocation for the aggregator + * A block of (fragment size + request-size) is extended from file allocation for the aggregator * The second block of 50 is allocated from the aggregator and should be aligned * Fragment from alignment of aggregator allocation is freed to free-space:[4126, 4066] * There is space of 2018 left in meta_aggr @@ -4609,12 +4646,14 @@ error: * Result: * A block of meta_aggr->alloc_size is allocated from file allocation for the aggregator * Fragment from alignment of file allocation is freed to free-space:[14336, 2048] - * Since this fragment adjoins sdata_aggr and fulfills "absorb" condition, - * the space left in sdata_aggr is absorbed into the fragment and freed to free-space: [12318, 2018] - * other_aggr is reset to 0 + * other_aggr is [12318, 2018] * The third block of 80 is allocated from the aggregator and should be aligned * There is space of 1968 left in meta_aggr * EOA is at 18432 + * + * Modifications: + * Vailin Choi; July 2012 + * Changes due to the switch to H5FD_FLMAP_DICHOTOMY */ static unsigned test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) @@ -4625,7 +4664,7 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) h5_stat_size_t file_size; /* File size */ H5FD_mem_t type, stype; haddr_t addr1, addr2, addr3, saddr1; - frspace_state_t state; + frspace_state_t state[H5FD_MEM_NTYPES]; haddr_t ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; hsize_t ma_size=0, sdata_size=0, mis_align=0; hsize_t alignment=0, tmp=0; @@ -4678,11 +4717,11 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) if (addr1 % alignment) TEST_ERROR /* fragment for alignment of block 30 is freed to free-space */ - HDmemset(&state, 0, sizeof(frspace_state_t)); + HDmemset(&state, 0, sizeof(frspace_state_t) * H5FD_MEM_NTYPES); if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); @@ -4702,9 +4741,9 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 50 is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); @@ -4735,9 +4774,9 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 30 for sdata_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[stype].tot_space += mis_align; + state[stype].tot_sect_count += 1; + state[stype].serial_sect_count += 1; } /* Verify that the allocated block is aligned */ @@ -4754,12 +4793,13 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * For alignment = 1024, alloc_size = 2048: * fragment for unused space in meta_aggr is freed to free-space * For alignment = 4096, alloc_size = 2048: - * fragment from alignment of file allocation absorbs sdata_aggr's remaining space + * fragment from alignment of ma_addr is freed + * block 30 is allocated from ma_addr */ mis_align = 0; if ((alignment == TEST_ALIGN1024) && (tmp = (ma_addr % alignment))) mis_align = alignment - tmp; - else if ((alignment == TEST_ALIGN4096) && (tmp = (sdata_addr % alignment))) + else if ((alignment == TEST_ALIGN4096) && (tmp = ((sdata_addr + sdata_size) % alignment))) mis_align = alignment - tmp; /* Allocate a block of 80 from meta_aggr */ @@ -4770,9 +4810,9 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 80 is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); @@ -4781,8 +4821,15 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) TEST_ERROR /* Verify total size of free space after all the allocations */ - if(check_stats(f, f->shared->fs_man[type], &state)) - TEST_ERROR + if(f->shared->fs_man[type]) { + if(check_stats(f, f->shared->fs_man[type], &(state[type]))) + TEST_ERROR + } + + if(f->shared->fs_man[stype]) { + if(check_stats(f, f->shared->fs_man[stype], &(state[stype]))) + TEST_ERROR + } H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); @@ -4942,6 +4989,11 @@ error: * The meta_aggr is updated to point to the new space * The block of 1034 is allocated from the new block and should be aligned * There is space of 1014 left in meta_aggr + * + * Modifications: + * Vailin Choi; July 2012 + * Changes due to the switch to H5FD_FLMAP_DICHOTOMY + * */ static unsigned test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) @@ -4953,7 +5005,7 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) H5FD_mem_t type, stype; haddr_t addr1, addr2, addr3; haddr_t saddr1, saddr2, saddr3; - frspace_state_t state; + frspace_state_t state[H5FD_MEM_NTYPES]; haddr_t ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; hsize_t ma_size=0, sdata_size=0, mis_align=0; hsize_t alignment=0, tmp=0; @@ -5007,11 +5059,11 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) if (addr1 % alignment) TEST_ERROR /* fragment for alignment of block 30 is freed to free-space */ - HDmemset(&state, 0, sizeof(frspace_state_t)); + HDmemset(&state, 0, sizeof(frspace_state_t) * H5FD_MEM_NTYPES); if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); @@ -5031,9 +5083,9 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 50 is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); @@ -5066,9 +5118,9 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 30 for sdata_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[stype].tot_space += mis_align; + state[stype].tot_sect_count += 1; + state[stype].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); @@ -5087,9 +5139,9 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 50 for sdata_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[stype].tot_space += mis_align; + state[stype].tot_sect_count += 1; + state[stype].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); @@ -5108,9 +5160,9 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 80 for sdata_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[stype].tot_space += mis_align; + state[stype].tot_sect_count += 1; + state[stype].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); @@ -5130,9 +5182,9 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 1034 for meta_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } /* calculate unused space in meta_aggr that is freed to free-space after block 1034 */ @@ -5142,9 +5194,9 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for unused space in meta_aggr after block 1034 is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); @@ -5153,8 +5205,15 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) TEST_ERROR /* Verify total size of free space after all allocations */ - if(check_stats(f, f->shared->fs_man[type], &state)) - TEST_ERROR + if(f->shared->fs_man[type]) { + if(check_stats(f, f->shared->fs_man[type], &(state[type]))) + TEST_ERROR + } + + if(f->shared->fs_man[stype]) { + if(check_stats(f, f->shared->fs_man[stype], &(state[stype]))) + TEST_ERROR + } if(H5Fclose(file) < 0) FAIL_STACK_ERROR @@ -5358,8 +5417,10 @@ test_mf_align_alloc4(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) if (addr3 % alignment) TEST_ERROR /* Verify total size of free space after all allocations */ - if(check_stats(f, f->shared->fs_man[type], &state)) - TEST_ERROR + if(f->shared->fs_man[type]) { + if(check_stats(f, f->shared->fs_man[type], &state)) + TEST_ERROR + } if(H5Fclose(file) < 0) FAIL_STACK_ERROR @@ -5445,6 +5506,10 @@ error: * sdata_aggr is reset to 0 * EOA is 14346 * meta_aggr and sdata_aggr are all 0 + * + * Modifications: + * Vailin Choi; July 2012 + * Changes due to the switch to H5FD_FLMAP_DICHOTOMY */ static unsigned test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) @@ -5455,7 +5520,7 @@ test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) h5_stat_size_t file_size; H5FD_mem_t type, stype; haddr_t addr1, addr2, saddr1; - frspace_state_t state; + frspace_state_t state[H5FD_MEM_NTYPES]; haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; haddr_t sdata_addr=HADDR_UNDEF, new_sdata_addr=HADDR_UNDEF; hsize_t ma_size=0, new_ma_size=0, sdata_size=0, new_sdata_size=0; @@ -5514,18 +5579,16 @@ test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) if ((addr1 + TEST_BLOCK_SIZE30) != ma_addr) TEST_ERROR /* fragment for alignment of block 30 is freed to free-space */ - HDmemset(&state, 0, sizeof(frspace_state_t)); + HDmemset(&state, 0, sizeof(frspace_state_t) * H5FD_MEM_NTYPES); if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } /* calculate fragment for alignment of block 30 from sdata_aggr */ mis_align = 0; - if ((alignment == TEST_ALIGN1024) && (tmp = (ma_addr + ma_size) % alignment)) - mis_align = alignment - tmp; - else if ((alignment == TEST_ALIGN4096) && (tmp = (ma_addr % alignment))) + if ((tmp = (ma_addr + ma_size) % alignment)) mis_align = alignment - tmp; /* Allocate a block of 30 from sdata_aggr */ @@ -5537,9 +5600,9 @@ test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment of alignment for block 30 in sdata_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[stype].tot_space += mis_align; + state[stype].tot_sect_count += 1; + state[stype].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); @@ -5547,9 +5610,7 @@ test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* calculate fragment for alignment of block 2058 from meta_aggr */ mis_align = 0; - if ((alignment == TEST_ALIGN1024) && (tmp = (sdata_addr + sdata_size) % alignment)) - mis_align = alignment - tmp; - else if ((alignment == TEST_ALIGN4096) && (tmp = (sdata_addr % alignment))) + if ((tmp = (sdata_addr + sdata_size) % alignment)) mis_align = alignment - tmp; /* Allocate a block of 2058 from meta_aggr */ @@ -5560,27 +5621,30 @@ test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 2058 is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } /* Verify total size of free space after all allocations */ - if(check_stats(f, f->shared->fs_man[type], &state)) - TEST_ERROR + if(f->shared->fs_man[type]) { + if(check_stats(f, f->shared->fs_man[type], &(state[type]))) + TEST_ERROR + } + + if(f->shared->fs_man[stype]) { + if(check_stats(f, f->shared->fs_man[stype], &(state[stype]))) + TEST_ERROR + } /* nothing is changed in meta_aggr */ H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); - if (alignment == TEST_ALIGN1024 && (new_ma_addr != ma_addr || new_ma_size != ma_size)) - TEST_ERROR - else if (alignment == TEST_ALIGN4096 && (new_ma_addr != 0 || new_ma_size != 0)) + if (new_ma_addr != ma_addr || new_ma_size != ma_size) TEST_ERROR /* nothing is changed in sdata_aggr */ H5MF_aggr_query(f, &(f->shared->sdata_aggr), &new_sdata_addr, &new_sdata_size); - if (alignment == TEST_ALIGN1024 && (new_sdata_addr != sdata_addr || new_sdata_size != sdata_size)) - TEST_ERROR - else if (alignment == TEST_ALIGN4096 && ((new_sdata_addr != 0 || new_sdata_size != 0))) + if (new_sdata_addr != sdata_addr || new_sdata_size != sdata_size) TEST_ERROR if(H5Fclose(file) < 0) @@ -5672,21 +5736,16 @@ error: * Result: * A block of sdata_aggr->alloc_size is allocated from file allocation * Fragment from alignment of file allocation is freed to free-space: [6144, 2048] - * This fragment adjoins meta_aggr and fulfills "absorb" condition, - * the remaining space left in meta_aggr is absorbed into the fragment and - * freed to free-space:[4126, 2018] - * meta_aggr is reset to 0 * The first block of 30 is allocated from the aggregator and should be aligned * There is space of 2018 left in sdata_aggr - * EOA is 5120 + * EOA is 10240 * * Allocate second block (50) from sdata_aggr: - * (request-size+fragment size) is <= sdata_aggr->size + * (request-size+fragment size) is > sdata_aggr->size * request-size < sdata_aggr->alloc_size * fragment size > (sdata_aggr->alloc_size - request-size) * Result: - * A block of sdata_aggr->alloc_size + (fragment size - (sdata_aggr->alloc_size - request-size)) - * is extended from file allocation for the aggregator + * A block of (fragment size + request-size) is extended from file allocation for the aggregator * The second block of 50 is allocated from sdata_aggr and should be aligned * Fragment from alignment of aggregator allocation is freed to free-space:[8222, 4066] * There is space of 2018 left in sdata_aggr @@ -5697,8 +5756,7 @@ error: * request-size < sdata_aggr->alloc_size * fragment size > (sdata_aggr->alloc_size - request-size) * Result: - * A block of sdata_aggr->alloc_size+(fragment size-(sdata_aggr->alloc_size-request-size)) - * is extended from file allocation for sdata_aggr + * A block of (fragment size + request-size) is extended from file allocation for sdata_aggr * The third block of 80 is allocated from sdata_aggr and should be aligned * Fragment from alignment of aggregator allocation is freed to free-space:[12338, 4046] * There is space of 2018 left in sdata_aggr @@ -5715,6 +5773,10 @@ error: * Fragment from alignment of file allocation is freed to free-space:[16464, 4016] * EOA is at 22538 * meta_aggr is unchanged + * + * Modifications: + * Vailin Choi; July 2012 + * Changes due to the switch to H5FD_FLMAP_DICHOTOMY */ static unsigned test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) @@ -5726,7 +5788,7 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) H5FD_mem_t type, stype; haddr_t addr1, addr2; haddr_t saddr1, saddr2, saddr3; - frspace_state_t state; + frspace_state_t state[H5FD_MEM_NTYPES]; haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; hsize_t ma_size=0, new_ma_size=0, sdata_size=0; hsize_t alignment=0, mis_align=0, tmp=0; @@ -5779,11 +5841,11 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) if (addr1 % alignment) TEST_ERROR /* fragment for alignment of block 30 in meta_aggr is freed to free-space */ - HDmemset(&state, 0, sizeof(frspace_state_t)); + HDmemset(&state, 0, sizeof(frspace_state_t) * H5FD_MEM_NTYPES); if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); @@ -5792,9 +5854,7 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* calculate fragment for alignment of block 30 in sdata_aggr */ mis_align = 0; - if ((alignment == TEST_ALIGN1024) && (tmp = (ma_addr + ma_size) % alignment)) - mis_align = alignment - tmp; - else if ((alignment == TEST_ALIGN4096) && (tmp = (ma_addr % alignment))) + if ((tmp = (ma_addr + ma_size) % alignment)) mis_align = alignment - tmp; /* Allocate a block of 30 from sdata_aggr */ @@ -5806,9 +5866,9 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 30 in sdata_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[stype].tot_space += mis_align; + state[stype].tot_sect_count += 1; + state[stype].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); @@ -5827,9 +5887,9 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 50 in sdata_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[stype].tot_space += mis_align; + state[stype].tot_sect_count += 1; + state[stype].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); @@ -5848,9 +5908,9 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 80 in sdata_aggr is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[stype].tot_space += mis_align; + state[stype].tot_sect_count += 1; + state[stype].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); @@ -5870,24 +5930,30 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) /* fragment for alignment of block 2058 is freed to free-space */ if (mis_align) { - state.tot_space += mis_align; - state.tot_sect_count += 1; - state.serial_sect_count += 1; + state[type].tot_space += mis_align; + state[type].tot_sect_count += 1; + state[type].serial_sect_count += 1; } H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); - if (alignment == TEST_ALIGN1024 && (new_ma_addr != ma_addr || new_ma_size != ma_size)) - TEST_ERROR - else if (alignment == TEST_ALIGN4096 && (new_ma_addr != 0 || new_ma_size != 0)) + if (new_ma_addr != ma_addr && new_ma_size != ma_size) TEST_ERROR - if (sdata_addr != 0 || sdata_size != 0) + if (sdata_addr != HADDR_UNDEF || sdata_size != 0) TEST_ERROR - if(check_stats(f, f->shared->fs_man[type], &state)) - TEST_ERROR + if(f->shared->fs_man[type]) { + if(check_stats(f, f->shared->fs_man[type], &(state[type]))) + TEST_ERROR + } + + + if(f->shared->fs_man[stype]) { + if(check_stats(f, f->shared->fs_man[stype], &(state[stype]))) + TEST_ERROR + } if(H5Fclose(file) < 0) FAIL_STACK_ERROR @@ -5908,6 +5974,100 @@ error: return(1); } /* test_mf_align_alloc6() */ +/* + * To verify that file space is allocated from the corresponding free-space manager + * because H5FD_FLMAP_DICHOTOMY is used as the default free-list mapping. + * + * (1) Allocate the first block (size 30) of type H5FD_MEM_SUPER + * (2) Allocate the second block (size 50) of type H5FD_MEM_SUPER + * + * (3) Allocate the first block (size 30) of type H5FD_MEM_DRAW + * + * (4) Free the first block (size 30) of type H5FD_MEM_SUPER + * + * (5) Allocate the second block (size 30) of type H5FD_MEM_DRAW + * (6) Verify that this second block is not the freed block from (3) + * + * (7) Allocate the second block (size 30) of type H5FD_MEM_DRAW + * (8) Free the first block (size 30) of type H5FD_MEM_DRAW + * + * (9) Allocate the third block (size 30) of type H5FD_MEM_SUPER + * (10) Verify that this third block is not freed block from (8) + */ +static unsigned +test_dichotomy(const char *env_h5_drvr, hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type, stype; + haddr_t addr1, addr2, addr3, saddr1, saddr2; + hbool_t contig_addr_vfd; /* Whether VFD used has a contigous address space */ + + TESTING("Allocation from raw or metadata free-space manager"); + + /* Skip test when using VFDs that don't use the metadata aggregator */ + contig_addr_vfd = (hbool_t)(HDstrcmp(env_h5_drvr, "split") && HDstrcmp(env_h5_drvr, "multi")); + if(contig_addr_vfd) { + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate the first block of type H5FD_MEM_SUPER */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Allocate the second block of type H5FD_MEM_SUPER */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Allocate the first block of type H5FD_MEM_DRAW */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Free the first block of type H5FD_MEM_SUPER */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + + /* Allocate the second block of type H5FD_MEM_DRAW */ + saddr2 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that saddr1 is not addr1 */ + if(saddr2 == addr1) TEST_ERROR + + /* Free the first block of type H5FD_MEM_DRAW */ + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE30); + + /* Allocate the third block of type H5FD_MEM_SUPER */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that addr3 is not saddr1 */ + if(addr3 == saddr1) TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + } /* end if */ + else { + SKIPPED(); + puts(" Current VFD doesn't support metadata aggregator"); + } /* end else */ + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_dichotomy() */ + int main(void) { @@ -5950,6 +6110,7 @@ main(void) nerrors += test_mf_fs_alloc_free(fapl); nerrors += test_mf_fs_extend(fapl); nerrors += test_mf_fs_absorb(env_h5_drvr, fapl); + nerrors += test_dichotomy(env_h5_drvr, new_fapl); /* interaction with meta/sdata aggregator */ nerrors += test_mf_aggr_alloc1(env_h5_drvr, fapl); diff --git a/test/tfile.c b/test/tfile.c index 32831b9..65cbf74 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -1312,6 +1312,11 @@ test_file_perm2(void) ** This test checks the free space available in a file in various ** situations. ** +** Modifications: +** Vailin Choi; July 2012 +** Remove datasets in reverse order so that all file spaces are shrunk. +** (A change due to H5FD_FLMAP_DICHOTOMY.) +** *****************************************************************/ static void test_file_freespace(void) @@ -1323,6 +1328,7 @@ test_file_freespace(void) hid_t dspace; /* Dataspace ID */ hid_t dset; /* Dataset ID */ hid_t dcpl; /* Dataset creation property list */ + int k; /* Local index variable */ unsigned u; /* Local index variable */ char name[32]; /* Dataset name */ herr_t ret; @@ -1382,11 +1388,11 @@ test_file_freespace(void) /* Check that there is the right amount of free space in the file */ free_space = H5Fget_freespace(file); CHECK(free_space, FAIL, "H5Fget_freespace"); - VERIFY(free_space, 2008, "H5Fget_freespace"); + VERIFY(free_space, 2360, "H5Fget_freespace"); /* Delete datasets in file */ - for(u = 0; u < 10; u++) { - sprintf(name, "Dataset %u", u); + for(k = 9; k >= 0; k--) { + sprintf(name, "Dataset %u", (unsigned)k); ret = H5Ldelete(file, name, H5P_DEFAULT); CHECK(ret, FAIL, "H5Ldelete"); } /* end for */ -- cgit v0.12