mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-12-27 08:01:04 +08:00
9289 lines
343 KiB
C
9289 lines
343 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Copyright by The HDF Group. *
|
|
* 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 COPYING file, which can be found at the root of the source code *
|
|
* distribution tree, or in https://www.hdfgroup.org/licenses. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/*
|
|
* Tests for file memory management consist of 3 parts:
|
|
* test_mf_eoa_*() tests for file meomory that interact with file allocation
|
|
* test_mf_fs_*() tests for file memory that interact with the free-space manager
|
|
* test_mf_aggr_*() tests for file memory that interact with the aggregators
|
|
* test_mf_align_*() tests for file memory with alignment setting
|
|
* test_filespace_*() tests for file space management
|
|
* test_page_*() tests for file space paging
|
|
*/
|
|
|
|
#include "h5test.h"
|
|
|
|
#define H5MF_FRIEND /*suppress error about including H5MFpkg */
|
|
#include "H5MFpkg.h"
|
|
|
|
#define H5FS_FRIEND /*suppress error about including H5FSpkg */
|
|
#include "H5FSpkg.h"
|
|
|
|
#define H5F_FRIEND /*suppress error about including H5Fpkg */
|
|
#define H5F_TESTING
|
|
#include "H5Fpkg.h"
|
|
|
|
#include "H5CXprivate.h" /* API Contexts */
|
|
#include "H5FLprivate.h"
|
|
#include "H5Iprivate.h"
|
|
#include "H5VLprivate.h" /* Virtual Object Layer */
|
|
#include "H5VMprivate.h"
|
|
|
|
#define FILENAME_LEN 1024
|
|
|
|
#define TBLOCK_SIZE1 1
|
|
#define TBLOCK_SIZE2 2
|
|
#define TBLOCK_SIZE3 3
|
|
#define TBLOCK_SIZE4 4
|
|
#define TBLOCK_SIZE5 5
|
|
#define TBLOCK_SIZE6 6
|
|
#ifdef PB_OUT
|
|
#define TBLOCK_SIZE7 7
|
|
#define TBLOCK_SIZE8 8
|
|
#endif /* PB_OUT */
|
|
#define TBLOCK_SIZE10 10
|
|
#define TBLOCK_SIZE11 11
|
|
#define TBLOCK_SIZE20 20
|
|
#define TBLOCK_SIZE30 30
|
|
#define TBLOCK_SIZE36 36
|
|
#define TBLOCK_SIZE40 40
|
|
#define TBLOCK_SIZE50 50
|
|
#define TBLOCK_SIZE80 80
|
|
#define TBLOCK_SIZE90 90
|
|
#define TBLOCK_SIZE98 98
|
|
#define TBLOCK_SIZE100 100
|
|
#define TBLOCK_SIZE150 150
|
|
#define TBLOCK_SIZE200 200
|
|
#define TBLOCK_SIZE600 600
|
|
#define TBLOCK_SIZE700 700
|
|
#define TBLOCK_SIZE1034 1034
|
|
#define TBLOCK_SIZE1970 1970
|
|
#define TBLOCK_SIZE2048 2048
|
|
#define TBLOCK_SIZE2058 2058
|
|
#define TBLOCK_SIZE2192 2192
|
|
#define TBLOCK_SIZE3080 3080
|
|
#define TBLOCK_SIZE3088 3088
|
|
#define TBLOCK_SIZE3198 3198
|
|
#define TBLOCK_SIZE3286 3286
|
|
#define TBLOCK_SIZE3248 3248
|
|
#define TBLOCK_SIZE3900 3900
|
|
#define TBLOCK_SIZE4020 4020
|
|
#define TBLOCK_SIZE4086 4086
|
|
#define TBLOCK_SIZE4096 4096
|
|
#define TBLOCK_SIZE4106 4106
|
|
#define TBLOCK_SIZE5000 5000
|
|
#define TBLOCK_SIZE6000 6000
|
|
#define TBLOCK_SIZE8000 8000
|
|
#define TBLOCK_SIZE8100 8100
|
|
#define TBLOCK_SIZE8192 8192
|
|
#define TBLOCK_SIZE8190 8190
|
|
#define TBLOCK_SIZE12000 12000
|
|
|
|
#define TBLOCK_ADDR70 70
|
|
#define TBLOCK_ADDR100 100
|
|
|
|
#define TEST_ALIGN16 16
|
|
#define TEST_ALIGN1024 1024
|
|
#define TEST_ALIGN4096 4096
|
|
|
|
#define TEST_THRESHOLD10 10
|
|
#define TEST_THRESHOLD3 3
|
|
|
|
static const char *FILENAME[] = {"mf", NULL};
|
|
|
|
typedef enum {
|
|
TEST_NORMAL, /* size of aggregator is >= alignment size */
|
|
TEST_AGGR_SMALL, /* size of aggregator is smaller than alignment size */
|
|
TEST_NTESTS /* The number of test types, must be last */
|
|
} test_type_t;
|
|
|
|
static int check_stats(const H5F_t *f, const H5FS_t *frsp, H5FS_stat_t *state);
|
|
|
|
static unsigned test_mf_eoa(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_eoa_shrink(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_eoa_extend(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_dichotomy(hid_t fapl);
|
|
static unsigned test_mf_fs_start(hid_t fapl);
|
|
static unsigned test_mf_fs_alloc_free(hid_t fapl);
|
|
static unsigned test_mf_fs_extend(hid_t fapl);
|
|
static unsigned test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_alloc1(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_alloc2(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_alloc3(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_alloc4(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_alloc5(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_alloc6(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_alloc7(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_extend(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_mf_align_eoa(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl);
|
|
static unsigned test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl);
|
|
static unsigned test_mf_align_alloc1(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl);
|
|
static unsigned test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl);
|
|
static unsigned test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl);
|
|
static unsigned test_mf_align_alloc4(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl);
|
|
static unsigned test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl);
|
|
static unsigned test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl);
|
|
static unsigned test_mf_tmp(const char *env_h5_drvr, hid_t fapl, bool new_format);
|
|
static unsigned test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, bool new_format);
|
|
static unsigned test_mf_strat_thres_gone(const char *env_h5_drvr, hid_t fapl, bool new_format);
|
|
static unsigned test_mf_fs_persist(const char *env_h5_drvr, hid_t fapl, bool new_format);
|
|
static unsigned test_mf_strat_thres_persist(const char *env_h5_drvr, hid_t fapl, bool new_format);
|
|
#ifdef PB_OUT
|
|
static unsigned test_mf_fs_persist_split(void);
|
|
static unsigned test_mf_fs_persist_multi(void);
|
|
#endif
|
|
static unsigned test_page_alloc_xfree(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_page_small(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_page_large(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_page_large_try_extend(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_page_small_try_extend(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_page_try_shrink(const char *env_h5_drvr, hid_t fapl);
|
|
static unsigned test_page_alignment(const char *env_h5_drvr, hid_t fapl);
|
|
|
|
/*
|
|
* Verify statistics for the free-space manager
|
|
*
|
|
*/
|
|
static int
|
|
check_stats(const H5F_t *f, const H5FS_t *frsp, H5FS_stat_t *state)
|
|
{
|
|
H5FS_stat_t frspace_stats; /* Statistics about the heap */
|
|
|
|
assert(f);
|
|
assert(frsp);
|
|
|
|
/* Get statistics for free-space and verify they are correct */
|
|
if (H5FS_stat_info(f, frsp, &frspace_stats) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (frspace_stats.tot_space != state->tot_space) {
|
|
fprintf(stdout, "frspace_stats.tot_space = %" PRIuHSIZE ", state->tot_space = %" PRIuHSIZE "\n",
|
|
frspace_stats.tot_space, state->tot_space);
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
if (frspace_stats.tot_sect_count != state->tot_sect_count) {
|
|
fprintf(stdout,
|
|
"frspace_stats.tot_sect_count = %" PRIuHSIZE ", state->tot_sect_count = %" PRIuHSIZE "\n",
|
|
frspace_stats.tot_sect_count, state->tot_sect_count);
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
if (frspace_stats.serial_sect_count != state->serial_sect_count) {
|
|
fprintf(stdout,
|
|
"frspace_stats.serial_sect_count = %" PRIuHSIZE ", state->serial_sect_count = %" PRIuHSIZE
|
|
"\n",
|
|
frspace_stats.serial_sect_count, state->serial_sect_count);
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
if (frspace_stats.ghost_sect_count != state->ghost_sect_count) {
|
|
fprintf(stdout,
|
|
"frspace_stats.ghost_sect_count = %" PRIuHSIZE ", state->ghost_sect_count = %" PRIuHSIZE "\n",
|
|
frspace_stats.ghost_sect_count, state->ghost_sect_count);
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
|
|
/* All tests passed */
|
|
return (0);
|
|
|
|
error:
|
|
return (1);
|
|
} /* check_stats() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks are allocated from file allocation
|
|
*
|
|
* Set up:
|
|
* Turn off using meta/small data aggregator
|
|
* There is nothing in free-space manager
|
|
*
|
|
* Allocate two blocks which should be from file allocation
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_eoa(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
H5FD_mem_t type;
|
|
haddr_t addr1, addr2;
|
|
haddr_t ma_addr = HADDR_UNDEF, new_ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MM_alloc() of file allocation");
|
|
|
|
/* Skip test when using VFDs that has different address spaces for each
|
|
* type of metadata allocation. Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 &&
|
|
strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_vfd) {
|
|
/* Set the filename to use for this test */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if ((fapl_new = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Turn off using meta/small data aggregator */
|
|
H5Pset_meta_block_size(fapl_new, (hsize_t)0);
|
|
H5Pset_small_data_block_size(fapl_new, (hsize_t)0);
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* nothing should be changed in meta_aggr */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size);
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
if (addr1 < (haddr_t)file_size)
|
|
TEST_ERROR;
|
|
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* nothing should be changed in meta_aggr */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size);
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
if (addr2 < (haddr_t)file_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30 + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Pclose(fapl_new) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support continuous address space");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl_new);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_eoa() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that an allocated block from file allocation is shrunk.
|
|
*
|
|
* Set up:
|
|
* Turn off using meta/small data aggregator
|
|
* There is nothing in free-space manager
|
|
*
|
|
* Test 1: Allocate a block of 30 from file allocation
|
|
* H5MF_try_shrink() the block by 30 : succeed
|
|
* Test 2: Allocate a block of 30 from file allocation
|
|
* H5MF_try_shrink() the block by 20 : fail
|
|
* Test 3: Allocate a block of 30 from file allocation
|
|
* H5MF_try_shrink() the block by 40 : fail
|
|
* Test 4: Allocate a block of 30 from file allocation
|
|
* H5MF_try_shrink() the block by 20 from the end: succeed
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_eoa_shrink(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size = 0, new_file_size; /* file size */
|
|
H5FD_mem_t type = H5FD_MEM_DEFAULT;
|
|
haddr_t addr = 0;
|
|
haddr_t ma_addr = HADDR_UNDEF, new_ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0, new_ma_size = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_try_shrink() of file allocation: test 1");
|
|
|
|
/* Skip test when using VFDs that has different address spaces for each
|
|
* type of metadata allocation. Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 &&
|
|
strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_vfd) {
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if ((fapl_new = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Turn off using meta/small data aggregator */
|
|
H5Pset_meta_block_size(fapl_new, (hsize_t)0);
|
|
H5Pset_small_data_block_size(fapl_new, (hsize_t)0);
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
type = H5FD_MEM_SUPER;
|
|
addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (addr < (haddr_t)file_size)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in 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_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
/* should succeed */
|
|
if (H5MF_try_shrink(f, type, addr, (hsize_t)TBLOCK_SIZE30) <= 0)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in meta_aggr */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size);
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
if (new_ma_size != ma_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_shrink() of file allocation: test 2");
|
|
|
|
/* Skip test when using VFDs that has different address spaces for each
|
|
* type of metadata allocation. Also skip test for Direct VFD.
|
|
*/
|
|
if (suitable_vfd) {
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (addr < (haddr_t)file_size)
|
|
TEST_ERROR;
|
|
|
|
/* should not succeed in shrinking */
|
|
if (H5MF_try_shrink(f, type, addr, (hsize_t)TBLOCK_SIZE30 - 10) > 0)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in meta_aggr */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size);
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
if (new_ma_size != ma_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_shrink() of file allocation: test 3");
|
|
|
|
/* Skip test when using VFDs that has different address spaces for each
|
|
* type of metadata allocation. Also skip test for Direct VFD.
|
|
*/
|
|
if (suitable_vfd) {
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
/* should not succeed in shrinking */
|
|
if (H5MF_try_shrink(f, type, addr, (hsize_t)TBLOCK_SIZE30 + 10) > 0)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in meta_aggr */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size);
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
if (new_ma_size != ma_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_shrink() of file allocation: test 4");
|
|
|
|
/* Skip test when using VFDs that has different address spaces for each
|
|
* type of metadata allocation. Also skip test for Direct VFD.
|
|
*/
|
|
if (suitable_vfd) {
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
/* should succeed in shrinking */
|
|
if (H5MF_try_shrink(f, type, addr + 10, (hsize_t)(TBLOCK_SIZE30 - 10)) <= 0)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in meta_aggr */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size);
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
if (new_ma_size != ma_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != (file_size + 10))
|
|
TEST_ERROR;
|
|
|
|
if (H5Pclose(fapl_new) < 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
|
|
{
|
|
H5Pclose(fapl_new);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_eoa_shrink() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that an allocated block from file allocation is extended.
|
|
*
|
|
* Set up:
|
|
* Turn off using meta/small data aggregator
|
|
* There is nothing in free-space manager
|
|
*
|
|
* Test 1: Allocate a block of 30
|
|
* H5MF_try_extend() the block of size 30 by 50: succeed
|
|
*
|
|
* Test 2: Allocate a block of 30
|
|
* H5MF_try_extend() the block of size 20 by 50: fail
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_eoa_extend(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* File size */
|
|
H5FD_mem_t type;
|
|
haddr_t addr;
|
|
htri_t was_extended;
|
|
haddr_t ma_addr = HADDR_UNDEF, new_ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0, new_ma_size = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_try_extend() of file allocation: test 1");
|
|
|
|
/* Skip test when using VFDs that has different address spaces for each
|
|
* type of metadata allocation. Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 &&
|
|
strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_vfd) {
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if ((fapl_new = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of a file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Turn off using meta/small data aggregator */
|
|
if (H5Pset_meta_block_size(fapl_new, (hsize_t)0) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_small_data_block_size(fapl_new, (hsize_t)0) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
type = H5FD_MEM_SUPER;
|
|
addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
if (addr < (haddr_t)file_size)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in 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 (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* should succeed */
|
|
was_extended =
|
|
H5MF_try_extend(f, type, (haddr_t)addr, (hsize_t)TBLOCK_SIZE30, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
if (was_extended <= 0)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in 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 (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30 + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_extend() of file allocation: test 2");
|
|
|
|
/* Skip test when using VFDs that has different address spaces for each
|
|
* type of metadata allocation. Also skip test for Direct VFD.
|
|
*/
|
|
if (suitable_vfd) {
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
type = H5FD_MEM_SUPER;
|
|
addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (addr < (haddr_t)file_size)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in meta_aggr */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
was_extended =
|
|
H5MF_try_extend(f, type, (haddr_t)addr, (hsize_t)(TBLOCK_SIZE30 - 10), (hsize_t)(TBLOCK_SIZE50));
|
|
|
|
/* should not succeed */
|
|
if (was_extended > 0)
|
|
TEST_ERROR;
|
|
|
|
/* nothing should be changed in 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 (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size + TBLOCK_SIZE30)
|
|
TEST_ERROR;
|
|
|
|
if (H5Pclose(fapl_new) < 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
|
|
{
|
|
H5Pclose(fapl_new);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_eoa_extend() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that temporary blocks are allocated correctly
|
|
*
|
|
* Set up:
|
|
* There is nothing in free-space manager
|
|
*
|
|
* Tests:
|
|
* Allocate a reasonable-sized temporary block
|
|
* Check that the temporary address is high enough
|
|
* Check that file I/O with the temporary address fails
|
|
* Check that freeing a temporary address fails
|
|
* Check that closing the file doesn't change the file's size
|
|
* Check that overlapping normal & temporary address space fails:
|
|
* - Reopen the file
|
|
* - Allocate enough temporary space to use ~1/3 of the file
|
|
* - Allocate enough 'normal' space to use ~1/3 of the file
|
|
* - Check that allocating another 1/2 of the file as temporary address
|
|
* space fails
|
|
* - Check that allocating another 1/2 of the file as normal address
|
|
* space fails
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_tmp(const char *env_h5_drvr, hid_t fapl, bool new_format)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl2 = H5I_INVALID_HID; /* File access property list */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list */
|
|
|
|
if (new_format)
|
|
TESTING("'temporary' file space allocation with new library format");
|
|
else
|
|
TESTING("'temporary' file space allocation with old library format");
|
|
|
|
/* Can't run this test with multi-file VFDs */
|
|
if (!h5_driver_uses_multiple_files(env_h5_drvr, 0)) {
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
haddr_t maxaddr; /* File's max. address */
|
|
haddr_t tmp_addr; /* Temporary space file address */
|
|
haddr_t norm_addr; /* Normal space file address */
|
|
haddr_t check_addr; /* File address for checking for errors */
|
|
unsigned char buf = 0; /* Buffer to read/write with */
|
|
herr_t status; /* Generic status value */
|
|
|
|
/* Set the filename to use for this test */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (new_format) {
|
|
/* Copy the file access property list */
|
|
if ((fapl2 = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the "use the latest version of the format" bounds for creating objects in the file */
|
|
if (H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1);
|
|
} /* end if */
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, new_format ? fapl2 : fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the file's maxaddr */
|
|
if (H5F__get_maxaddr_test(file, &maxaddr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate some temporary address space */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc_tmp(f, (hsize_t)TBLOCK_SIZE30)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if temporary file address is valid */
|
|
if (!H5F_IS_TMP_ADDR(f, tmp_addr))
|
|
TEST_ERROR;
|
|
if (tmp_addr < (haddr_t)(maxaddr - TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Reading & writing with a temporary address value should fail */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
status = H5F_block_read(f, H5FD_MEM_SUPER, tmp_addr, sizeof(buf), &buf);
|
|
}
|
|
H5E_END_TRY
|
|
if (status >= 0)
|
|
TEST_ERROR;
|
|
H5E_BEGIN_TRY
|
|
{
|
|
status = H5F_block_write(f, H5FD_MEM_SUPER, tmp_addr, sizeof(buf), &buf);
|
|
}
|
|
H5E_END_TRY
|
|
if (status >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Freeing a temporary address value should fail */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
status = H5MF_xfree(f, H5FD_MEM_SUPER, tmp_addr, (hsize_t)TBLOCK_SIZE30);
|
|
}
|
|
H5E_END_TRY
|
|
if (status >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 1/3 of the file as temporary address space */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc_tmp(f, (hsize_t)(maxaddr / 3))))
|
|
FAIL_STACK_ERROR;
|
|
if (!H5F_IS_TMP_ADDR(f, tmp_addr))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 1/3 of the file as normal address space */
|
|
if (HADDR_UNDEF == (norm_addr = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)(maxaddr / 3))))
|
|
FAIL_STACK_ERROR;
|
|
if (H5F_IS_TMP_ADDR(f, norm_addr))
|
|
TEST_ERROR;
|
|
|
|
/* Test that pushing temporary space allocation into normal space fails */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
check_addr = H5MF_alloc_tmp(f, (hsize_t)(maxaddr / 3));
|
|
}
|
|
H5E_END_TRY
|
|
if (H5_addr_defined(check_addr))
|
|
TEST_ERROR;
|
|
|
|
/* Test that pushing normal space allocation into temporary space fails */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
check_addr = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)(maxaddr / 3));
|
|
}
|
|
H5E_END_TRY
|
|
if (H5_addr_defined(check_addr))
|
|
TEST_ERROR;
|
|
|
|
/* Free the normal block (so the file doesn't blow up to a huge size) */
|
|
if (H5MF_xfree(f, H5FD_MEM_DRAW, norm_addr, (hsize_t)(maxaddr / 3)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support continuous address space");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_tmp() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that the free-space manager is created or opened
|
|
*
|
|
* Set up:
|
|
* Turn off using meta/small data aggregator
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_fs_start(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
H5FS_stat_t state;
|
|
|
|
TESTING("H5MF_create_fstype()/H5MF__open_fstype() of free-space manager");
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if ((fapl_new = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Turn off using meta/small data aggregator */
|
|
H5Pset_meta_block_size(fapl_new, (hsize_t)0);
|
|
H5Pset_small_data_block_size(fapl_new, (hsize_t)0);
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Pclose(fapl_new) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl_new);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_fs_start() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that a block is allocated/freed from/to the free-space manager
|
|
*
|
|
* Set up:
|
|
* Turn off using meta/small data aggregator
|
|
*
|
|
* Test 1:
|
|
* Add section A to free-space manager (addr=70, size=30)
|
|
* Allocate a block of size=30
|
|
* The returned space's address should be same as section A's address
|
|
* Deallocate the block which will be returned to the free-space manager
|
|
* Test 2:
|
|
* Add section A to free-space manager (addr=70, size=30)
|
|
* Allocate a block of size=20
|
|
* The returned space's address should be same as section A's address
|
|
* There should still be space of 10 left in the free-space manager
|
|
* Deallocate the block which will be returned to free-space manager
|
|
* Test 3:
|
|
* Add section A to free-space manager (addr=70, size=30)
|
|
* Allocate a block of size=40
|
|
* The free-space manager is unable to fulfill the request
|
|
* 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)
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_fs_alloc_free(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
H5MF_free_section_t *sect_node = NULL;
|
|
haddr_t addr;
|
|
haddr_t tmp;
|
|
H5FS_stat_t state;
|
|
|
|
TESTING("H5MF_alloc()/H5MF_xfree() of free-space manager:test 1");
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if ((fapl_new = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of a file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Turn off using meta/small data aggregator */
|
|
H5Pset_meta_block_size(fapl_new, (hsize_t)0);
|
|
H5Pset_small_data_block_size(fapl_new, (hsize_t)0);
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of 30 */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is section A in free-space */
|
|
if (addr != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
state.tot_space -= TBLOCK_SIZE30;
|
|
state.tot_sect_count -= 1;
|
|
state.serial_sect_count -= 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the block to free-space */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
state.tot_space += TBLOCK_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Remove section A from free-space */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30, f->shared->fs_man[H5FD_MEM_SUPER], &tmp) !=
|
|
true)
|
|
TEST_ERROR;
|
|
|
|
if (tmp != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5MF_alloc()/H5MF_xfree() of free-space manager:test 2");
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of 20 */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)(TBLOCK_SIZE20));
|
|
|
|
/* Verify that the allocated block is section A in free-space manager */
|
|
if (addr != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
/* should still have 1 section of size 10 left in free-space manager */
|
|
state.tot_space -= (TBLOCK_SIZE20);
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the block to free-space manager */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)(TBLOCK_SIZE20));
|
|
|
|
/* Still 1 section in free-space because of merging */
|
|
state.tot_space += TBLOCK_SIZE20;
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Remove section A from free-space */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30, f->shared->fs_man[H5FD_MEM_SUPER], &tmp) !=
|
|
true)
|
|
TEST_ERROR;
|
|
|
|
if (tmp != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5MF_alloc()/H5MF_xfree() of free-space manager:test 3");
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Allocate a block of 40.
|
|
* Since free-space manager cannot fulfull the request,
|
|
* the block is obtained from file allocation
|
|
*/
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)(TBLOCK_SIZE40));
|
|
|
|
/* Verify that the allocated block is not section A in free-space */
|
|
if (addr == TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
/* free-space info should be the same */
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Remove section A from free-space */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30, f->shared->fs_man[H5FD_MEM_SUPER], &tmp) !=
|
|
true)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the block is section A in free-space */
|
|
if (tmp != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the block of size 40 to free-space */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)(TBLOCK_SIZE40));
|
|
|
|
/*
|
|
* Free-space info is the same.
|
|
* The block is returned to free-space.
|
|
* It is shrunk and freed because it is at end of file.
|
|
*/
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Pclose(fapl_new) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl_new);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_fs_alloc_free() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that a block allocated from the free-space manager can be extended
|
|
*
|
|
* Set up:
|
|
* Turn off using meta/small data aggregator
|
|
*
|
|
* Test 1:
|
|
* Add section A to free-space manager: addr=70, size=30
|
|
* Allocate a block of size 30 from free-space manager
|
|
* Add section B to free-space manager: addr=100, size=50
|
|
* Try to extend the allocated block by requested-size=50
|
|
* Succeed: section A adjoins section B (70+30=100 which is section B's address) and
|
|
* requested-size (50) is equal to the size of section B
|
|
* Test 2:
|
|
* Add section A to free-space manager: addr=70, size=30
|
|
* Allocate a block of size 30 from free-space manager
|
|
* Add section B to free-space manager: addr=100, size=50
|
|
* Try to extend the allocated block by requested-size=60
|
|
* Fail: section A adjoins section B (70+30=100 which is section B's address) but
|
|
* requested-size (60) > size of section B (50)
|
|
*
|
|
* Test 3:
|
|
* Add section A to free-space manager: addr=70, size=30
|
|
* Allocate a block of size 30 from free-space manager
|
|
* Add section B to free-space manager: addr=100, size=50
|
|
* Try to extend the allocated block by requested-size=40
|
|
* Succeed: section A adjoins section B (70+30=100 which is section B's address) and
|
|
* requested-size (40) < size of section B (50), therefore,
|
|
* a section of 10 is left in the free-space manager
|
|
* Test 4:
|
|
* Add section A to free-space manager: addr=70, size=20
|
|
* Allocate a block of size 20 from free-space manager
|
|
* Add section B to free-space manager: addr=100, size=50
|
|
* 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)
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_fs_extend(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
H5MF_free_section_t *sect_node1 = NULL, *sect_node2 = NULL;
|
|
haddr_t addr;
|
|
haddr_t tmp;
|
|
H5FS_stat_t state; /* State of free space*/
|
|
htri_t was_extended;
|
|
|
|
TESTING("H5MF_try_extend() of free-space manager:test 1");
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if ((fapl_new = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of a file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Turn off using meta/small data aggregator */
|
|
H5Pset_meta_block_size(fapl_new, (hsize_t)0);
|
|
H5Pset_small_data_block_size(fapl_new, (hsize_t)0);
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node1 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of 30 */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is section A in free-space manager */
|
|
if (addr != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
state.tot_space -= TBLOCK_SIZE30;
|
|
state.tot_sect_count -= 1;
|
|
state.serial_sect_count -= 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Create section B */
|
|
sect_node2 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR100, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Add section B to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2))
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += TBLOCK_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Try to extend the allocated block */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_SUPER, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30,
|
|
(hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* should succeed */
|
|
if (was_extended <= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Section B is removed from free-space manager */
|
|
state.tot_space -= TBLOCK_SIZE50;
|
|
state.tot_sect_count -= 1;
|
|
state.serial_sect_count -= 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the extended block to free-space manager */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)(TBLOCK_SIZE30 + TBLOCK_SIZE50));
|
|
|
|
/* Verify that the extended block is back into free-space */
|
|
state.tot_space += (TBLOCK_SIZE30 + TBLOCK_SIZE50);
|
|
state.tot_sect_count = 1;
|
|
state.serial_sect_count = 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Remove the extended block */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)(TBLOCK_SIZE30 + TBLOCK_SIZE50),
|
|
f->shared->fs_man[H5FD_MEM_SUPER], &tmp) != true)
|
|
TEST_ERROR;
|
|
|
|
if (tmp != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5MF_try_extend() of free-space manager:test 2");
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node1 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of 30 */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is section A in free-space manager */
|
|
if (addr != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
state.tot_space -= TBLOCK_SIZE30;
|
|
state.tot_sect_count -= 1;
|
|
state.serial_sect_count -= 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Create section B */
|
|
sect_node2 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR100, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Add section B to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2))
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += TBLOCK_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Try to extend the allocated block */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_SUPER, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30,
|
|
(hsize_t)(TBLOCK_SIZE50 + 10));
|
|
|
|
/* Should not be able to extend the allocated block */
|
|
if (was_extended)
|
|
TEST_ERROR;
|
|
|
|
/* free-space info should remain the same */
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the allocated block A to free-space */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* the returned section A is merged with section B in free-space */
|
|
/* rest of the info remains the same */
|
|
state.tot_space += TBLOCK_SIZE30;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Remove the merged sections A & B from free-space */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)(TBLOCK_SIZE30 + TBLOCK_SIZE50),
|
|
f->shared->fs_man[H5FD_MEM_SUPER], &tmp) != true)
|
|
TEST_ERROR;
|
|
|
|
if (tmp != addr)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5MF_try_extend() of free-space manager:test 3");
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node1 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of 30 */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is section A in free-space manager */
|
|
if (addr != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
state.tot_space -= TBLOCK_SIZE30;
|
|
state.tot_sect_count -= 1;
|
|
state.serial_sect_count -= 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Create section B */
|
|
sect_node2 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR100, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Add section B to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2))
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += TBLOCK_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Try to extend the allocated block */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_SUPER, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE30,
|
|
(hsize_t)(TBLOCK_SIZE40));
|
|
|
|
/* Should succeed in extending the allocated block */
|
|
if (was_extended <= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Should have 1 section of size=10 left in free-space manager */
|
|
state.tot_space -= (TBLOCK_SIZE40);
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the extended block */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)(TBLOCK_SIZE30 + TBLOCK_SIZE40));
|
|
|
|
/* rest info is same, the extended section returned is merged with the section in free-space */
|
|
state.tot_space += (TBLOCK_SIZE30 + TBLOCK_SIZE40);
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Remove the merged sections A & B from free-space */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)(TBLOCK_SIZE30 + TBLOCK_SIZE50),
|
|
f->shared->fs_man[H5FD_MEM_SUPER], &tmp) != true)
|
|
TEST_ERROR;
|
|
|
|
if (tmp != addr)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5MF_try_extend() of free-space manager:test 4");
|
|
|
|
/* Re-open the file with meta/small data setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node1 =
|
|
H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)(TBLOCK_SIZE30 - 10));
|
|
|
|
/* Add section A of size=20 to free-space */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node1))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += (TBLOCK_SIZE30 - 10);
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of size=20 */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)(TBLOCK_SIZE30 - 10));
|
|
|
|
/* Verify that the allocated block is section A in free-space manager */
|
|
if (addr != TBLOCK_ADDR70)
|
|
TEST_ERROR;
|
|
|
|
state.tot_space -= (TBLOCK_SIZE30 - 10);
|
|
state.tot_sect_count -= 1;
|
|
state.serial_sect_count -= 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Create section B */
|
|
sect_node2 = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR100, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Add section B to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node2))
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += TBLOCK_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Try to extend the allocated block */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_SUPER, (haddr_t)TBLOCK_ADDR70, (hsize_t)(TBLOCK_SIZE30 - 10),
|
|
(hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Should not succeed in extending the allocated block */
|
|
if (was_extended)
|
|
TEST_ERROR;
|
|
|
|
/* Free-space info should be the same */
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the allocated block */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)(TBLOCK_SIZE30 - 10));
|
|
|
|
state.tot_space += (TBLOCK_SIZE30 - 10);
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Remove section A from free-space manager */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)(TBLOCK_SIZE30 - 10), f->shared->fs_man[H5FD_MEM_SUPER],
|
|
&tmp) != true)
|
|
TEST_ERROR;
|
|
|
|
if (tmp != addr)
|
|
TEST_ERROR;
|
|
|
|
/* Remove section B from free-space manager */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE50, f->shared->fs_man[H5FD_MEM_SUPER], &tmp) !=
|
|
true)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Pclose(fapl_new) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl_new);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_fs_extend() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that an aggregator is absorbed into a section.
|
|
*
|
|
* Test 1: To absorb the aggregator onto the beginning of the section
|
|
* Allocate block A from meta_aggr
|
|
* Create a free-space section node with an address that adjoins
|
|
* the end of meta_aggr and a size to make the aggregator
|
|
* get absorbed into the section.
|
|
* The adding of the section to free-space will call H5MF_aggr_absorb(),
|
|
* 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)
|
|
*
|
|
* Test 2: To absorb the aggregator onto the end of the section
|
|
* Allocate block A from meta_aggr
|
|
* Allocate block B from sdata_aggr
|
|
* Create a free-space section node with an address that adjoins
|
|
* the beginning of meta_aggr and a size to make the
|
|
* aggregator get absorbed into the section.
|
|
* The adding of the section to free-space will call H5MF_aggr_absorb(),
|
|
* 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)
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
haddr_t addr, saddr;
|
|
haddr_t tmp;
|
|
haddr_t ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0;
|
|
H5MF_free_section_t *sect_node = NULL;
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
|
|
TESTING("A free-space section absorbs an aggregator: test 1");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a section from meta_aggr */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
/* Create a section */
|
|
sect_node =
|
|
H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)(ma_addr + ma_size), (hsize_t)TBLOCK_SIZE2048);
|
|
|
|
/* Add a section to free-space that adjoins end of the aggregator */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that the section did absorb the aggregator */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)(ma_addr + ma_size),
|
|
f->shared->fs_man[H5FD_MEM_SUPER], &tmp) != true)
|
|
TEST_ERROR;
|
|
|
|
if (tmp != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Restore info for aggregator */
|
|
f->shared->meta_aggr.addr = ma_addr;
|
|
f->shared->meta_aggr.size = ma_size;
|
|
|
|
/* Remove section from meta_aggr */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("A free-space section absorbs an aggregator: test 2");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
if (contig_addr_vfd) {
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a section from meta_aggr */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
/* Allocate a section from sdata_aggr */
|
|
saddr = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Add a section to free-space that adjoins the beginning of meta_aggr */
|
|
sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)addr, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* When adding, meta_aggr is absorbed onto the end of the section */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that the section did absorb the aggregator */
|
|
if (H5MF__find_sect(f, H5FD_MEM_SUPER, (hsize_t)(ma_size + TBLOCK_SIZE30),
|
|
f->shared->fs_man[H5FD_MEM_SUPER], &tmp) != true)
|
|
TEST_ERROR;
|
|
|
|
if ((tmp + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* restore info to meta_aggr */
|
|
f->shared->meta_aggr.addr = ma_addr;
|
|
f->shared->meta_aggr.size = ma_size;
|
|
|
|
/* Remove section from meta_aggr */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)TBLOCK_SIZE30);
|
|
/* Remove section from sdata_aggr */
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, saddr, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
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_mf_fs_absorb() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks are allocated from the aggregator
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (nothing in the aggregator)
|
|
* request-size is > what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* The first block of 30 is allocated from meta_aggr
|
|
* There is space of 2018 left in meta_aggr
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* request-size is <= what is left in meta_aggr
|
|
* Result:
|
|
* The second block of 50 is allocated from meta_aggr
|
|
* There is space of 1968 left in meta_aggr
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_alloc1(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
hid_t fcpl; /* File creation property list */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
H5FD_mem_t type;
|
|
haddr_t addr1, addr2;
|
|
haddr_t ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator:test 1");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator. Also skip test for Direct VFD. */
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 &&
|
|
strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_vfd) {
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* File creation property list template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set to H5F_FSPACE_STRATEGY_AGGR strategy */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_AGGR, false, (hsize_t)1) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get the size of a file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate first block from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
if ((addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30)) == HADDR_UNDEF)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate second block from meta_aggr */
|
|
if ((addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50)) == HADDR_UNDEF)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr2 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30 + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
TEST_ERROR;
|
|
|
|
/* Free the two blocks: order matters because of H5F_FSPACE_STRATEGY_AGGR strategy */
|
|
if (H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50) < 0)
|
|
TEST_ERROR;
|
|
if (H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Pclose(fcpl) < 0)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
H5Pclose(fcpl);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_aggr_alloc1() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks are allocated from the aggregator
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (nothing in the aggregator)
|
|
* request-size is > what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is obtained via file allocation
|
|
* There is space of 2018 left in meta_aggr
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* request-size is <= what is left in meta_aggr
|
|
* Result:
|
|
* The second block of 50 is allocated from what is left in meta_aggr
|
|
* There is space of 1968 left in meta_aggr
|
|
*
|
|
* Allocate third block (2058) from meta_aggr:
|
|
* request-size is > what is left in meta_aggr and is >= meta_aggr->alloc_size
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* A block of request-size is extended via file allocation and is merged with meta_aggr
|
|
* The block of 2058 is allocated out of meta_aggr
|
|
* There is space of 1968 left in meta_aggr
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_alloc2(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
H5FD_mem_t type;
|
|
haddr_t addr1, addr2, addr3;
|
|
haddr_t ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator:test 2");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator. Also skip test for Direct VFD. */
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 &&
|
|
strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of a file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr2 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
if (ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2058);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr3 + TBLOCK_SIZE2058) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
if (ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
/* Unused space is freed from the end of the file */
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30 + TBLOCK_SIZE50 + TBLOCK_SIZE2058))
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30 + TBLOCK_SIZE50 + TBLOCK_SIZE2058);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_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_mf_aggr_alloc2() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks are allocated from the aggregator
|
|
*
|
|
* Allocate first block (30) from meta_aggr : (nothing in the aggregator)
|
|
* request-size is > what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocated from there
|
|
* There is space of 2018 left in meta_aggr
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* request-size is <= what is left in meta_aggr
|
|
* Result:
|
|
* The second block of 50 is allocated from what is left in meta_aggr
|
|
* There is space of 1968 left in meta_aggr
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (nothing in sdata_aggr)
|
|
* request-size is > what is left in other_aggr and is < sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of sdata_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocated from there
|
|
* There is space of 2018 left in sdata_aggr
|
|
*
|
|
* Allocate the third block (2058) from meta_aggr:
|
|
* request-size is > what is left in meta_aggr and >= meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size
|
|
* Result: A block of request-size is obtained via file allocation
|
|
* The new block's address is returned
|
|
* Nothing is changed in meta_aggr and sdata_aggr
|
|
*
|
|
* Allocate fourth block (50) from meta_aggr:
|
|
* request-size is <= what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* Result:
|
|
* The fourth block of 50 is allocated from what is left in meta_aggr
|
|
* There is space of 1968 left in meta_aggr
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_alloc3(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2, addr3, addr4, saddr1;
|
|
haddr_t ma_addr = HADDR_UNDEF, new_ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0, new_ma_size = 0;
|
|
haddr_t sdata_addr = HADDR_UNDEF;
|
|
hsize_t sdata_size = 0;
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator: test 3");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate first block from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate second block from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr2 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate first block from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((saddr1 + TBLOCK_SIZE30) != sdata_addr)
|
|
TEST_ERROR;
|
|
if (sdata_size != (TBLOCK_SIZE2048 - TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate third block, which is from file allocation not from meta_aggr */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)(TBLOCK_SIZE2058));
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
/* info for meta_aggr shouldn't be changed */
|
|
if (addr3 != (sdata_addr + sdata_size))
|
|
TEST_ERROR;
|
|
if ((addr3 + TBLOCK_SIZE2058) == new_ma_addr)
|
|
TEST_ERROR;
|
|
if ((new_ma_addr != ma_addr) || (new_ma_size != ma_size))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate fourth block, which should be from meta_aggr */
|
|
addr4 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr4 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50 + TBLOCK_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
/* Free all the allocated blocks */
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE2058);
|
|
H5MF_xfree(f, type, addr4, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF_xfree(f, stype, saddr1, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_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_mf_aggr_alloc3() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks are allocated from the aggregator
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (nothing in the aggregator)
|
|
* request-size is > what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is obtained via file allocation
|
|
* There is space of 2018 left in meta_aggr
|
|
* The first block of 30 is allocated from there
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (nothing in sdata_aggr)
|
|
* request-size is > what is left in sdata_aggr and < sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of sdata_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocated from there
|
|
*
|
|
* Allocate the second block (2018) from sdata_aggr:
|
|
* request-size is <= what is left in sdata_aggr and < sdata_aggr->alloc_size
|
|
* request-size is < sdata_aggr->alloc_size
|
|
* Result:
|
|
* The block is allocated from what is left in sdata_aggr (all used up)
|
|
*
|
|
* Allocate third block (50) from sdata_aggr :
|
|
* request-size is > what is left in sdata_aggr and < sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of sdata_aggr->alloc_size is extended via file allocation
|
|
* The third block of 50 is allocated from there
|
|
* There is space of 1998 left in the sdata_aggr
|
|
*
|
|
* Allocate second block (2058) from meta_aggr:
|
|
* request-size is > what is left in meta_aggr and >= meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* unused spaced in sdata_aggr is freed to free-space and is shrunk
|
|
* sdata_aggr is reset to 0
|
|
* A block of request-size is obtained via file allocation
|
|
* The new block's address is returned
|
|
* The block does not adjoin meta_aggr
|
|
* meta_aggr's info is unchanged
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_alloc4(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* File size */
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2, saddr1, saddr2, saddr3;
|
|
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;
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator:test 4");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate first block from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate first block from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((saddr1 + TBLOCK_SIZE30) != sdata_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate second block from sdata_aggr */
|
|
saddr2 = H5MF_alloc(f, stype, (hsize_t)(TBLOCK_SIZE2048 - TBLOCK_SIZE30));
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if (saddr2 + (TBLOCK_SIZE2048 - TBLOCK_SIZE30) != sdata_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate third block from sdata_aggr */
|
|
saddr3 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
|
|
if ((saddr3 + TBLOCK_SIZE50) != sdata_addr)
|
|
TEST_ERROR;
|
|
if (sdata_size != (TBLOCK_SIZE2048 - TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate second block of 2058, which is from file allocation, not from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2058);
|
|
|
|
if (addr2 != sdata_addr)
|
|
TEST_ERROR;
|
|
|
|
/* sdata_aggr is reset 0 */
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((sdata_addr != 0) && (sdata_size != 0))
|
|
TEST_ERROR;
|
|
|
|
/* info is unchanged in meta_aggr */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
if ((new_ma_addr != ma_addr) && (new_ma_size != ma_size))
|
|
TEST_ERROR;
|
|
|
|
/* Free all the allocated blocks */
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE2058);
|
|
H5MF_xfree(f, stype, saddr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, stype, saddr2, (hsize_t)TBLOCK_SIZE2048 - TBLOCK_SIZE30);
|
|
H5MF_xfree(f, stype, saddr3, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_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_mf_aggr_alloc4() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks are allocated from the aggregator
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (nothing in the aggregator)
|
|
* request-size is > what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocate from there
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* request-size is < what is left in meta_aggr
|
|
* Result:
|
|
* The second block of 50 is allocated from what is left there
|
|
* There is space of 1968 left in the meta_aggr
|
|
*
|
|
* Allocate third block (1970) from meta_aggr:
|
|
* request-size is > what is left in meta_aggr and is < meta_aggr->alloc_size
|
|
* Result: A block of meta_aggr->alloc_size is extended via file allocation and is absorbed into the
|
|
*meta_aggr The block of 1970 is allocated from there There is space of 2046 left in meta_aggr
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_alloc5(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* File size */
|
|
H5FD_mem_t type;
|
|
haddr_t addr1, addr2, addr3;
|
|
haddr_t ma_addr = HADDR_UNDEF, new_ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0, new_ma_size = 0;
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator:test 5");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate first block from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate second block from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if (addr2 + TBLOCK_SIZE50 != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate third block from meta_aggr */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1970);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
if (addr3 != ma_addr)
|
|
TEST_ERROR;
|
|
if ((addr3 + TBLOCK_SIZE1970) != new_ma_addr)
|
|
TEST_ERROR;
|
|
if (new_ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE1970 - ma_size)))
|
|
TEST_ERROR;
|
|
|
|
/* Free all the allocated blocks */
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE1970);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_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_mf_aggr_alloc5() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks are allocated from the aggregator
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (nothing in the aggregator)
|
|
* request-size is > what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocated from there
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* request-size is <= what is left in meta_aggr
|
|
* Result:
|
|
* The second block of 50 is allocated from what is left in meta_aggr
|
|
* There is space of 1968 left in meta_aggr
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (nothing in sdata_aggr)
|
|
* request-size is > what is left in sdata_aggr and is < sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of sdata_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocated from there
|
|
* There is space of 2018 left in sdata_aggr
|
|
*
|
|
* Allocate third block (1970) from meta_aggr:
|
|
* request-size is > what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is obtained via file allocation.
|
|
* The block does not adjoin meta_aggr
|
|
* sdata_aggr is untouched
|
|
* meta_aggr's unused space of [880, 1968] is freed to free-space
|
|
* meta_aggr is updated to point to the new block
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_alloc6(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size; /* file size */
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2, addr3, saddr1;
|
|
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;
|
|
H5FS_stat_t state;
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator:test 6");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
type = H5FD_MEM_SUPER;
|
|
|
|
/* Allocate first block from meta_aggr */
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate second block from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if (addr2 + TBLOCK_SIZE50 != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate first block from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((saddr1 + TBLOCK_SIZE30) != sdata_addr)
|
|
TEST_ERROR;
|
|
if (sdata_size != (TBLOCK_SIZE2048 - TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate third block from meta_aggr */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1970);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
if ((addr3 + TBLOCK_SIZE1970) != new_ma_addr)
|
|
TEST_ERROR;
|
|
if (addr3 != (sdata_addr + sdata_size))
|
|
TEST_ERROR;
|
|
|
|
if ((ma_addr + TBLOCK_SIZE1970) == new_ma_addr)
|
|
TEST_ERROR;
|
|
if (new_ma_size != (TBLOCK_SIZE2048 - TBLOCK_SIZE1970))
|
|
TEST_ERROR;
|
|
|
|
/* Verify that meta_aggr's unused space of 1968 is freed to free-space */
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50));
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[type], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free all the allocated blocks */
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE1970);
|
|
H5MF_xfree(f, stype, saddr1, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((new_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (new_file_size != file_size)
|
|
TEST_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_mf_aggr_alloc6() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks are allocated from the aggregator
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (nothing in meta_aggr)
|
|
* request-size is > what is left in meta_aggr and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocated from there
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* request-size is <= what is left in meta_aggr
|
|
* Result:
|
|
* The second block of 50 is allocated from what is left in the aggregator
|
|
* There is space of 1968 left in the meta_aggr
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (nothing in sdata_aggr)
|
|
* request-size is > what is left in sdata_aggr->size and < sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of sdata_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocate from there
|
|
*
|
|
* Allocate second block (2018) from sdata_aggr:
|
|
* request-size is <= what is left in sdata_aggr and is < sdata_aggr->alloc_size
|
|
* Result:
|
|
* The second block of 2018 is allocated from what is left in sdata_aggr (all used up)
|
|
*
|
|
* Allocate third block (50) from sdata_aggr:
|
|
* request-size is > what is left in sdata_aggr and < sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of sdata_aggr->alloc_size is extended via file allocation
|
|
* The third block of 50 is allocated from there
|
|
*
|
|
* Allocate third block (1970) from meta_aggr:
|
|
* request-size is > what is left in meta_aggr and is < meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* unused space in sdata_aggr is freed to free-space and is shrunk
|
|
* sdata_aggr is reset to 0
|
|
* A block of meta_aggr->alloc_size is obtained via file allocation
|
|
* The block does not adjoin meta_aggr
|
|
* meta_aggr's unused space of [880, 1968] is freed to free-space
|
|
* meta_aggr is updated to point to the new block
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_alloc7(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t empty_size, file_size;
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2, addr3, saddr1, saddr2, saddr3;
|
|
haddr_t ma_addr = HADDR_UNDEF, sdata_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0, sdata_size = 0;
|
|
H5FS_stat_t state;
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator:test 7");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate the first block from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate the second block from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if (addr2 + TBLOCK_SIZE50 != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate the first block from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((saddr1 + TBLOCK_SIZE30) != sdata_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate the second block from sdata_aggr */
|
|
saddr2 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE2048 - TBLOCK_SIZE30);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((saddr2 + (TBLOCK_SIZE2048 - TBLOCK_SIZE30)) != sdata_addr)
|
|
TEST_ERROR;
|
|
if (sdata_size != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate the third block from sdata_aggr */
|
|
saddr3 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((saddr3 + TBLOCK_SIZE50) != sdata_addr)
|
|
TEST_ERROR;
|
|
if (sdata_size != (TBLOCK_SIZE2048 - TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate the third block from meta_aggr */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1970);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if (addr3 != sdata_addr)
|
|
TEST_ERROR;
|
|
if ((addr3 + TBLOCK_SIZE1970) != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - TBLOCK_SIZE1970))
|
|
TEST_ERROR;
|
|
|
|
/* sdata_aggr info is reset to 0 */
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
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 */
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += (TBLOCK_SIZE2048 - (TBLOCK_SIZE30 + TBLOCK_SIZE50));
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[type], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free all the allocated blocks */
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE1970);
|
|
H5MF_xfree(f, stype, saddr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, stype, saddr2, (hsize_t)(TBLOCK_SIZE2048 - TBLOCK_SIZE30));
|
|
H5MF_xfree(f, stype, saddr3, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (file_size != empty_size)
|
|
TEST_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_mf_aggr_alloc7() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that a block can be extended from the aggregator
|
|
*
|
|
* Test 1: Allocate block A from meta_aggr which is at end of file
|
|
* Try to extend the block which adjoins the aggregator that is at end of file
|
|
* a. block size < (% * aggr->alloc_size)
|
|
* The block is allocated from the aggregator
|
|
* b. block size > (% * aggr->alloc_size) but block size < aggr->alloc_size
|
|
* The block is extended by aggr->alloc_size and the block is allocated from the aggregator
|
|
* c. block size > (% * aggr->alloc_size) but block size > aggr->alloc_size
|
|
* The block is extended by extended-request and the block is allocated from the aggregator
|
|
*
|
|
* Test 2: Allocate block A from meta_aggr
|
|
* Allocate block B from sdata_aggr so that meta_aggr is not at end of file
|
|
* Try to extend a block which adjoins meta_aggr and meta_aggr can fulfill the extended-request
|
|
* H5MF_try_extend() succeeds: the block is extended into the aggregator
|
|
*
|
|
* Test 3: Allocate block A from meta_aggr
|
|
* Allocate block B from sdata_aggr so that meta_aggr is not at end of file
|
|
* Try to extend a block which adjoins meta_aggr but meta_aggr cannot fulfill the extended-request
|
|
* H5MF_try_extend() fails
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_extend(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t empty_size = 0, file_size;
|
|
H5FD_mem_t type, stype;
|
|
haddr_t new_addr, addr, saddr;
|
|
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;
|
|
htri_t was_extended;
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
|
|
TESTING("H5MF_try_extend() of meta/sdata aggregator: test 1");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate the first block from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Adjust meta_aggr's info info for testing */
|
|
f->shared->meta_aggr.addr = addr;
|
|
f->shared->meta_aggr.size = f->shared->meta_aggr.alloc_size;
|
|
|
|
new_addr = addr - 10;
|
|
|
|
/* Try to extend the block by an amount < (% * aggr->alloc_size) */
|
|
was_extended = H5MF_try_extend(f, type, (haddr_t)new_addr, (hsize_t)10, (hsize_t)(TBLOCK_SIZE50));
|
|
|
|
/* should succeed */
|
|
if (!was_extended)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
if (new_ma_addr != (addr + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
if (new_ma_size != (f->shared->meta_aggr.alloc_size - TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* Free the allocated blocks */
|
|
H5MF_xfree(f, type, addr, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Try to extend the block by an amount > (% * aggr->alloc_size) but amount < aggr->alloc_size */
|
|
was_extended = H5MF_try_extend(f, type, (haddr_t)new_addr, (hsize_t)10, (hsize_t)(TBLOCK_SIZE700));
|
|
|
|
/* should succeed */
|
|
if (!was_extended)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
if (new_ma_addr != (addr + TBLOCK_SIZE700))
|
|
TEST_ERROR;
|
|
if (new_ma_size != (f->shared->meta_aggr.alloc_size * 2 - TBLOCK_SIZE700))
|
|
TEST_ERROR;
|
|
|
|
/* Free the allocated blocks */
|
|
H5MF_xfree(f, type, addr, (hsize_t)TBLOCK_SIZE700);
|
|
|
|
/* Try to extend the block by an amount > (% * aggr->alloc_size) but amount > aggr->alloc_size */
|
|
was_extended = H5MF_try_extend(f, type, (haddr_t)new_addr, (hsize_t)10, (hsize_t)(TBLOCK_SIZE2058));
|
|
|
|
/* should succeed */
|
|
if (!was_extended)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
if (new_ma_addr != (addr + TBLOCK_SIZE2058))
|
|
TEST_ERROR;
|
|
if (new_ma_size != f->shared->meta_aggr.size)
|
|
TEST_ERROR;
|
|
|
|
/* Free the allocated blocks */
|
|
H5MF_xfree(f, type, addr, (hsize_t)TBLOCK_SIZE2058);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (file_size != empty_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_extend() of meta/sdata aggregator: test 2");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
if (contig_addr_vfd) {
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate the first block from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate the first block from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((saddr + TBLOCK_SIZE50) != sdata_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Adjust meta_aggr's info info for testing */
|
|
f->shared->meta_aggr.addr = addr;
|
|
f->shared->meta_aggr.size = f->shared->meta_aggr.alloc_size;
|
|
|
|
new_addr = addr - 10;
|
|
|
|
/* should be able to fulfill request from the aggreqator itself */
|
|
was_extended = H5MF_try_extend(f, type, (haddr_t)new_addr, (hsize_t)10, (hsize_t)(TBLOCK_SIZE50));
|
|
|
|
if (!was_extended)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
if (new_ma_addr != (addr + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
if (new_ma_size != (f->shared->meta_aggr.alloc_size - TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* Restore info for meta_aggr */
|
|
f->shared->meta_aggr.addr = ma_addr;
|
|
f->shared->meta_aggr.size = ma_size;
|
|
|
|
H5MF_xfree(f, type, addr, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, stype, saddr, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (file_size != empty_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_extend() of meta/sdata aggregator: test 3");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
if (contig_addr_vfd) {
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate first block from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate first block from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
if ((saddr + TBLOCK_SIZE50) != sdata_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Adjust meta_aggr's info info for testing */
|
|
f->shared->meta_aggr.addr = addr;
|
|
f->shared->meta_aggr.size = 0;
|
|
|
|
new_addr = addr - 10;
|
|
|
|
/* unable to fulfill request from the aggreqator itself */
|
|
was_extended = H5MF_try_extend(f, type, (haddr_t)new_addr, (hsize_t)10, (hsize_t)(TBLOCK_SIZE50));
|
|
|
|
if (was_extended)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
if (new_ma_addr != addr)
|
|
TEST_ERROR;
|
|
if (new_ma_size != 0)
|
|
TEST_ERROR;
|
|
|
|
/* restore info for meta_aggr */
|
|
f->shared->meta_aggr.addr = ma_addr;
|
|
f->shared->meta_aggr.size = ma_size;
|
|
|
|
H5MF_xfree(f, type, addr, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, stype, saddr, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (file_size != empty_size)
|
|
TEST_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_mf_aggr_extend() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that a block is absorbed into an aggregator
|
|
*
|
|
* MF_try_shrink() only allows blocks to be absorbed into an aggregator
|
|
*
|
|
* Test 1: H5MF_alloc() block A from meta_aggr
|
|
* H5MF_try_shrink() block A should merge it back into meta_aggr
|
|
* since block A adjoins the beginning of meta_aggr
|
|
*
|
|
* Test 2: H5MF_alloc() block A from meta_aggr
|
|
* H5MF_alloc() block B from sdata_aggr
|
|
* 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
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t empty_size = 0, file_size;
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2, addr3, saddr1;
|
|
haddr_t ma_addr = HADDR_UNDEF, new_ma_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;
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
|
|
TESTING("H5MF_try_shrink() of meta/sdata aggregator: test 1");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate block A from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
ma_addr = new_ma_addr - TBLOCK_SIZE30;
|
|
|
|
if ((addr1 + TBLOCK_SIZE30) != new_ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* should succeed */
|
|
if (H5MF_try_shrink(f, type, addr1, (hsize_t)TBLOCK_SIZE30) <= 0)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (file_size != empty_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_shrink() of meta/sdata aggregator: test 2");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
if (contig_addr_vfd) {
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate block A from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
if (ma_size != (TBLOCK_SIZE2048 - TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate block B from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), NULL, &sdata_size);
|
|
|
|
/* should succeed */
|
|
if (H5MF_try_shrink(f, stype, saddr1, (hsize_t)TBLOCK_SIZE50) <= 0)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &new_sdata_addr, &new_sdata_size);
|
|
if (new_sdata_addr != saddr1)
|
|
TEST_ERROR;
|
|
if (new_sdata_size != sdata_size + TBLOCK_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_ERROR;
|
|
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (file_size != empty_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support metadata aggregator");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_shrink() of meta/sdata aggregator: test 3");
|
|
|
|
/* Skip test when using VFDs that don't use the metadata aggregator */
|
|
if (contig_addr_vfd) {
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate block A from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate block B from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr2 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate block C from meta_aggr */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)(TBLOCK_SIZE30 + TBLOCK_SIZE50));
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if ((addr3 + TBLOCK_SIZE30 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* should not succeed */
|
|
if (H5MF_try_shrink(f, type, addr2, (hsize_t)TBLOCK_SIZE50) > 0)
|
|
TEST_ERROR;
|
|
|
|
/* aggregator info should be the same as before */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size);
|
|
if (new_ma_addr != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF_xfree(f, type, addr3, (hsize_t)(TBLOCK_SIZE30 + TBLOCK_SIZE50));
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify the file is the correct size */
|
|
if (file_size != empty_size)
|
|
TEST_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_mf_aggr_absorb() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that a block allocated from file allocation is aligned, can be shrunk and extended
|
|
*
|
|
* Alignment = 1024 or 4096
|
|
*
|
|
* Test 1:
|
|
* Turn off using metadata aggregator
|
|
* Allocate a block of 30 which should be from file allocation
|
|
* Result:
|
|
* The return address should be aligned
|
|
* A fragment [800, 224] or [800, 3296] is freed to free-space
|
|
* EOA is 1054 or 4126
|
|
*
|
|
* Allocate a block of 50 which should be from file allocation
|
|
* Result:
|
|
* The return address should be aligned
|
|
* A fragment [1054, 994] or [4126, 4066] is freed to free-space
|
|
* EOA is 2098 or 8242
|
|
* Test 2:
|
|
* Turn off using metadata aggregator
|
|
* Allocate a block which should be from file allocation
|
|
* The return address should be aligned
|
|
* H5MF_try_shrink() the block with aligned address should succeed
|
|
*
|
|
* Test 3:
|
|
* Turn off using metadata aggregator
|
|
* Allocate a block which should be from file allocation
|
|
* The return address should be aligned
|
|
* H5MF_try_extend() the block with aligned address should succeed
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_align_eoa(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl1 = H5I_INVALID_HID;
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size, new_file_size;
|
|
H5FD_mem_t type;
|
|
haddr_t addr1, addr2;
|
|
haddr_t ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0;
|
|
htri_t was_extended;
|
|
H5FS_stat_t state;
|
|
hsize_t alignment = 0, mis_align = 0, tmp = 0, accum = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MM_alloc() of file allocation with alignment: test 1");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 &&
|
|
strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_vfd) {
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Turn off using meta/small data aggregator */
|
|
if ((fapl1 = H5Pcopy(new_fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
H5Pset_meta_block_size(fapl1, (hsize_t)0);
|
|
H5Pset_small_data_block_size(fapl1, (hsize_t)0);
|
|
|
|
/* Create the file to work on (without alignment) */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* get alignment setting */
|
|
if (H5Pget_alignment(fapl1, NULL, &alignment) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment and meta/sdata setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 30 */
|
|
if ((tmp = (hsize_t)file_size % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
accum = mis_align + TBLOCK_SIZE30;
|
|
|
|
/* Allocate a block of 30 from file allocation */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* there should be nothing in the aggregator */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if (ma_addr || ma_size)
|
|
TEST_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
if (mis_align) {
|
|
state.tot_space += mis_align;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
if (check_stats(f, f->shared->fs_man[type], &state))
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* calculate fragment for alignment of block 50 */
|
|
mis_align = 0;
|
|
if ((tmp = ((hsize_t)file_size + accum) % alignment))
|
|
mis_align = alignment - tmp;
|
|
accum += (mis_align + TBLOCK_SIZE50);
|
|
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* there should be nothing in the aggregator */
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
if (ma_addr || ma_size)
|
|
TEST_ERROR;
|
|
|
|
if (mis_align) {
|
|
state.tot_space += mis_align;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
if (check_stats(f, f->shared->fs_man[type], &state))
|
|
TEST_ERROR;
|
|
}
|
|
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if ((new_file_size = h5_get_file_size(filename, fapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (new_file_size != file_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_shrink() of file allocation with alignment: test 2");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
if (suitable_vfd) {
|
|
/* Re-open the file with alignment and meta/sdata setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* allocate a block of 50 from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* address should be aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if ((file_size = h5_get_file_size(filename, fapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* shrink the block */
|
|
if (H5MF_try_shrink(f, type, addr1, (hsize_t)TBLOCK_SIZE50) <= 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if ((new_file_size = h5_get_file_size(filename, fapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (new_file_size != (file_size - TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
TESTING("H5MF_try_extend() of file allocation with alignment: test 3");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
if (suitable_vfd) {
|
|
/* Re-open the file with alignment and meta/sdata setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* allocate a block of 50 */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* address should be aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if ((file_size = h5_get_file_size(filename, fapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* try to extend the block */
|
|
was_extended =
|
|
H5MF_try_extend(f, type, (haddr_t)addr1, (hsize_t)TBLOCK_SIZE50, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (was_extended <= 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if ((new_file_size = h5_get_file_size(filename, fapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (new_file_size != (file_size + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
if (fapl1 >= 0 && H5Pclose(fapl1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_align_eoa() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that a block allocated from the free-space manager is aligned
|
|
*
|
|
* Alignment = 1024 or 4096
|
|
*
|
|
* Test 1:
|
|
* Add section A with an aligned address to free-space manager (addr=alignment, size=50)
|
|
* Allocate a block of size=50
|
|
* The returned space's address should be same as section A's address
|
|
*
|
|
* Test 2:
|
|
* Add section A to free-space manager (addr=70, size=8000):
|
|
* section A is mis-aligned but the size is big enough for allocation with alignment
|
|
* Allocate a block of size=600
|
|
* The returned space should be allocated from section A with an aligned address:
|
|
* address=alignment size=600
|
|
* There will be 2 sections in free-space: (alignment = 1024 or alignment = 4096)
|
|
* the fragment left from aligning section A: [70, 954] or [70, 4026]
|
|
* the section left after allocating block A: [1624, 416] or [4696, 3374]
|
|
* H5MF_try_extend() the block of size 600 by 200 should succeed:
|
|
* the existing fragment left from aligning section A: [70, 954] or [70, 4026]
|
|
* the section left after extending block A: [1824, 216] or [4896, 3174]
|
|
*
|
|
* Test 3:
|
|
* Add section A to free-space manager (addr=70, size=700):
|
|
* section A is mis-aligned but the size is not big enough for allocation with alignment
|
|
* 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
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
h5_stat_size_t file_size;
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5MF_free_section_t *sect_node = NULL;
|
|
haddr_t addr;
|
|
H5FS_stat_t state;
|
|
htri_t was_extended;
|
|
hsize_t alignment = 0, tmp = 0, mis_align = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of free-space manager with alignment: test 1");
|
|
|
|
/* 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;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* get alignment setting */
|
|
if (H5Pget_alignment(new_fapl, NULL, &alignment) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)alignment, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of 50 */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Verify that the allocated block is section A in free-space */
|
|
if (addr != (haddr_t)alignment)
|
|
TEST_ERROR;
|
|
if (addr % alignment)
|
|
TEST_ERROR;
|
|
|
|
state.tot_space -= TBLOCK_SIZE50;
|
|
state.tot_sect_count -= 1;
|
|
state.serial_sect_count -= 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the block to free-space */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
state.tot_space += TBLOCK_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5MF_alloc() of free-space manager with alignment: test 2");
|
|
|
|
/* Re-open the file with alignment setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE8000);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE8000;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of 600 */
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE600);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* should have 1 more section in free-space */
|
|
state.tot_space -= TBLOCK_SIZE600;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* try to extend the block */
|
|
was_extended =
|
|
H5MF_try_extend(f, H5FD_MEM_SUPER, (haddr_t)addr, (hsize_t)TBLOCK_SIZE600, (hsize_t)TBLOCK_SIZE200);
|
|
|
|
if (was_extended <= 0)
|
|
TEST_ERROR;
|
|
|
|
/* space should be decreased by 200, # of sections remain the same */
|
|
state.tot_space -= TBLOCK_SIZE200;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
/* Free the block to free-space manager */
|
|
H5MF_xfree(f, H5FD_MEM_SUPER, addr, (hsize_t)(TBLOCK_SIZE600 + TBLOCK_SIZE200));
|
|
|
|
/* only 1 section in free-space because of merging */
|
|
state.tot_space += (TBLOCK_SIZE600 + TBLOCK_SIZE200);
|
|
state.tot_sect_count = 1;
|
|
state.serial_sect_count = 1;
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5MF_alloc() of free-space manager with alignment: test 3");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 &&
|
|
strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_vfd) {
|
|
if ((file_size = h5_get_file_size(filename, new_fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__start_fstype(f, (H5F_mem_page_t)H5FD_MEM_SUPER) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_state[H5FD_MEM_SUPER] != H5F_FS_STATE_OPEN)
|
|
TEST_ERROR;
|
|
if (f->shared->fs_man[H5FD_MEM_SUPER]->client != H5FS_CLIENT_FILE_ID)
|
|
TEST_ERROR;
|
|
|
|
/* Create section A */
|
|
sect_node = H5MF__sect_new(H5MF_FSPACE_SECT_SIMPLE, (haddr_t)TBLOCK_ADDR70, (hsize_t)TBLOCK_SIZE700);
|
|
|
|
/* Add section A to free-space manager */
|
|
if (H5MF__add_sect(f, H5FD_MEM_SUPER, f->shared->fs_man[H5FD_MEM_SUPER], sect_node))
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
state.tot_space += TBLOCK_SIZE700;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
/*
|
|
* Allocate a block of 40
|
|
* Since free-space manager cannot fulfull the request because of alignment,
|
|
* the block is obtained from file allocation
|
|
*/
|
|
addr = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)(TBLOCK_SIZE40));
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* verify that the allocated block is from file allocation, not section A in free-space */
|
|
if (!(addr >= (haddr_t)file_size))
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 40 from file allocation */
|
|
if ((tmp = (hsize_t)file_size % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
if (mis_align) {
|
|
state.tot_space += mis_align;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
}
|
|
|
|
/* free-space info should be the same */
|
|
if (check_stats(f, f->shared->fs_man[H5FD_MEM_SUPER], &state))
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_align_fs() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks allocated from the aggregator are aligned
|
|
*
|
|
* Alignment = 1024 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (nothing in the aggregator)
|
|
* request-size > aggr->size and < aggr->alloc_size
|
|
* Result:
|
|
* An "aggr->alloc_size" block is allocated from file allocation for the aggregator
|
|
* EOA is 3072
|
|
* The first block of 30 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 224]
|
|
* There is space of 2018 left in meta_aggr
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* (request-size + fragment size) <= aggr->size
|
|
* Result:
|
|
* 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:[1054, 994]
|
|
* There is space of 974 left in meta_aggr
|
|
*
|
|
* Allocate third block (80) from meta_aggr:
|
|
* (request-size + fragment size) > aggr->size
|
|
* request-size < meta_aggr->alloc_size
|
|
* fragment size < (meta_aggr->alloc_size - request-size)
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* A block of "meta_aggr->alloc_size" is extended from file allocation for meta_aggr
|
|
* EOA is 5120
|
|
* The third block of 80 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[2098, 974]
|
|
* There is space of 1968 left in meta_aggr
|
|
*
|
|
* Allocate fourth block (1970) from meta_aggr:
|
|
* (request-size + fragment size) is <= aggr->size
|
|
* fragment size > (aggr->alloc_size - request-size)
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* A block of aggr->alloc_size + fragment size - (aggr->alloc_size - request-size))
|
|
* is extended from file allocation for meta_aggr
|
|
* The third block of 1970 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[3152, 944]
|
|
* There is space of 1968 left in meta_aggr
|
|
* EOA is at 8034
|
|
*
|
|
*
|
|
* Alignment = 4096 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (aggregator is empty)
|
|
* request-size is > meta_aggr->size and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A meta_aggr->alloc_size block is allocated from file allocation for the aggregator
|
|
* The first block of 30 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 3296]
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is at 6144
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* (request-size + fragment size) is > meta_aggr->size
|
|
* request-size < meta_aggr->alloc_size
|
|
* fragment size > (meta_aggr->alloc_size - request-size)
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size + (fragment size - (meta_aggr->alloc_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
|
|
* EOA is at 10260
|
|
*
|
|
* Allocate third block (80) from meta_aggr:
|
|
* (request-size + fragment size) is > meta_aggr->size
|
|
* request-size < meta_aggr->alloc_size
|
|
* fragment size > (meta_aggr->alloc_size - request-size)
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size + (fragment size - (meta_aggr->alloc_size - request-size))
|
|
* is extended from file allocation for the aggregator
|
|
* The third block of 80 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[8242, 4046]
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is at 14386
|
|
*
|
|
* Allocate fourth block (1970) from meta_aggr:
|
|
* (request-size + fragment size) > meta_aggr->size
|
|
* request-size < meta_aggr->alloc_size
|
|
* fragment size > (meta_aggr->alloc_size - request-size)
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size + (fragment size - (meta_aggr->alloc_size - request-size))
|
|
* is extended from file allocation for the aggregator
|
|
* The fourth block of 1970 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[12368, 4016]
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is at 20372
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_align_alloc1(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size; /* File size */
|
|
|
|
H5FD_mem_t type;
|
|
haddr_t addr1, addr2, addr3, addr4;
|
|
H5FS_stat_t state;
|
|
haddr_t ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0, mis_align = 0;
|
|
hsize_t alignment = 0, tmp = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 1");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 &&
|
|
strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_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 (without alignment) */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* get alignment setting */
|
|
if (H5Pget_alignment(new_fapl, NULL, &alignment) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 30 */
|
|
if ((tmp = (hsize_t)file_size % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 30 is freed to free-space */
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
if (mis_align) {
|
|
state.tot_space += mis_align;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
}
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 50 */
|
|
mis_align = 0;
|
|
if ((tmp = ma_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 50 from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr2 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 80 */
|
|
mis_align = 0;
|
|
if ((tmp = ma_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE80);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr3 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr3 + TBLOCK_SIZE80) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 1970 */
|
|
mis_align = 0;
|
|
if ((tmp = ma_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 1970 from meta_aggr */
|
|
addr4 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1970);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr4 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 1970 is freed to free-space */
|
|
if (mis_align) {
|
|
state.tot_space += mis_align;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
}
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr4 + TBLOCK_SIZE1970) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Verify total size of free space after all the allocations */
|
|
if (check_stats(f, f->shared->fs_man[type], &state))
|
|
TEST_ERROR;
|
|
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE80);
|
|
H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE1970);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_align_alloc1() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks allocated from the aggregator are aligned
|
|
*
|
|
* Alignment = 1024 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size is > meta_aggr->size and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A meta_aggr->alloc_size block is allocated from file allocation for the aggregator
|
|
* The first block of 30 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 224]
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is 3072
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* (request-size+fragment size) <= aggr->size
|
|
* Result:
|
|
* 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:[1054, 994]
|
|
* There is space of 974 left in meta_aggr
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (sdata_aggr is empty)
|
|
* request-size is > sdata_aggr->size and < sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of sdata_aggr->alloc_size is obtained via file allocation
|
|
* The first block of 30 is allocated from sdata_aggr and should be aligned
|
|
* EOA is 5120
|
|
*
|
|
* Allocate third block (80) from meta_aggr:
|
|
* request-size+fragment size is > meta_aggr->size
|
|
* sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* The unused space in meta_aggr is freed to free-space [2098, 974]
|
|
* meta_aggr is updated to point to the new block
|
|
* The third block of 80 is allocated from meta_aggr and should be aligned
|
|
* EOA is 7168
|
|
*
|
|
* Alignment = 4096 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size is > aggr->size and < aggr->alloc_size
|
|
* Result:
|
|
* A meta_aggr->alloc_size block is allocated from file allocation for the aggregator
|
|
* The first block of 30 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 3296]
|
|
* There is space of 2018 left meta_aggr
|
|
* EOA is at 6144
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* (request-size + fragment size) > aggr->size
|
|
* request-size < aggr->alloc_size
|
|
* fragment size > (aggr->alloc_size - request-size)
|
|
* Result:
|
|
* 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
|
|
* EOA is at 10260
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (sdata_aggr is empty)
|
|
* request-size is > sdata_aggr->size and < sdata_aggr->alloc_size
|
|
* meta_aggr is at EOA and has used up more than meta_aggr->alloc_size
|
|
* Result:
|
|
* The remaining space in meta_aggr is freed to free-space [8242, 2018] and shrunk since at EOF
|
|
* meta_aggr is reset to 0
|
|
* A block of sdata_aggr->alloc_size is obtained via file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space: [8242, 4046]
|
|
* The first block of 30 is allocated from sdata_aggr and should be aligned
|
|
* There is space of 2018 left in sdata_aggr
|
|
* EOA is 14336
|
|
*
|
|
* Allocate third block (80) from meta_aggr:
|
|
* (request-size + fragment size) is > meta_aggr->size
|
|
* request-size < meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size
|
|
* 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]
|
|
* 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
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size; /* File size */
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2, addr3, saddr1;
|
|
H5FS_stat_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;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 2");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 &&
|
|
strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_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 (without alignment) */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* get alignment setting */
|
|
if (H5Pget_alignment(new_fapl, NULL, &alignment) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 30 */
|
|
if ((tmp = (hsize_t)file_size % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 30 is freed to free-space */
|
|
memset(&state, 0, sizeof(H5FS_stat_t) * H5FD_MEM_NTYPES);
|
|
if (mis_align) {
|
|
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);
|
|
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 50 is freed to free-space */
|
|
mis_align = 0;
|
|
if ((tmp = ma_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 50 is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
|
|
if ((addr2 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Calculate fragment for alignment of block 30 in sdata_aggr:
|
|
*
|
|
* For alignment = 1024, alloc_size = 2048:
|
|
* block 30 is allocated from (ma_addr + ma_size),
|
|
* which is already aligned
|
|
*
|
|
* For alignment = 4096, alloc_size = 2048:
|
|
* since remaining space in meta_aggr is freed and shrunk,
|
|
* block 30 is allocated from ma_addr
|
|
*/
|
|
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)))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* fragment for alignment of block 30 for sdata_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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 */
|
|
if (saddr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size);
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if (sdata_addr != (saddr1 + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Calculate fragment for the allocation of block 80 from meta_aggr:
|
|
*
|
|
* 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 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 + sdata_size) % alignment)))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 80 from meta_aggr */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE80);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr3 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 80 is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
|
|
if ((addr3 + TBLOCK_SIZE80) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Verify total size of free space after all the allocations */
|
|
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, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE50);
|
|
H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE80);
|
|
H5MF_xfree(f, stype, saddr1, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_align_alloc2() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks allocated from the aggregator are aligned
|
|
*
|
|
* Alignment = 1024 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size is > meta_aggr->size and < meta_aggr->alloc_size
|
|
* 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:[800, 224]
|
|
* The first block of 30 is allocated from the aggregator and should be aligned
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is 3072
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* (request-size+fragment size) is <= aggr->size
|
|
* Result:
|
|
* 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:[1054, 994]
|
|
* There is space of 974 left in the aggregator
|
|
*
|
|
* Allocate first block (30) from other_aggr: (nothing in other_aggr)
|
|
* request-size is > what is left in other_aggr->size and < other_aggr->alloc_size
|
|
* Result:
|
|
* A "other_aggr->alloc_size" block is allocated from file allocation for other_aggr
|
|
* The first block of 30 is allocated from other_aggr and should be aligned
|
|
* There is space of 2018 left in other_aggr->size
|
|
* EOA is 5120
|
|
*
|
|
* Allocate second block (50) from sdata_aggr:
|
|
* (request-size+fragment size) < sdata_aggr->size
|
|
* Result:
|
|
* 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:[3102, 994]
|
|
* There is space of 974 left in sdata_aggr
|
|
*
|
|
* Allocate third block (80) from sdata_aggr:
|
|
* (request-size+fragment size) is >= sdata_aggr->size
|
|
* request-size < sdata_aggr->alloc_size
|
|
* sdata_aggr is at EOA
|
|
* Result:
|
|
* Another block of sdata_aggr->alloc_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:[4146, 974]
|
|
* There is space of 1968 left in sdata_aggr
|
|
* EOA is 7168
|
|
*
|
|
* Allocate third block (1034) from meta_aggregator:
|
|
* (request-size + alignment) > meta_aggr->size but < meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* The unused space in sdata_aggr is freed to free-space [5200, 1968] then shrunk
|
|
* sdata_aggr is reset to 0
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space [5200, 944]
|
|
* The unused space in meta_aggr is freed to free-space [2098, 974]
|
|
* 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
|
|
* EOA is 8192
|
|
*
|
|
* Alignment = 4096 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size is > what is left in aggr->size and < aggr->alloc_size
|
|
* Result:
|
|
* A meta_aggr->alloc block is allocated from file allocation for the aggregator
|
|
* The first block of 30 is allocated from the aggregator and should be aligned
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 3296]
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is at 6144
|
|
*
|
|
* Allocate second block (50) from meta_aggr:
|
|
* (request-size + fragment size) is > what is left in aggr->size
|
|
* 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
|
|
* 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
|
|
* EOA is at 10260
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (sdata_aggr is empty)
|
|
* request-size > sdata_aggr->size and < sdata_aggr->alloc_size
|
|
* meta_aggr is at EOA and has used up more than meta_aggr->alloc_size
|
|
* Result:
|
|
* The remaining space in meta_aggr is freed to free-space [8242, 2018] and shrunk
|
|
* since at EOF
|
|
* meta_aggr is reset to 0
|
|
* A block of sdata_aggr->alloc_size is obtained via file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space: [8242, 4046]
|
|
* The first block of 30 is allocated from sdata_aggr and should be aligned
|
|
* There is space of 2018 left in sdata_aggr
|
|
* EOA is 14336
|
|
*
|
|
* Allocate second block (50) from sdata_aggr:
|
|
* request-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
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[12318, 4066]
|
|
* The second block of 50 is allocated from the aggregator and should be aligned
|
|
* There is space of 2018 left in the sdata_aggr
|
|
* EOA is at 18452
|
|
*
|
|
* Allocate third block (80) from sdata_aggr:
|
|
* 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 allocated from file allocation for the aggregator
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[16434, 4046]
|
|
* The third block of 80 is allocated from the aggregator and should be aligned
|
|
* There is space of 2018 left in the sdata_aggr
|
|
* EOA is at 22578
|
|
*
|
|
* Allocate third block (1034) from meta_aggregator:
|
|
* (request-size + fragment size) is > meta_aggr->size but request-size < meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* The remaining space in sdata_aggr is freed to free-space [20560, 2018] then shrunk
|
|
* sdata_aggr is reset to 0
|
|
* There is nothing in meta_aggr
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space [20560, 4016]
|
|
* EOA is 26624
|
|
* 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
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size;
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2, addr3;
|
|
haddr_t saddr1, saddr2, saddr3;
|
|
H5FS_stat_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;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 3");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 &&
|
|
strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_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 (without alignment) */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* get alignment setting */
|
|
if (H5Pget_alignment(new_fapl, NULL, &alignment) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 30 */
|
|
if ((tmp = (hsize_t)file_size % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 30 is freed to free-space */
|
|
memset(&state, 0, sizeof(H5FS_stat_t) * H5FD_MEM_NTYPES);
|
|
if (mis_align) {
|
|
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);
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 50 */
|
|
mis_align = 0;
|
|
if ((tmp = ma_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 50 from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 50 is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
if ((addr2 + TBLOCK_SIZE50) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Calculate fragment for alignment of block 30 in sdata_aggr:
|
|
*
|
|
* For alignment = 1024, alloc_size = 2048:
|
|
* block 30 is allocated from (ma_addr + ma_size),
|
|
* which is already aligned
|
|
*
|
|
* For alignment = 4096, alloc_size = 2048:
|
|
* since remaining space in meta_aggr is freed and shrunk,
|
|
* block 30 is allocated from ma_addr
|
|
*/
|
|
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))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (saddr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 30 for sdata_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
if (sdata_addr != (saddr1 + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 50 in sdata_aggr */
|
|
mis_align = 0;
|
|
if ((tmp = sdata_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 50 from sdata_aggr */
|
|
saddr2 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (saddr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 50 for sdata_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
if (sdata_addr != (saddr2 + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 80 in sdata_aggr */
|
|
mis_align = 0;
|
|
if ((tmp = sdata_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 80 from sdata_aggr */
|
|
saddr3 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE80);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (saddr3 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 80 for sdata_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
if ((saddr3 + TBLOCK_SIZE80) != sdata_addr)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 1034 */
|
|
mis_align = 0;
|
|
if ((tmp = sdata_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 1034 for meta_aggr */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1034);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr3 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 1034 for meta_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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 */
|
|
mis_align = 0;
|
|
if ((alignment == TEST_ALIGN1024) && (tmp = (ma_addr % alignment)))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* fragment for unused space in meta_aggr after block 1034 is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
|
|
if ((addr3 + TBLOCK_SIZE1034) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* Verify total size of free space after all allocations */
|
|
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;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_align_alloc3() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks allocated from the aggregator are aligned
|
|
*
|
|
* Alignment = 4096 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size > meta_aggr->size and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 224]
|
|
* The first block of 30 is allocated from meta_aggr and should be aligned
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is 3072
|
|
*
|
|
* Allocate second block (2058) from meta_aggr:
|
|
* (request-size+fragment) is > meta_aggr->size and request-size is > meta_aggr->alloc_size
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* The second block of 2058 + fragment is extended and merged together with meta_aggr
|
|
* The block of 2058 is allocated out of the aggregator
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[1054, 994]
|
|
* There is space of 2018 (same as before) left in meta_aggr
|
|
* EOA is 6124
|
|
*
|
|
* Allocate third block (5) from meta_aggr:
|
|
* request-size+fragment < meta_aggr->size
|
|
* Result:
|
|
* A block of 5 is allocated from the aggregator
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[4106, 1014]
|
|
* There is space of 999 left in meta_aggr
|
|
*
|
|
* Alignment = 4096 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size is > meta_aggr->size and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 3296]
|
|
* The first block of 30 is allocated from meta_aggr and should be aligned
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is 6144
|
|
*
|
|
* Allocate second block (2058) from meta_aggr:
|
|
* (request-size+fragment) is > meta_aggr->size and request-size is > meta_aggr->alloc_size
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* The second block of 2058 + fragment is extended and merged together with meta_aggr
|
|
* The block of 2058 is allocated out of the aggregator
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[4126, 4066]
|
|
* There is space of 2018 (same as before) left in meta_aggr
|
|
* EOA is 12268
|
|
*
|
|
* Allocate third block (5) from meta_aggr:
|
|
* request-size+fragment is > meta_aggr->size
|
|
* request-size < meta_aggr->alloc_size
|
|
* fragment < (meta_aggr->alloc_size - request-size)
|
|
* meta_aggr is at EOA
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is extended from file allocation for the aggregator
|
|
* A block of 5 is allocated from the aggregator
|
|
* Fragment from alignment of aggregator allocation is freed to free-space:[10250, 2038]
|
|
* There is space of 2023 left in meta_aggr
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_align_alloc4(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size;
|
|
H5FD_mem_t type;
|
|
haddr_t addr1, addr2, addr3;
|
|
H5FS_stat_t state;
|
|
haddr_t ma_addr = HADDR_UNDEF;
|
|
hsize_t ma_size = 0, saved_ma_size = 0;
|
|
hsize_t alignment = 0, mis_align = 0, tmp = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 4");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 &&
|
|
strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_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 (without alignment) */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment setting and meta/sdata setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* get alignment setting */
|
|
if (H5Pget_alignment(new_fapl, NULL, &alignment) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 30 */
|
|
if ((tmp = (hsize_t)file_size % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 30 is freed to free-space */
|
|
memset(&state, 0, sizeof(H5FS_stat_t));
|
|
if (mis_align) {
|
|
state.tot_space += mis_align;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
}
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
saved_ma_size = ma_size;
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 2058 */
|
|
mis_align = 0;
|
|
if ((tmp = ma_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 2058 from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2058);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr2 + TBLOCK_SIZE2058) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* meta_aggr->size remains the same */
|
|
if (ma_size != saved_ma_size)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 5 from meta_aggr */
|
|
mis_align = 0;
|
|
if ((tmp = ma_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 5 from meta_aggr */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE5);
|
|
|
|
/* fragment for alignment of block 5 is freed to free-space */
|
|
if (mis_align) {
|
|
state.tot_space += mis_align;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
}
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr3 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* Verify total size of free space after all allocations */
|
|
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;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_align_alloc4() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks allocated from the aggregator are aligned
|
|
*
|
|
* Alignment = 1024 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size > meta_aggr->size and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 224]
|
|
* The first block of 30 is allocated from meta_aggr and should be aligned
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is 3072
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (nothing in the aggregator)
|
|
* A block of sdata_aggr->alloc_size is allocated from file allocation
|
|
* 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
|
|
*
|
|
* Allocate second block (2058) from meta_aggr:
|
|
* (request-size + fragment size) > meta_aggr->size and > meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA but has not used up sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of 2058 is allocated from file allocation
|
|
* EOA is 7178
|
|
* Nothing is changed in meta_aggr and sdata_aggr
|
|
*
|
|
* Alignment = 4096 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size is > meta_aggr->size and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 3296]
|
|
* The first block of 30 is allocated from meta_aggr and should be aligned
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is 6144
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (meta_aggr is empty)
|
|
* meta_aggr is at EOA but has not used up more than meta_aggr->alloc_size
|
|
* 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 10240
|
|
*
|
|
* Allocate second block (2058) from meta_aggr:
|
|
* request-size + fragment size is > meta_aggr->size
|
|
* request_size is > meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of 2058 is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[10240, 2048]
|
|
* This fragment adjoins sdata_aggr and fulfills "absorb" condition,
|
|
* the remaining space left in sdata_aggr is absorbed into the fragment and
|
|
* freed to free-space: [8222, 2018]
|
|
* sdata_aggr is reset to 0
|
|
* EOA is 14346
|
|
* meta_aggr and sdata_aggr are all 0
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size;
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2, saddr1;
|
|
H5FS_stat_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;
|
|
hsize_t alignment = 0, mis_align = 0, tmp = 0;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 5");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 &&
|
|
strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_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 (without alignment) */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment setting and meta/sdata setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* get alignment setting */
|
|
if (H5Pget_alignment(new_fapl, NULL, &alignment) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 30 */
|
|
if ((tmp = (hsize_t)file_size % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
H5MF__aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
|
|
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 30 is freed to free-space */
|
|
memset(&state, 0, sizeof(H5FS_stat_t) * H5FD_MEM_NTYPES);
|
|
if (mis_align) {
|
|
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 ((tmp = (ma_addr + ma_size) % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (saddr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment of alignment for block 30 in sdata_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
if ((saddr1 + TBLOCK_SIZE30) != sdata_addr)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 2058 from meta_aggr */
|
|
mis_align = 0;
|
|
if ((tmp = (sdata_addr + sdata_size) % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 2058 from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2058);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 2058 is freed to free-space */
|
|
if (mis_align) {
|
|
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 (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 (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 (new_sdata_addr != sdata_addr || new_sdata_size != sdata_size)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_align_alloc5() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* To verify that blocks allocated from the aggregator are aligned
|
|
*
|
|
* Alignment = 1024 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size is > meta_aggr->size and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 224]
|
|
* The first block of 30 is allocated from the aggregator and should be aligned
|
|
* There is space of 2018 left in meta_aggr->size
|
|
* EOA is 3072
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (sdata_aggr is empty)
|
|
* request_size > sdata_aggr->size and < sdata_aggr->alloc_size
|
|
* Result:
|
|
* A block of sdata_aggr->alloc_size is allocated from file allocation
|
|
* 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
|
|
*
|
|
* Allocate second block (50) from sdata_aggr:
|
|
* (request-size+fragment size) <= sdata_aggr->size
|
|
* Result:
|
|
* 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:[3102, 994]
|
|
* There is space of 974 left in sdata_aggr
|
|
*
|
|
* Allocate third block (80) from sdata_aggr:
|
|
* (request-size+fragment size) > sdata_aggr->size
|
|
* request-size < sdata_aggr->alloc_size
|
|
* fragment size < (sdata_aggr->alloc_size - request-size)
|
|
* Result:
|
|
* Another block of sdata_aggr->alloc_size block 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:[4146, 974]
|
|
* There is space of 1968 left in sdata_aggr
|
|
* EOA is 7168
|
|
*
|
|
* Allocate second block (2058) from meta_aggr:
|
|
* request-size + fragment size is > meta_aggr->size
|
|
* request-size is > meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* The remaining space in sdata_aggr is freed to free-space and shrunk
|
|
* sdata_aggr is reset to 0
|
|
* A block of 2058 is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[5200, 944]
|
|
* EOA is at 8202
|
|
* meta_aggr is unchanged
|
|
*
|
|
* Alignment = 4096 aggr->alloc_size = 2048
|
|
*
|
|
* Allocate first block (30) from meta_aggr: (meta_aggr is empty)
|
|
* request-size is > meta_aggr->size and < meta_aggr->alloc_size
|
|
* Result:
|
|
* A block of meta_aggr->alloc_size is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[800, 3296]
|
|
* The first block of 30 is allocated from the aggregator and should be aligned
|
|
* There is space of 2018 left in meta_aggr
|
|
* EOA is 6144
|
|
*
|
|
* Allocate first block (30) from sdata_aggr: (sdata_aggr is empty)
|
|
* request_size > sdata_aggr->size and < sdata_aggr->alloc_size
|
|
* 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]
|
|
* 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 10240
|
|
*
|
|
* Allocate second block (50) from sdata_aggr:
|
|
* (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 (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
|
|
* EOA is at 14356
|
|
*
|
|
* Allocate third block (80) from sdata_aggr:
|
|
* (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 (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
|
|
* EOA is 18482
|
|
*
|
|
* Allocate second block (2058) from meta_aggr:
|
|
* request-size + fragment size is > meta_aggr->size
|
|
* request-size is > meta_aggr->alloc_size
|
|
* sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size
|
|
* Result:
|
|
* The remaining space in sdata_aggr is freed to free-space and shrunk: [16464, 2018]
|
|
* sdata_aggr is reset to 0
|
|
* A block of 2058 is allocated from file allocation
|
|
* Fragment from alignment of file allocation is freed to free-space:[16464, 4016]
|
|
* EOA is at 22538
|
|
* meta_aggr is unchanged
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
h5_stat_size_t file_size;
|
|
H5FD_mem_t type, stype;
|
|
haddr_t addr1, addr2;
|
|
haddr_t saddr1, saddr2, saddr3;
|
|
H5FS_stat_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;
|
|
bool suitable_vfd;
|
|
|
|
TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 6");
|
|
|
|
/* Skip test when using VFDs that have their own 'alloc' callback, which
|
|
* don't push mis-aligned space fragments on the file free space list.
|
|
* Also skip test for Direct VFD.
|
|
*/
|
|
suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 &&
|
|
strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0);
|
|
if (suitable_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 (without alignment) */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the file with alignment setting and meta/sdata setting */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* get alignment setting */
|
|
if (H5Pget_alignment(new_fapl, NULL, &alignment) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 30 */
|
|
if ((tmp = (hsize_t)file_size % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from meta_aggr */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 30 in meta_aggr is freed to free-space */
|
|
memset(&state, 0, sizeof(H5FS_stat_t) * H5FD_MEM_NTYPES);
|
|
if (mis_align) {
|
|
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);
|
|
if ((addr1 + TBLOCK_SIZE30) != ma_addr)
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 30 in sdata_aggr */
|
|
mis_align = 0;
|
|
if ((tmp = (ma_addr + ma_size) % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 30 from sdata_aggr */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (saddr1 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 30 in sdata_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
if (sdata_addr != (saddr1 + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 50 in sdata_aggr */
|
|
mis_align = 0;
|
|
if ((tmp = sdata_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 50 from sdata_aggr */
|
|
saddr2 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (saddr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 50 in sdata_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
if (sdata_addr != (saddr2 + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 80 in sdata_aggr */
|
|
mis_align = 0;
|
|
if ((tmp = sdata_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 80 from sdata_aggr */
|
|
saddr3 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE80);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (saddr3 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 80 in sdata_aggr is freed to free-space */
|
|
if (mis_align) {
|
|
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);
|
|
if (sdata_addr != (saddr3 + TBLOCK_SIZE80))
|
|
TEST_ERROR;
|
|
|
|
/* calculate fragment for alignment of block 2058 */
|
|
/* remaining space in sdata_aggr is freed and shrunk */
|
|
mis_align = 0;
|
|
if ((tmp = sdata_addr % alignment))
|
|
mis_align = alignment - tmp;
|
|
|
|
/* Allocate a block of 2058 from meta_aggr */
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2058);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % alignment)
|
|
TEST_ERROR;
|
|
|
|
/* fragment for alignment of block 2058 is freed to free-space */
|
|
if (mis_align) {
|
|
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 (new_ma_addr != ma_addr && new_ma_size != ma_size)
|
|
TEST_ERROR;
|
|
|
|
if (sdata_addr != HADDR_UNDEF || sdata_size != 0)
|
|
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;
|
|
|
|
PASSED();
|
|
} /* end if */
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support mis-aligned fragments");
|
|
} /* end else */
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_mf_align_alloc6() */
|
|
|
|
/*
|
|
* Test a bug that occurs when an allocator with zero size left and an unaligned
|
|
* endpoint is extended to allocate an aligned object
|
|
*/
|
|
static unsigned
|
|
test_mf_bug1(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t copied_fapl = H5I_INVALID_HID; /* FAPL to use for this test */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FD_mem_t type;
|
|
haddr_t addr1, addr2;
|
|
hsize_t block_size;
|
|
hsize_t align;
|
|
bool split = false, multi = false;
|
|
|
|
TESTING("H5MF_alloc() bug 1");
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Copy fapl */
|
|
if ((copied_fapl = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get metadata block size */
|
|
if (H5Pget_meta_block_size(copied_fapl, &block_size) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set alignment to equal block size / 2 */
|
|
align = block_size / 2;
|
|
if (H5Pset_alignment(copied_fapl, 0, align) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Check for split or multi driver */
|
|
if (!strcmp(env_h5_drvr, "split"))
|
|
split = true;
|
|
else if (!strcmp(env_h5_drvr, "multi"))
|
|
multi = true;
|
|
|
|
/* Add alignment to member files for split/multi driver */
|
|
if (split || multi) {
|
|
if (split) {
|
|
hid_t memb_fapl_arr[H5FD_MEM_NTYPES];
|
|
|
|
/* Get current multi settings */
|
|
if (H5Pget_fapl_multi(copied_fapl, NULL, memb_fapl_arr, NULL, NULL, NULL) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set alignment. Note that it is the block size of the parent FAPL that
|
|
* is important here. */
|
|
if (H5Pset_alignment(memb_fapl_arr[H5FD_MEM_SUPER], 0, align) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pset_alignment(memb_fapl_arr[H5FD_MEM_DRAW], 0, align) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set split driver with new FAPLs */
|
|
if (H5Pset_fapl_split(copied_fapl, "-m.h5", memb_fapl_arr[H5FD_MEM_SUPER], "-r.h5",
|
|
memb_fapl_arr[H5FD_MEM_DRAW]) < 0)
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
else {
|
|
H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
|
|
hid_t memb_fapl_arr[H5FD_MEM_NTYPES];
|
|
char *memb_name[H5FD_MEM_NTYPES];
|
|
haddr_t memb_addr[H5FD_MEM_NTYPES];
|
|
bool relax;
|
|
H5FD_mem_t mt;
|
|
|
|
/* Get current multi settings */
|
|
memset(memb_name, 0, sizeof memb_name);
|
|
if (H5Pget_fapl_multi(copied_fapl, memb_map, memb_fapl_arr, memb_name, memb_addr, &relax) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Populate memb_fapl_arr, patch memb_addr so member file addresses
|
|
* are aligned */
|
|
for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) {
|
|
/* Set alignment. Note that it is the block size of the parent FAPL that
|
|
* is important here. */
|
|
if (H5Pset_alignment(memb_fapl_arr[mt], 0, align) < 0)
|
|
TEST_ERROR;
|
|
memb_addr[mt] = ((memb_addr[mt] + align - 1) / align) * align;
|
|
} /* end for */
|
|
|
|
/* Set multi driver with new FAPLs */
|
|
if (H5Pset_fapl_multi(copied_fapl, memb_map, memb_fapl_arr, (const char *const *)memb_name,
|
|
memb_addr, relax) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Free memb_name */
|
|
for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++)
|
|
free(memb_name[mt]);
|
|
} /* end else */
|
|
} /* end if */
|
|
|
|
/* Reopen the file with alignment */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, copied_fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of size align from meta_aggr. This should create an
|
|
* aggregator that extends to the end of the file, with
|
|
* block_size / 2 bytes remaining, and the end of the file aligned */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, align);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % align)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of size align from meta_aggr. This should force the
|
|
* aggregator to extend to the end of the file, with 0 bytes remaining, and
|
|
* the end of the file aligned */
|
|
type = H5FD_MEM_SUPER;
|
|
addr2 = H5MF_alloc(f, type, align);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % align)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the allocated block is placed align after the previous */
|
|
if ((addr2 - addr1) != align)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of size block_size + 1 from meta_aggr. This should
|
|
* force the aggregator to extend to the end of the file, with 0 bytes
|
|
* remaining, and the end of the file unaligned */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, block_size + (hsize_t)1);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr1 % align)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the allocated block is placed block_size / 2 after the
|
|
* previous */
|
|
if ((addr1 - addr2) != align)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a block of size 1. This should extend the aggregator from
|
|
* the previous allocation, and align the new block */
|
|
type = H5FD_MEM_SUPER;
|
|
addr2 = H5MF_alloc(f, type, (hsize_t)1);
|
|
|
|
/* Verify that the allocated block is aligned */
|
|
if (addr2 % align)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the allocated block is placed 3 * (block_size / 2) after
|
|
* the previous */
|
|
if ((addr2 - addr1) != (3 * align))
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
if (H5Pclose(copied_fapl) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
TEST_ERROR;
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_bug1() */
|
|
|
|
/*
|
|
* Verify that the file's free-space manager(s) are persistent for a split-file
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifdef PB_OUT
|
|
static unsigned
|
|
test_mf_fs_persist_split(void)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FD_mem_t type, stype, btype; /* File allocation type */
|
|
H5FS_stat_t fs_stat; /* Information for free-space manager */
|
|
haddr_t addr1, addr2, addr3, addr4; /* File address for H5FD_MEM_SUPER */
|
|
haddr_t saddr1, saddr2, saddr3, saddr4; /* File address for H5FD_MEM_DRAW */
|
|
haddr_t baddr5, baddr6, baddr7, baddr8; /* File address for H5FD_MEM_BTREE */
|
|
haddr_t tmp_addr; /* temporary variable for address */
|
|
|
|
TESTING("File's free-space managers are persistent for split-file");
|
|
|
|
/* for now, we don't support persistent free space managers
|
|
* with the split file driver.
|
|
*/
|
|
SKIPPED();
|
|
fprintf(stdout, " Persistent FSMs disabled in multi file driver.\n");
|
|
return 0; /* <========== note return */
|
|
|
|
/* File creation property list template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
|
|
/* for now, we don't support persistent free space managers
|
|
* with the split file driver.
|
|
*/
|
|
SKIPPED();
|
|
fprintf(stdout, " Persistent FSMs disabled in multi file driver.\n");
|
|
return 0; /* <========== note return */
|
|
|
|
/* File creation property list template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
|
|
if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set up split driver */
|
|
if (H5Pset_fapl_split(fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* File creation property list template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, true, (hsize_t)1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* 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, fcpl, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 4 blocks of type H5FD_MEM_SUPER */
|
|
type = H5FD_MEM_SUPER;
|
|
if (HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #1, #3 into H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 4 blocks of type H5FD_MEM_DRAW */
|
|
stype = H5FD_MEM_DRAW;
|
|
if (HADDR_UNDEF == (saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (saddr2 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (saddr3 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (saddr4 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #1, #3 into H5FD_MEM_DRAW free-space manager */
|
|
if (H5MF_xfree(f, stype, saddr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, stype, saddr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that the H5FD_MEM_SUPER free-space manager is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[type]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < (TBLOCK_SIZE1 + TBLOCK_SIZE3))
|
|
TEST_ERROR;
|
|
if (fs_stat.serial_sect_count < 2)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve block #1 from H5FD_MEM_SUPER free-space manager; block #3 still in free-space */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != addr1)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the free-space manager for H5FD_MEM_DRAW is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[stype]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_DRAW free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)stype) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[stype], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < (TBLOCK_SIZE1 + TBLOCK_SIZE3))
|
|
TEST_ERROR;
|
|
if (fs_stat.serial_sect_count < 2)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve blocks #1 from H5FD_MEM_DRAW free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != saddr1)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve blocks #3 from H5FD_MEM_DRAW free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != saddr3)
|
|
TEST_ERROR;
|
|
/* H5FD_MEM_DRAW free-space manager is going away at closing */
|
|
/* works for this one because the freeing of sect_addr is to H5FD_MEM_SUPER fs, not against itself */
|
|
|
|
/* Allocate 4 blocks of type H5FD_MEM_BTREE */
|
|
btype = H5FD_MEM_BTREE;
|
|
if (HADDR_UNDEF == (baddr5 = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE5)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (baddr6 = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE6)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (baddr7 = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE7)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (baddr8 = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE8)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #5 & #7 into H5FD_MEM_BTREE free-space manager */
|
|
if (H5MF_xfree(f, btype, baddr5, (hsize_t)TBLOCK_SIZE5) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, btype, baddr7, (hsize_t)TBLOCK_SIZE7) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that the free-space manager for H5FD_MEM_DRAW is not there */
|
|
if (H5_addr_defined(f->shared->fs_addr[stype]))
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the free-space manager for H5FD_MEM_SUPER is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[type]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < (TBLOCK_SIZE3 + TBLOCK_SIZE5 + TBLOCK_SIZE7))
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve block #3 from H5FD_MEM_SUPER free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != addr3)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve block #7 from H5FD_MEM_BTREE free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE7)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != baddr7)
|
|
TEST_ERROR;
|
|
|
|
/* There should still be block #5 of H5FD_MEM_BTREE in H5FD_MEM_BTREE free-space manager */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that the H5FD_MEM_SUPER free-space manager is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[type]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < TBLOCK_SIZE5)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
H5Pclose(fcpl);
|
|
H5Pclose(fapl);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_fs_persist_split() */
|
|
|
|
#define MULTI_SETUP(memb_map, memb_fapl, memb_name, memb_addr, sv) \
|
|
{ \
|
|
H5FD_mem_t mt; \
|
|
memset(memb_map, 0, sizeof memb_map); \
|
|
memset(memb_fapl, 0, sizeof memb_fapl); \
|
|
memset(memb_name, 0, sizeof memb_name); \
|
|
memset(memb_addr, 0, sizeof memb_addr); \
|
|
memset(sv, 0, sizeof sv); \
|
|
for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { \
|
|
memb_map[mt] = H5FD_MEM_SUPER; \
|
|
memb_fapl[mt] = H5P_DEFAULT; \
|
|
} \
|
|
memb_map[H5FD_MEM_BTREE] = H5FD_MEM_BTREE; \
|
|
memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; \
|
|
memb_map[H5FD_MEM_GHEAP] = H5FD_MEM_GHEAP; \
|
|
memb_map[H5FD_MEM_LHEAP] = H5FD_MEM_LHEAP; \
|
|
snprintf(sv[H5FD_MEM_SUPER], 64, "%%s-%c.h5", 's'); \
|
|
memb_name[H5FD_MEM_SUPER] = sv[H5FD_MEM_SUPER]; \
|
|
memb_addr[H5FD_MEM_SUPER] = 0; \
|
|
snprintf(sv[H5FD_MEM_BTREE], 64, "%%s-%c.h5", 'b'); \
|
|
memb_name[H5FD_MEM_BTREE] = sv[H5FD_MEM_BTREE]; \
|
|
memb_addr[H5FD_MEM_BTREE] = HADDR_MAX / 6; \
|
|
snprintf(sv[H5FD_MEM_DRAW], 64, "%%s-%c.h5", 'r'); \
|
|
memb_name[H5FD_MEM_DRAW] = sv[H5FD_MEM_DRAW]; \
|
|
memb_addr[H5FD_MEM_DRAW] = HADDR_MAX / 3; \
|
|
snprintf(sv[H5FD_MEM_GHEAP], 64, "%%s-%c.h5", 'g'); \
|
|
memb_name[H5FD_MEM_GHEAP] = sv[H5FD_MEM_GHEAP]; \
|
|
memb_addr[H5FD_MEM_GHEAP] = HADDR_MAX / 2; \
|
|
snprintf(sv[H5FD_MEM_LHEAP], 64, "%%s-%c.h5", 'l'); \
|
|
memb_name[H5FD_MEM_LHEAP] = sv[H5FD_MEM_LHEAP]; \
|
|
memb_addr[H5FD_MEM_LHEAP] = HADDR_MAX * 2 / 3; \
|
|
snprintf(sv[H5FD_MEM_OHDR], 64, "%%s-%c.h5", 'o'); \
|
|
memb_name[H5FD_MEM_OHDR] = sv[H5FD_MEM_OHDR]; \
|
|
memb_addr[H5FD_MEM_OHDR] = HADDR_MAX * 5 / 6; \
|
|
}
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* Verify that the file's free-space manager(s) are persistent for a multi-file
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_fs_persist_multi(void)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FD_mem_t type, stype, btype, gtype; /* File allocation type */
|
|
H5FS_stat_t fs_stat; /* Information for free-space manager */
|
|
haddr_t addr1, addr2, addr3, addr4; /* File allocation type */
|
|
haddr_t saddr1, saddr2, saddr3, saddr4; /* File address for H5FD_MEM_SUPER */
|
|
haddr_t baddr1, baddr2, baddr3, baddr4; /* File address for H5FD_MEM_DRAW */
|
|
haddr_t gaddr1, gaddr2; /* File address for H5FD_MEM_GHEAP */
|
|
haddr_t tmp_addr; /* Temporary variable for address */
|
|
H5FS_section_info_t *node; /* Free space section node */
|
|
htri_t node_found = false; /* Indicate section is in free-space */
|
|
H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; /* Memory usage map */
|
|
hid_t memb_fapl[H5FD_MEM_NTYPES]; /* Member access properties */
|
|
char sv[H5FD_MEM_NTYPES][64]; /* Name generators */
|
|
const char *memb_name[H5FD_MEM_NTYPES]; /* Name generators */
|
|
haddr_t memb_addr[H5FD_MEM_NTYPES]; /* Member starting address */
|
|
|
|
TESTING("File's free-space managers are persistent for multi-file");
|
|
|
|
/* for now, we don't support persistent free space managers
|
|
* with the multi file driver.
|
|
*/
|
|
SKIPPED();
|
|
fprintf(stdout, " Persistent FSMs disabled in multi file driver.\n");
|
|
return 0; /* <========== note return */
|
|
|
|
/* for now, we don't support persistent free space managers
|
|
* with the multi file driver.
|
|
*/
|
|
SKIPPED();
|
|
fprintf(stdout, " Persistent FSMs disabled in multi file driver.\n");
|
|
return 0; /* <========== note return */
|
|
|
|
/* File creation property list template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, true, (hsize_t)1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
MULTI_SETUP(memb_map, memb_fapl, memb_name, memb_addr, sv)
|
|
|
|
if (H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr, true) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* 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, fcpl, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 4 blocks of type H5FD_MEM_SUPER */
|
|
type = H5FD_MEM_SUPER;
|
|
if (HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #1, #3 into H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 4 blocks of type H5FD_MEM_DRAW */
|
|
stype = H5FD_MEM_DRAW;
|
|
if (HADDR_UNDEF == (saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (saddr2 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (saddr3 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (saddr4 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #1, #3 into H5FD_MEM_DRAW free-space manager */
|
|
if (H5MF_xfree(f, stype, saddr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, stype, saddr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that the H5FD_MEM_SUPER free-space manager is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[type]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < (TBLOCK_SIZE1 + TBLOCK_SIZE3))
|
|
TEST_ERROR;
|
|
if (fs_stat.serial_sect_count < 2)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve block #1 from H5FD_MEM_SUPER free-space manager; block #3 still in free-space */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != addr1)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the free-space manager for H5FD_MEM_DRAW is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[stype]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_DRAW free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)stype) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[stype], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < (TBLOCK_SIZE1 + TBLOCK_SIZE3))
|
|
TEST_ERROR;
|
|
if (fs_stat.serial_sect_count < 2)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve blocks #1 from H5FD_MEM_DRAW free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != saddr1)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve blocks #3 from H5FD_MEM_DRAW free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != saddr3)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 4 blocks of type H5FD_MEM_BTREE */
|
|
btype = H5FD_MEM_BTREE;
|
|
if (HADDR_UNDEF == (baddr1 = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (baddr2 = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (baddr3 = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (baddr4 = H5MF_alloc(f, btype, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #1 & #3 into H5FD_MEM_BTREE free-space manager */
|
|
if (H5MF_xfree(f, btype, baddr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, btype, baddr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that the free-space manager for H5FD_MEM_SUPER is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[type]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < TBLOCK_SIZE3)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve block #3 from H5FD_MEM_SUPER free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != addr3)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the free-space manager for H5FD_MEM_DRAW is not there */
|
|
if (H5_addr_defined(f->shared->fs_addr[stype]))
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the free-space manager for H5FD_MEM_BTREE is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[btype]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_BTREE free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)btype) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[btype], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < (TBLOCK_SIZE1 + TBLOCK_SIZE3))
|
|
TEST_ERROR;
|
|
if (fs_stat.serial_sect_count < 2)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 2 blocks of type H5FD_MEM_GHEAP */
|
|
gtype = H5FD_MEM_GHEAP;
|
|
if (HADDR_UNDEF == (gaddr2 = H5MF_alloc(f, gtype, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (gaddr1 = H5MF_alloc(f, gtype, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #2 into H5FD_MEM_GHEAP free-space manager */
|
|
if (H5MF_xfree(f, gtype, gaddr2, (hsize_t)TBLOCK_SIZE2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* If H5FD_MEM_SUPER is there, should not find block #1 & #3 */
|
|
if (H5_addr_defined(f->shared->fs_addr[type])) {
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if ((node_found = H5FS_sect_find(f, f->shared->fs_man[type], (hsize_t)TBLOCK_SIZE1,
|
|
(H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
if ((node_found = H5FS_sect_find(f, f->shared->fs_man[type], (hsize_t)TBLOCK_SIZE3,
|
|
(H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* Verify that the H5FD_MEM_GHEAP free-space manager is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[gtype]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_GHEAP free-space manager */
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)gtype) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[gtype], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < TBLOCK_SIZE2)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
H5Pclose(fcpl);
|
|
H5Pclose(fapl);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_fs_persist_multi() */
|
|
#endif /* PB_OUT */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* Verify that the file's free-space persists where there are free sections in the manager
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_fs_persist(const char *env_h5_drvr, hid_t fapl, bool new_format)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list ID */
|
|
hid_t fapl2 = H5I_INVALID_HID; /* File access property list ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FD_mem_t type; /* File allocation type */
|
|
H5FD_mem_t tt; /* File allocation type */
|
|
H5FS_stat_t fs_stat; /* Information for free-space manager */
|
|
haddr_t addr1, addr2, addr3, addr4, addr5, addr6; /* File address for H5FD_MEM_SUPER */
|
|
haddr_t tmp_addr; /* Temporary variable for address */
|
|
|
|
if (new_format)
|
|
TESTING("File's free-space is persistent with new library format");
|
|
else
|
|
TESTING("File's free-space is persistent with old library format");
|
|
|
|
if (strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0) {
|
|
|
|
/* File creation property list template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Copy the file access property list */
|
|
if ((fapl2 = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (new_format) {
|
|
/* Latest format */
|
|
if (H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Set to paged aggregation and persisting free-space */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, true, (hsize_t)1) < 0)
|
|
TEST_ERROR;
|
|
}
|
|
else {
|
|
/* Setting: aggregation with persisting free-space */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, true, (hsize_t)1) < 0)
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* 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, fcpl, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 6 blocks */
|
|
type = H5FD_MEM_SUPER;
|
|
if (HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr5 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE5)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr6 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE6)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #1, #3, #5 to H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, type, addr5, (hsize_t)TBLOCK_SIZE5) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__alloc_to_fs_type(f->shared, type, TBLOCK_SIZE6, (H5F_mem_page_t *)&tt);
|
|
|
|
/* Verify that H5FD_MEM_SUPER free-space manager is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[tt]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (!(f->shared->fs_man[tt]))
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)tt) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get info for free-space manager */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[tt], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify free-space info */
|
|
if (fs_stat.tot_space < (TBLOCK_SIZE1 + TBLOCK_SIZE3 + TBLOCK_SIZE5))
|
|
TEST_ERROR;
|
|
|
|
if (fs_stat.serial_sect_count < 3)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve block #3 from H5FD_MEM_SUPER free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != addr3)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve block #1 from H5FD_MEM_SUPER free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != addr1)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that H5FD_MEM_SUPER free-space manager is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[tt]))
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve block #5 from H5FD_MEM_SUPER free-space manager */
|
|
if (HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE5)))
|
|
FAIL_STACK_ERROR;
|
|
if (tmp_addr != addr5)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fapl2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support persisting free-space or paged aggregation strategy");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
H5Pclose(fcpl);
|
|
H5Pclose(fapl2);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_fs_persist() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* Verify free-space are merged/shrunk away
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, bool new_format)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list */
|
|
hid_t fapl2 = H5I_INVALID_HID; /* File access property list */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FD_mem_t type; /* File allocation type */
|
|
H5FS_stat_t fs_stat; /* Information for free-space manager */
|
|
haddr_t addr1, addr2, addr3, addr4; /* File address for H5FD_MEM_SUPER */
|
|
haddr_t addrx;
|
|
H5FD_mem_t fs_type;
|
|
bool contig_addr_vfd;
|
|
|
|
if (new_format)
|
|
TESTING("File's free-space is going away with new library format");
|
|
else
|
|
TESTING("File's free-space is going away with old library format");
|
|
|
|
/* Current VFD that does not support contiguous address space */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
|
|
if (contig_addr_vfd) {
|
|
|
|
/* File creation property list template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Copy the file access property list */
|
|
if ((fapl2 = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (new_format) {
|
|
if (H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
else {
|
|
if (H5Pset_libver_bounds(fapl2, H5F_LIBVER_V18, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
|
|
/* Set to aggregation and persisting free-space */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, true, (hsize_t)1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl2, filename, sizeof(filename));
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 4 blocks */
|
|
type = H5FD_MEM_SUPER;
|
|
if (HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #1, #3 to H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve block #1, #3 from H5FD_MEM_SUPER free-space manager */
|
|
if (HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__alloc_to_fs_type(f->shared, type, TBLOCK_SIZE4, (H5F_mem_page_t *)&fs_type);
|
|
|
|
/* Verify that the H5FD_MEM_SUPER free-space manager is not there */
|
|
if (H5_addr_defined(f->shared->fs_addr[fs_type]))
|
|
TEST_ERROR;
|
|
|
|
/* Put block #3 to H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that H5FD_MEM_SUPER free-space manager is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[fs_type]))
|
|
TEST_ERROR;
|
|
|
|
/* Start up H5FD_MEM_SUPER free-space manager */
|
|
if (!(f->shared->fs_man[fs_type]))
|
|
if (H5MF__open_fstype(f, (H5F_mem_page_t)fs_type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get info for H5FD_MEM_SUPER free-space manager */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[fs_type], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_stat.addr))
|
|
TEST_ERROR;
|
|
|
|
if (fs_stat.tot_space < TBLOCK_SIZE3)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate/free space accordingly so that the free-space manager will go away */
|
|
if (new_format) {
|
|
if (H5MF_xfree(f, type, addr4, (hsize_t)TBLOCK_SIZE4) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
else {
|
|
if (HADDR_UNDEF == (addrx = H5MF_alloc(f, type, (hsize_t)3)))
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
|
|
/* The H5FD_MEM_SUPER free-space manager will go away at H5MF_close() */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
/* Verify that the H5FD_MEM_SUPER free-space manager is not there */
|
|
if (H5_addr_defined(f->shared->fs_addr[fs_type]))
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fapl2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support persistent free-space manager");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
H5Pclose(fcpl);
|
|
H5Pclose(fapl2);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_fs_gone() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* Verify that free-space persist with combinations of
|
|
* file space strategy and free space threshold as specified.
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_strat_thres_persist(const char *env_h5_drvr, hid_t fapl, bool new_format)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list template */
|
|
hid_t fapl2 = H5I_INVALID_HID; /* File access property list template */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FD_mem_t type; /* File allocation type */
|
|
H5FD_mem_t tt; /* File allocation type */
|
|
haddr_t addr1, addr2, addr3, addr4, addr5, addr6; /* File address for H5FD_MEM_SUPER */
|
|
H5F_fspace_strategy_t fs_type; /* File space handling strategy */
|
|
hsize_t fs_threshold; /* Free-space section threshold */
|
|
unsigned fs_persist; /* To persist free-space or not */
|
|
bool contig_addr_vfd;
|
|
|
|
if (new_format)
|
|
TESTING("File space strategy/persisting/threshold with new library format");
|
|
else
|
|
TESTING("File space strategy/persisting/threshold with old library format");
|
|
|
|
/* Current VFD that does not support contiguous address space */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Copy the file access property list */
|
|
if ((fapl2 = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (new_format)
|
|
if (H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test with true or false for persisting free-space */
|
|
for (fs_persist = false; fs_persist <= true; fs_persist++) {
|
|
|
|
for (fs_threshold = 0; fs_threshold <= TEST_THRESHOLD10; fs_threshold++) {
|
|
|
|
/* Testing for H5F_FSPACE_STRATEGY_FSM_AGGR and H5F_FSPACE_STRATEGY_PAGE strategies only */
|
|
for (fs_type = H5F_FSPACE_STRATEGY_FSM_AGGR; fs_type < H5F_FSPACE_STRATEGY_AGGR; fs_type++) {
|
|
|
|
if (!contig_addr_vfd && (fs_persist || fs_type == H5F_FSPACE_STRATEGY_PAGE))
|
|
continue;
|
|
|
|
/* Create file-creation template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set default file space information */
|
|
if (H5Pset_file_space_strategy(fcpl, fs_type, (bool)fs_persist, fs_threshold) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 6 blocks */
|
|
type = H5FD_MEM_SUPER;
|
|
if (HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr5 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE5)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr6 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE6)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #1, #3, #5 to H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, type, addr5, (hsize_t)TBLOCK_SIZE5) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__alloc_to_fs_type(f->shared, type, TBLOCK_SIZE6, (H5F_mem_page_t *)&tt);
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (f->shared->fs_persist) {
|
|
hssize_t nsects; /* # of free-space sections */
|
|
int i; /* local index variable */
|
|
H5F_sect_info_t *sect_info; /* array to hold the free-space information */
|
|
|
|
/* Get the # of free-space sections in the file */
|
|
if ((nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)0, NULL)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify no free-space sections */
|
|
/* paged aggregation has 1 section for last_small */
|
|
if (fs_threshold > TBLOCK_SIZE5 && nsects && fs_type != H5F_FSPACE_STRATEGY_PAGE)
|
|
TEST_ERROR;
|
|
|
|
if (nsects) {
|
|
/* Allocate storage for the free space section information */
|
|
sect_info = (H5F_sect_info_t *)calloc((size_t)nsects, sizeof(H5F_sect_info_t));
|
|
|
|
H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)nsects, sect_info);
|
|
|
|
/* Verify the size of free-space sections */
|
|
for (i = 0; i < nsects; i++)
|
|
if (sect_info[i].size < fs_threshold)
|
|
TEST_ERROR;
|
|
if (sect_info)
|
|
free(sect_info);
|
|
}
|
|
}
|
|
else {
|
|
if (H5_addr_defined(f->shared->fs_addr[tt]))
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* Closing */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
} /* end for fs_type */
|
|
} /* end for fs_threshold */
|
|
} /* end for fs_persist */
|
|
|
|
if (H5Pclose(fapl2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fcpl);
|
|
H5Pclose(fapl2);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_strat_thres_persist() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* Verify free-space are merged/shrunk away with file space settings:
|
|
* --strategy, persist/not persist file space
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_mf_strat_thres_gone(const char *env_h5_drvr, hid_t fapl, bool new_format)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list template */
|
|
hid_t fapl2 = H5I_INVALID_HID; /* File access property list template */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FD_mem_t type; /* File allocation type */
|
|
H5FD_mem_t tt; /* File allocation type */
|
|
haddr_t addr1, addr2, addr3, addr4, addr5, addr6; /* File address for H5FD_MEM_SUPER */
|
|
H5F_fspace_strategy_t fs_type; /* File space handling strategy */
|
|
unsigned fs_persist; /* To persist free-space or not */
|
|
H5FS_stat_t fs_state; /* Information for free-space manager */
|
|
H5FS_stat_t fs_state_zero; /* Information for free-space manager */
|
|
bool contig_addr_vfd;
|
|
|
|
if (new_format)
|
|
TESTING("File space merge/shrink for section size < threshold with new library format");
|
|
else
|
|
TESTING("File space merge/shrink for section size < threshold with old library format");
|
|
|
|
/* Current VFD that does not support contiguous address space */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
memset(&fs_state_zero, 0, sizeof(H5FS_stat_t));
|
|
|
|
/* Copy the file access property list */
|
|
if ((fapl2 = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (new_format)
|
|
if (H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test with true or false for persisting free-space */
|
|
for (fs_persist = false; fs_persist <= true; fs_persist++) {
|
|
/* Testing for H5F_FSPACE_STRATEGY_FSM_AGGR and H5F_FSPACE_STRATEGY_PAGE strategies only */
|
|
for (fs_type = H5F_FSPACE_STRATEGY_FSM_AGGR; fs_type < H5F_FSPACE_STRATEGY_AGGR; fs_type++) {
|
|
|
|
/* Skip for multi/split driver: persisting free-space or paged aggregation strategy */
|
|
if (!contig_addr_vfd && (fs_persist || fs_type == H5F_FSPACE_STRATEGY_PAGE))
|
|
continue;
|
|
|
|
/* Clear out free-space statistics */
|
|
memset(&fs_state, 0, sizeof(H5FS_stat_t));
|
|
|
|
/* Create file-creation template */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set default file space information */
|
|
if (H5Pset_file_space_strategy(fcpl, fs_type, fs_persist, (hsize_t)TEST_THRESHOLD3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 6 blocks */
|
|
type = H5FD_MEM_SUPER;
|
|
if (HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE1)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE2)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE3)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE4)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr5 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE5)))
|
|
FAIL_STACK_ERROR;
|
|
if (HADDR_UNDEF == (addr6 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE6)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5MF__alloc_to_fs_type(f->shared, type, TBLOCK_SIZE6, (H5F_mem_page_t *)&tt);
|
|
|
|
/* For paged aggregation, the section in the page at EOF for small meta fs is not shrunk away */
|
|
if (fs_type == H5F_FSPACE_STRATEGY_PAGE)
|
|
if (H5FS_stat_info(f, f->shared->fs_man[tt], &fs_state) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Put block #3, #5 to H5FD_MEM_SUPER free-space manager */
|
|
if (H5MF_xfree(f, type, addr3, (hsize_t)TBLOCK_SIZE3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5MF_xfree(f, type, addr5, (hsize_t)TBLOCK_SIZE5) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
fs_state.tot_space += TBLOCK_SIZE3 + TBLOCK_SIZE5;
|
|
fs_state.tot_sect_count += 2;
|
|
fs_state.serial_sect_count += 2;
|
|
|
|
if (check_stats(f, f->shared->fs_man[tt], &fs_state))
|
|
TEST_ERROR;
|
|
|
|
/* section #2 is less than threshold but is merged into section #3 */
|
|
if (H5MF_xfree(f, type, addr2, (hsize_t)TBLOCK_SIZE2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
fs_state.tot_space += TBLOCK_SIZE2;
|
|
if (check_stats(f, f->shared->fs_man[tt], &fs_state))
|
|
TEST_ERROR;
|
|
|
|
if (H5MF_xfree(f, type, addr4, (hsize_t)TBLOCK_SIZE4) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5MF_xfree(f, type, addr6, (hsize_t)TBLOCK_SIZE6) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* For paged aggregation, the sections in the page at EOF for small meta fs are merged but are not
|
|
* shrunk away */
|
|
if (fs_type == H5F_FSPACE_STRATEGY_PAGE) {
|
|
fs_state.tot_sect_count = fs_state.serial_sect_count = 1;
|
|
fs_state.tot_space += (TBLOCK_SIZE4 + TBLOCK_SIZE6);
|
|
}
|
|
|
|
/* For old format: the sections at EOF are shrunk away */
|
|
if (check_stats(f, f->shared->fs_man[tt],
|
|
(fs_type == H5F_FSPACE_STRATEGY_PAGE) ? &fs_state : &fs_state_zero))
|
|
TEST_ERROR;
|
|
|
|
/* section #1 is less than threshold but is shrunk away */
|
|
if (H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* For paged aggregation, the section in the page at EOF for small meta fs is not shrunk away */
|
|
if (fs_type == H5F_FSPACE_STRATEGY_PAGE)
|
|
fs_state.tot_space += TBLOCK_SIZE1;
|
|
|
|
/* For old format: the sections at EOF are shrunk away */
|
|
if (check_stats(f, f->shared->fs_man[tt],
|
|
(fs_type == H5F_FSPACE_STRATEGY_PAGE) ? &fs_state : &fs_state_zero))
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open the file */
|
|
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Free-space manager should be empty */
|
|
if (!(fs_type == H5F_FSPACE_STRATEGY_PAGE && fs_persist))
|
|
if (H5_addr_defined(f->shared->fs_addr[tt]))
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
} /* end for fs_type */
|
|
} /* end for fs_persist */
|
|
|
|
if (H5Pclose(fapl2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fcpl);
|
|
H5Pclose(fapl2);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_mf_strat_thres_gone() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* 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(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* 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, addr3, saddr1, saddr2;
|
|
|
|
TESTING("Allocation from raw or metadata free-space manager");
|
|
|
|
/* 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 *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate the first block of type H5FD_MEM_SUPER */
|
|
type = H5FD_MEM_SUPER;
|
|
addr1 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Allocate the second block of type H5FD_MEM_SUPER */
|
|
H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Allocate the first block of type H5FD_MEM_DRAW */
|
|
stype = H5FD_MEM_DRAW;
|
|
saddr1 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Free the first block of type H5FD_MEM_SUPER */
|
|
H5MF_xfree(f, type, addr1, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Allocate the second block of type H5FD_MEM_DRAW */
|
|
saddr2 = H5MF_alloc(f, stype, (hsize_t)TBLOCK_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, saddr1, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Allocate the third block of type H5FD_MEM_SUPER */
|
|
addr3 = H5MF_alloc(f, type, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
/* Verify that addr3 is not saddr1 */
|
|
if (addr3 == saddr1)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
} /* test_dichotomy() */
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
* set_multi_split():
|
|
* Internal routine to set up page-aligned address space for multi/split driver
|
|
* when testing paged aggregation.
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static int
|
|
set_multi_split(hid_t fapl, hsize_t pagesize, bool is_multi_or_split)
|
|
{
|
|
H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
|
|
hid_t memb_fapl_arr[H5FD_MEM_NTYPES];
|
|
char *memb_name[H5FD_MEM_NTYPES];
|
|
haddr_t memb_addr[H5FD_MEM_NTYPES];
|
|
bool relax;
|
|
H5FD_mem_t mt;
|
|
|
|
assert(is_multi_or_split);
|
|
|
|
memset(memb_name, 0, sizeof memb_name);
|
|
|
|
/* Get current split settings */
|
|
if (H5Pget_fapl_multi(fapl, memb_map, memb_fapl_arr, memb_name, memb_addr, &relax) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (is_multi_or_split) {
|
|
/* Set memb_addr aligned */
|
|
memb_addr[H5FD_MEM_SUPER] = ((memb_addr[H5FD_MEM_SUPER] + pagesize - 1) / pagesize) * pagesize;
|
|
memb_addr[H5FD_MEM_DRAW] = ((memb_addr[H5FD_MEM_DRAW] + pagesize - 1) / pagesize) * pagesize;
|
|
}
|
|
else {
|
|
/* Set memb_addr aligned */
|
|
for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++)
|
|
memb_addr[mt] = ((memb_addr[mt] + pagesize - 1) / pagesize) * pagesize;
|
|
} /* end else */
|
|
|
|
/* Set multi driver with new FAPLs */
|
|
if (H5Pset_fapl_multi(fapl, memb_map, memb_fapl_arr, (const char *const *)memb_name, memb_addr, relax) <
|
|
0)
|
|
TEST_ERROR;
|
|
|
|
/* Free memb_name */
|
|
for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++)
|
|
free(memb_name[mt]);
|
|
|
|
return 0;
|
|
|
|
error:
|
|
return (-1);
|
|
} /* set_multi_split() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_page_alloc_xfree
|
|
*
|
|
* Purpose: To verify allocations and de-allocations for large/small
|
|
* sections are done properly when paged aggregation is enabled.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: number of errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_page_alloc_xfree(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list */
|
|
hid_t fapl_new = H5I_INVALID_HID; /* File access property list ID */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
haddr_t addr2, addr3; /* Addresses for small metadata blocks */
|
|
haddr_t saddr1; /* Addresses for small raw data blocks */
|
|
haddr_t gaddr1; /* Addresses for large data blocks */
|
|
bool split = false, multi = false;
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
haddr_t found_addr; /* Address of the found section */
|
|
unsigned fs_persist; /* To persist free-space or not */
|
|
|
|
TESTING("Paged aggregation for file space: H5MF_alloc/H5MF_xfree");
|
|
|
|
/* Check for split or multi driver */
|
|
if (!strcmp(env_h5_drvr, "split"))
|
|
split = true;
|
|
else if (!strcmp(env_h5_drvr, "multi"))
|
|
multi = true;
|
|
|
|
if (!multi && !split) {
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if ((fapl_new = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (multi || split)
|
|
if (set_multi_split(fapl_new, 4096, split) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Test with true or false for persisting free-space */
|
|
for (fs_persist = false; fs_persist <= true; fs_persist++) {
|
|
H5F_mem_page_t fs_type;
|
|
|
|
/* File creation property list */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set the strategy to paged aggregation */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, fs_persist, (hsize_t)1) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 3 small metadata blocks: addr1, addr2, addr3 */
|
|
H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE30);
|
|
addr2 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE1034);
|
|
addr3 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Free the block with addr2 */
|
|
H5MF_xfree(f, H5FD_MEM_OHDR, addr2, (hsize_t)TBLOCK_SIZE1034);
|
|
|
|
if (!fs_persist) {
|
|
H5MF__alloc_to_fs_type(f->shared, H5FD_MEM_OHDR, TBLOCK_SIZE1034, (H5F_mem_page_t *)&fs_type);
|
|
|
|
/* Verify that the freed block with addr2 is found from the small metadata manager */
|
|
if (H5MF__find_sect(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE1034, f->shared->fs_man[fs_type],
|
|
&found_addr) < 0)
|
|
TEST_ERROR;
|
|
if (found_addr != addr2)
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
|
|
/* Allocate 2 small raw data blocks: saddr1, saddr2 */
|
|
saddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE1034);
|
|
|
|
/* Free the block with saddr1 */
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, saddr1, (hsize_t)TBLOCK_SIZE30);
|
|
|
|
if (!fs_persist) {
|
|
/* Verify that the freed block with saddr1 is found from the small raw data manager */
|
|
if (H5MF__find_sect(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE30,
|
|
f->shared->fs_man[H5F_MEM_PAGE_DRAW], &found_addr) < 0)
|
|
TEST_ERROR;
|
|
if (found_addr != saddr1)
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
|
|
/* Allocate 2 large data blocks: gaddr1, gaddr2 */
|
|
gaddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE5000);
|
|
H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE8000);
|
|
|
|
/* Free the block with gaddr1 */
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, gaddr1, (hsize_t)TBLOCK_SIZE5000);
|
|
|
|
if (!fs_persist) {
|
|
H5MF__alloc_to_fs_type(f->shared, H5FD_MEM_DRAW, TBLOCK_SIZE5000, (H5F_mem_page_t *)&fs_type);
|
|
|
|
/* Verify that the freed block with gaddr1 is found from the large data manager */
|
|
if (H5MF__find_sect(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE8192, f->shared->fs_man[fs_type],
|
|
&found_addr) < 0)
|
|
TEST_ERROR;
|
|
if (found_addr != gaddr1)
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fcpl) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (fs_persist) {
|
|
haddr_t prv_tag = HADDR_UNDEF;
|
|
|
|
/* Re-open the file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
TEST_ERROR;
|
|
|
|
/* Set the freespace tag for the metadata cache */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, &prv_tag);
|
|
|
|
/* Verify that the large generic manager is there */
|
|
H5MF__alloc_to_fs_type(f->shared, H5FD_MEM_DRAW, TBLOCK_SIZE5000, (H5F_mem_page_t *)&fs_type);
|
|
if (!H5_addr_defined(f->shared->fs_addr[fs_type]))
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the small metadata manager is there */
|
|
H5MF__alloc_to_fs_type(f->shared, H5FD_MEM_OHDR, f->shared->fs_page_size - 1,
|
|
(H5F_mem_page_t *)&fs_type);
|
|
if (!H5_addr_defined(f->shared->fs_addr[fs_type]))
|
|
TEST_ERROR;
|
|
|
|
/* Set up to use the small metadata manager */
|
|
if (!(f->shared->fs_man[fs_type]))
|
|
if (H5MF__open_fstype(f, fs_type) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the freed block with addr2 is found from the small metadata manager */
|
|
if (H5MF__find_sect(f, H5FD_MEM_OHDR,
|
|
(hsize_t)(f->shared->fs_page_size - (addr3 + TBLOCK_SIZE50)),
|
|
f->shared->fs_man[fs_type], &found_addr) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (found_addr != (addr3 + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the small raw data manager is there */
|
|
if (!H5_addr_defined(f->shared->fs_addr[H5F_MEM_PAGE_DRAW]))
|
|
TEST_ERROR;
|
|
|
|
/* Set up to use the small raw data manager */
|
|
if (!(f->shared->fs_man[H5F_MEM_PAGE_DRAW]))
|
|
if (H5MF__open_fstype(f, H5F_MEM_PAGE_DRAW) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the freed block with saddr1 is found from the small raw data manager */
|
|
if (H5MF__find_sect(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE30,
|
|
f->shared->fs_man[H5F_MEM_PAGE_DRAW], &found_addr) < 0)
|
|
TEST_ERROR;
|
|
if (found_addr != saddr1)
|
|
TEST_ERROR;
|
|
|
|
H5MF__alloc_to_fs_type(f->shared, H5FD_MEM_DRAW, TBLOCK_SIZE5000, (H5F_mem_page_t *)&fs_type);
|
|
|
|
if (!(f->shared->fs_man[fs_type]))
|
|
/* Set up to use the large data manager */
|
|
if (H5MF__open_fstype(f, fs_type) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that the freed block with gaddr1 is found from the large data manager */
|
|
if (H5MF__find_sect(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE8192, f->shared->fs_man[fs_type],
|
|
&found_addr) < 0)
|
|
TEST_ERROR;
|
|
if (found_addr != gaddr1)
|
|
TEST_ERROR;
|
|
|
|
/* Reset the previous tag */
|
|
H5AC_tag(prv_tag, NULL);
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
TEST_ERROR;
|
|
} /* end if fs_persist */
|
|
} /* end for */
|
|
|
|
if (H5Pclose(fapl_new) < 0)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support persisting free-space or paged aggregation strategy");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
H5Pclose(fcpl);
|
|
H5Pclose(fapl_new);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
|
|
} /* test_page_alloc_xfree() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_page_try_shrink
|
|
*
|
|
* Purpose: To verify that shrinking via H5MF_try_shrink() work properly
|
|
* when paged aggregation is enabled.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: number of errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_page_try_shrink(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
haddr_t addr1; /* Address for small metadata block */
|
|
haddr_t saddr1; /* Address for small raw data block */
|
|
haddr_t gaddr1; /* Address for large data block */
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
htri_t status; /* status from shrinking */
|
|
h5_stat_size_t file_size; /* File size */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
|
|
TESTING("Paged aggregation for file space: H5MF_try_shrink()");
|
|
|
|
/* Current VFD that does not support continuous address space */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
|
|
if (contig_addr_vfd) {
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* File creation property list */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the strategy to paged aggregation */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate a small metadata block with addr1 */
|
|
addr1 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Try to shrink the block with addr1 */
|
|
if ((status = H5MF_try_shrink(f, H5FD_MEM_OHDR, addr1, (hsize_t)TBLOCK_SIZE50)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Couldn't shrink due to the section (remaining space in the page) is in the small metadata
|
|
* free-space manager */
|
|
if (status == true)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a small raw data block with saddr1 */
|
|
saddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Try to shrink the block with saddr1 */
|
|
if ((status = H5MF_try_shrink(f, H5FD_MEM_DRAW, saddr1, (hsize_t)TBLOCK_SIZE50)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Couldn't shrink due to the section (remaining space in the page) is in the small raw data
|
|
* free-space manager */
|
|
if (status == true)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr1 */
|
|
gaddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE5000);
|
|
|
|
/* Try to shrink the block with gaddr1 */
|
|
if ((status = H5MF_try_shrink(f, H5FD_MEM_DRAW, gaddr1, (hsize_t)TBLOCK_SIZE5000)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Couldn't shrink due to the section (remaining space in the page) is in the large-sized free-space
|
|
* manager */
|
|
if (status == true)
|
|
TEST_ERROR;
|
|
|
|
/* Free the block with saddr1--merge to become 1 page, then return to the large manager */
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, saddr1, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Merge all 3 sections and shrunk */
|
|
H5MF_xfree(f, H5FD_MEM_OHDR, gaddr1, (hsize_t)TBLOCK_SIZE5000);
|
|
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Should be on page boundary */
|
|
if (file_size % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support paged aggregation");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
H5Pclose(fcpl);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
|
|
} /* test_page_try_shrink() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_page_small_try_extend
|
|
*
|
|
* Purpose: To verify that extending a small block via H5MF_try_extend() works
|
|
* properly when paged aggregation is enabled.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: number of errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_page_small_try_extend(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
haddr_t addr1, addr2, addr3; /* Addresses for small metadata blocks */
|
|
haddr_t saddr1; /* Address for small raw data block */
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
htri_t was_extended; /* Whether the block can be extended or not */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
|
|
TESTING("Paged aggregation for file space: H5MF_try_extend() a small block");
|
|
|
|
/* Current VFD that does not support continuous address space */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 &&
|
|
strcmp(env_h5_drvr, "family") != 0);
|
|
|
|
if (contig_addr_vfd) {
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* File creation property list */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the strategy to paged aggregation */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate a small metadata block with addr1 */
|
|
addr1 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE98);
|
|
|
|
/* Try extending the block with addr1 at EOF not crossing page boundary */
|
|
was_extended =
|
|
H5MF_try_extend(f, H5FD_MEM_OHDR, (haddr_t)addr1, (hsize_t)TBLOCK_SIZE98, (hsize_t)3100);
|
|
/* Should succeed */
|
|
if (was_extended != true)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 2 small metadata blocks with addr2 and addr3--will be on another metadata page */
|
|
addr2 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE100);
|
|
addr3 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE150);
|
|
|
|
/* The block with addr2 should be page aligned */
|
|
/* The block with addr3 resides right next to the block with addr2 */
|
|
if (addr2 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
if (addr3 != (addr2 + TBLOCK_SIZE100))
|
|
TEST_ERROR;
|
|
|
|
/* Free the block with addr2 */
|
|
H5MF_xfree(f, H5FD_MEM_OHDR, addr2, (hsize_t)TBLOCK_SIZE100);
|
|
|
|
/* Try extending the block with addr1 that will cross to the next page where the freed block with
|
|
* addr2 resides */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_OHDR, (haddr_t)addr1, (hsize_t)TBLOCK_SIZE3198,
|
|
(hsize_t)TBLOCK_SIZE100);
|
|
/* Shouldn't succeed--should not cross page boundary */
|
|
if (was_extended == true)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the block with addr1 into the free-space section that is big enough to fulfill the
|
|
* request */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_OHDR, (haddr_t)addr1, (hsize_t)TBLOCK_SIZE3198,
|
|
(hsize_t)TBLOCK_SIZE50);
|
|
/* Should succeed */
|
|
if (was_extended != true)
|
|
TEST_ERROR;
|
|
|
|
/* Free the block with addr1 */
|
|
H5MF_xfree(f, H5FD_MEM_OHDR, addr1, (hsize_t)TBLOCK_SIZE3248);
|
|
|
|
/* Allocate a new metadata block with addr1 */
|
|
/* There is a page end threshold of size H5F_FILE_SPACE_PGEND_META_THRES at the end of the block */
|
|
/* The block is right next to the threshold */
|
|
addr1 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE3286);
|
|
|
|
/* Try extending the block into the threshold with size > H5F_FILE_SPACE_PGEND_META_THRES */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_OHDR, (haddr_t)addr1, (hsize_t)TBLOCK_SIZE3286,
|
|
(hsize_t)TBLOCK_SIZE11);
|
|
/* Shouldn't succeed */
|
|
if (was_extended == true)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the block into the threshold with size < H5F_FILE_SPACE_PGEND_META_THRES */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_OHDR, (haddr_t)addr1, (hsize_t)TBLOCK_SIZE3286,
|
|
(hsize_t)TBLOCK_SIZE2);
|
|
/* Should succeed */
|
|
if (was_extended != true)
|
|
TEST_ERROR;
|
|
|
|
/* Free the block with addr3--will merge with the remaining sections to become a page and then free
|
|
* the page */
|
|
H5MF_xfree(f, H5FD_MEM_OHDR, addr3, (hsize_t)TBLOCK_SIZE150);
|
|
|
|
/* Allocate a small raw data block with saddr1 */
|
|
saddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE4086);
|
|
|
|
/* Try extending the block crossing the page boundary */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)saddr1, (hsize_t)TBLOCK_SIZE4086,
|
|
(hsize_t)TBLOCK_SIZE11);
|
|
/* Shouldn't succeed */
|
|
if (was_extended == true)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the block not crossing page boundary */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)saddr1, (hsize_t)TBLOCK_SIZE4086,
|
|
(hsize_t)TBLOCK_SIZE10);
|
|
/* Should succeed */
|
|
if (was_extended != true)
|
|
TEST_ERROR;
|
|
|
|
/* The extended block is now "large" in size */
|
|
/* Try extending the block */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)saddr1, (hsize_t)TBLOCK_SIZE4096,
|
|
(hsize_t)TBLOCK_SIZE10);
|
|
/* Should succeed */
|
|
if (was_extended != true)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the large-sized block */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)saddr1, (hsize_t)TBLOCK_SIZE4106,
|
|
(hsize_t)TBLOCK_SIZE5000);
|
|
/* Should not succeed because the mis-aligned fragment in the page is in the large-sized free-space
|
|
* manager */
|
|
if (was_extended == true)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support paged aggregation");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
H5Pclose(fcpl);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
|
|
} /* test_page_small_try_extend() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_page_large_try_extend
|
|
*
|
|
* Purpose: To verify that extending a large block via H5MF_try_extend()
|
|
* is done properly when paged aggregation is enabled.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: number of errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_page_large_try_extend(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
haddr_t gaddr1, gaddr2, gaddr3, gaddr4; /* Addresses for large data blocks */
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
htri_t was_extended; /* Whether the block can be extended or not */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
|
|
TESTING("Paged aggregation for file space: H5MF_try_extend() a large block");
|
|
|
|
/* Current VFD that does not support continuous address space */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
|
|
if (contig_addr_vfd) {
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* File creation property list */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the strategy to paged aggregation */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr1 */
|
|
gaddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)6000);
|
|
|
|
/* Should be page aligned */
|
|
if (gaddr1 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Extending the block with gaddr1 at EOF to become 2 pages */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)gaddr1, (hsize_t)TBLOCK_SIZE6000,
|
|
(hsize_t)TBLOCK_SIZE2192);
|
|
/* Should succeed */
|
|
if (was_extended != true)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr2 */
|
|
gaddr2 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE8000);
|
|
/* Should be page aligned */
|
|
if (gaddr2 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the block with gaddr1 */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)gaddr1, (hsize_t)TBLOCK_SIZE8192,
|
|
(hsize_t)TBLOCK_SIZE50);
|
|
/* Should not succeed */
|
|
if (was_extended == true)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr3 */
|
|
gaddr3 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE8000);
|
|
/* Should be page aligned */
|
|
if (gaddr3 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the block with gaddr2--there is a free-space section big enough to fulfill the
|
|
* request */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)gaddr2, (hsize_t)TBLOCK_SIZE8000,
|
|
(hsize_t)TBLOCK_SIZE100);
|
|
/* Should succeed */
|
|
if (was_extended == false)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the block with gaddr2--there is no free-space section big enough to fulfill the
|
|
* request */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)gaddr2, (hsize_t)TBLOCK_SIZE8100,
|
|
(hsize_t)TBLOCK_SIZE100);
|
|
/* Should not succeed */
|
|
if (was_extended == true)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the block with gaddr2--there is a free-space section big enough to fulfill the
|
|
* request */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)gaddr2, (hsize_t)TBLOCK_SIZE8100,
|
|
(hsize_t)TBLOCK_SIZE90);
|
|
/* Should succeed */
|
|
if (was_extended == false)
|
|
TEST_ERROR;
|
|
|
|
/* Try extending the block with gaddr2 */
|
|
/* There is no free-space section big enough to fulfill the request (request is <
|
|
* H5F_FILE_SPACE_PGEND_META_THRES) */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)gaddr2, (hsize_t)TBLOCK_SIZE8190,
|
|
(hsize_t)TBLOCK_SIZE5);
|
|
/* Should not succeed */
|
|
if (was_extended == true)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr4 */
|
|
gaddr4 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE5000);
|
|
/* Should be page aligned */
|
|
if (gaddr4 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Free the block with gaddr3--will merge with remaining free space to become 2 pages + section (size
|
|
* 2) in previous page */
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, gaddr3, (hsize_t)TBLOCK_SIZE8000);
|
|
|
|
/* Try extending the block with gaddr2 crossing page boundary--there is free-space section big enough
|
|
* to fulfill the request */
|
|
was_extended = H5MF_try_extend(f, H5FD_MEM_DRAW, (haddr_t)gaddr2, (hsize_t)TBLOCK_SIZE8190,
|
|
(hsize_t)TBLOCK_SIZE5);
|
|
/* Should succeed */
|
|
if (was_extended == false)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support paged aggregation strategy");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
H5Pclose(fcpl);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
|
|
} /* test_page_large_try_extend() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_page_large
|
|
*
|
|
* Purpose: To verify that allocations and de-allocations for large data
|
|
* are done properly when paged aggregation is enabled.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: number of errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_page_large(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list ID */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
haddr_t gaddr1, gaddr2, gaddr3, gaddr4; /* Addresses for blocks */
|
|
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
|
|
H5FS_stat_t fs_stat; /* Information for free-space manager */
|
|
h5_stat_size_t file_size; /* File size */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
|
|
TESTING("Paged aggregation for file space: large allocations and de-allocations");
|
|
|
|
/* Current VFD that does not support continuous address space */
|
|
contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0);
|
|
|
|
if (contig_addr_vfd) {
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* File creation property list */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the strategy to paged aggregation */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr1 */
|
|
/* 1 page + 1904 bytes; 2192 bytes in free-space manager */
|
|
gaddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE6000);
|
|
|
|
/* Should be page aligned */
|
|
if (gaddr1 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr2--should be on another page */
|
|
/* Allocate 1 page + 3904 bytes; 192 bytes in free-space manager */
|
|
gaddr2 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE8000);
|
|
/* Should be page aligned */
|
|
if (gaddr2 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr3--should be on another page */
|
|
/* Allocate 2 pages + 3808 bytes; 288 bytes in free-space manager */
|
|
gaddr3 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE12000);
|
|
if (!H5_addr_defined(gaddr3))
|
|
TEST_ERROR;
|
|
|
|
/* Free the block with gaddr2 */
|
|
/* Merged sections: 2192 + 8000 + 192 = 10384 */
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, gaddr2, (hsize_t)TBLOCK_SIZE8000);
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[H5F_MEM_PAGE_GENERIC], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify that the manager contains 2 free-space sections: 10384 and 288 */
|
|
if (fs_stat.tot_sect_count != 2)
|
|
TEST_ERROR;
|
|
if (fs_stat.tot_space != (10384 + 288))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a large data block with gaddr4--there is a free-space section able to fulfill the request
|
|
*/
|
|
/* Free-space sections: 2192 + 3192 + 288 = 5672 bytes */
|
|
gaddr4 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE5000);
|
|
|
|
/* Should be page aligned */
|
|
if (gaddr4 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
if (gaddr4 != gaddr2)
|
|
TEST_ERROR;
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[H5F_MEM_PAGE_GENERIC], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Verify that that there are 3 free-space sections */
|
|
if (fs_stat.tot_sect_count != 3)
|
|
TEST_ERROR;
|
|
if (fs_stat.tot_space != (2192 + 3192 + 288))
|
|
TEST_ERROR;
|
|
|
|
/* Free the two blocks with gaddr1 and gaddr4 */
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, gaddr1, (hsize_t)TBLOCK_SIZE6000);
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, gaddr4, (hsize_t)TBLOCK_SIZE5000);
|
|
|
|
/* Get free-space info */
|
|
if (H5FS_stat_info(f, f->shared->fs_man[H5F_MEM_PAGE_GENERIC], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Verify that that there are 2 free-space sections: 16384 (4 pages) + 288 */
|
|
if (fs_stat.tot_sect_count != 2)
|
|
TEST_ERROR;
|
|
if (fs_stat.tot_space != (16384 + 288))
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of the file */
|
|
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify that file size end on a page boundary */
|
|
if (file_size % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support paged aggregation strategy");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
|
|
} /* test_page_large() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_page_small
|
|
*
|
|
* Purpose: To verify allocations and de-allocations for small meta/raw data
|
|
* are done properly when paged aggregation is enabled.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: number of errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_page_small(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
haddr_t addr2, addr3, addr4, addr5; /* Addresses for blocks */
|
|
haddr_t addr9, addr10, addr11; /* Address for small metadata blocks */
|
|
haddr_t saddr1, saddr2; /* Addresses for small raw data blocks */
|
|
H5FS_stat_t fs_stat; /* Information for free-space manager */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
bool multi = false, split = false, family = false;
|
|
|
|
TESTING("Paged aggregation for file space: small allocations and de-allocations");
|
|
|
|
if (!strcmp(env_h5_drvr, "split"))
|
|
split = true;
|
|
else if (!strcmp(env_h5_drvr, "multi"))
|
|
multi = true;
|
|
else if (!strcmp(env_h5_drvr, "family"))
|
|
family = true;
|
|
|
|
if (!multi && !split) {
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* File creation property list */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the strategy to paged aggregation */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Allocate 2 small metadata blocks: addr1, addr2 */
|
|
H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE30);
|
|
addr2 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Allocate a small raw data block with saddr1 */
|
|
saddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE30);
|
|
/* Should be on the second page and page aligned */
|
|
if (saddr1 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a small raw data block with saddr2 */
|
|
saddr2 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE50);
|
|
/* Should not be page aligned */
|
|
if (!(saddr2 % TBLOCK_SIZE4096))
|
|
TEST_ERROR;
|
|
/* Should be next to the block with saddr1 */
|
|
if (saddr2 != (saddr1 + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a small metadata block with addr3--there is no free-space section big enough to fulfill
|
|
* the request */
|
|
addr3 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE4020);
|
|
/* Should be on the third page and page aligned */
|
|
if (addr3 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a small metadata block with addr4--there is a free-space section big enough to fulfill the
|
|
* request */
|
|
addr4 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE80);
|
|
/* Should not be page aligned */
|
|
if (!(addr4 % TBLOCK_SIZE4096))
|
|
TEST_ERROR;
|
|
/* Should be next to the block with addr2 */
|
|
if (addr4 != (addr2 + TBLOCK_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a small metadata block with addr5--there is a free-space section big enough to fulfill the
|
|
* request */
|
|
addr5 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE40);
|
|
/* Should not be page aligned */
|
|
if (!(addr5 % TBLOCK_SIZE4096))
|
|
TEST_ERROR;
|
|
|
|
/* Should be next to the block with addr3 */
|
|
if (addr5 != (addr3 + TBLOCK_SIZE4020))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a small metadata block with addr6--taking up the remaining space in the first page */
|
|
if (family)
|
|
H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE3080);
|
|
else
|
|
H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE3088);
|
|
|
|
/* Allocate a small metadata block with addr7--taking up the remaining space in the third page */
|
|
H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE36);
|
|
|
|
/* Allocate 2 small metadata blocks: addr8, addr9--there is no free-space to fulfill the request */
|
|
H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE50);
|
|
addr9 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE80);
|
|
|
|
/* Free the block with saddr1 and saddr2--merge with remaining section to become a page which will be
|
|
* returned to the large manager */
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, saddr1, (hsize_t)TBLOCK_SIZE30);
|
|
H5MF_xfree(f, H5FD_MEM_DRAW, saddr2, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Verify that the large manager does contain a section with file space page size (default is 4096) */
|
|
if (!f->shared->fs_man[H5F_MEM_PAGE_GENERIC])
|
|
TEST_ERROR;
|
|
if (H5FS_stat_info(f, f->shared->fs_man[H5F_MEM_PAGE_GENERIC], &fs_stat) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (fs_stat.tot_space != TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a small metadata block with addr10--there is a free-space section big enough to fulfill
|
|
* the request */
|
|
addr10 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE3900);
|
|
/* The block should be next to the block with addr9 */
|
|
if (addr10 != (addr9 + TBLOCK_SIZE80))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a small metadata block with addr11 */
|
|
/* The current free-space section is unable to fulfill the request; obtain a page from the large
|
|
* manager */
|
|
addr11 = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)TBLOCK_SIZE80);
|
|
/* The address of the block should be the same the freed block with saddr1 */
|
|
if (addr11 != saddr1)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support paged aggregation strategy");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
H5Pclose(fcpl);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
|
|
} /* test_page_small() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_page_alignment
|
|
*
|
|
* Purpose: To verify the proper alignment is used when H5Pset_alignment()
|
|
* is set and paged aggregation is enabled.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: number of errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static unsigned
|
|
test_page_alignment(const char *env_h5_drvr, hid_t fapl)
|
|
{
|
|
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fcpl = H5I_INVALID_HID; /* File creation property list ID */
|
|
hid_t fcpl2 = H5I_INVALID_HID; /* File creation property list ID */
|
|
hid_t fapl_new = H5I_INVALID_HID; /* File access property list ID */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
haddr_t addr1, addr2; /* Addresses for small metadata blocks */
|
|
haddr_t saddr1, saddr2; /* Addresses for small raw data blocks */
|
|
haddr_t gaddr1, gaddr2; /* Addresses for blocks */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
bool split = false, multi = false;
|
|
|
|
TESTING("Paged aggregation and H5Pset_alignment: verify proper alignment is used");
|
|
|
|
/* Check for split or multi driver */
|
|
if (!strcmp(env_h5_drvr, "split"))
|
|
split = true;
|
|
else if (!strcmp(env_h5_drvr, "multi"))
|
|
multi = true;
|
|
|
|
if (!multi && !split) {
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/*
|
|
* Case 1: Verify that the alignment in use is the default file space
|
|
* page size when paged aggregation is enabled.
|
|
*/
|
|
|
|
if ((fapl_new = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* The alignment to use will be the library's default file space page size */
|
|
if (H5Pset_libver_bounds(fapl_new, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set alignment value to 16 */
|
|
if (H5Pset_alignment(fapl_new, (hsize_t)0, (hsize_t)TEST_ALIGN16) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (split || multi) {
|
|
hid_t memb_fapl;
|
|
H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
|
|
hid_t memb_fapl_arr[H5FD_MEM_NTYPES];
|
|
char *memb_name[H5FD_MEM_NTYPES];
|
|
haddr_t memb_addr[H5FD_MEM_NTYPES];
|
|
bool relax;
|
|
H5FD_mem_t mt;
|
|
|
|
/* Create fapl */
|
|
if ((memb_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set alignment */
|
|
if (H5Pset_alignment(memb_fapl, 0, (hsize_t)TEST_ALIGN16) < 0)
|
|
TEST_ERROR;
|
|
|
|
memset(memb_name, 0, sizeof memb_name);
|
|
|
|
if (split) {
|
|
/* Set split driver with new FAPLs */
|
|
if (H5Pset_fapl_split(fapl_new, "-m.h5", memb_fapl, "-r.h5", memb_fapl) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get current multi settings */
|
|
if (H5Pget_fapl_multi(fapl_new, memb_map, memb_fapl_arr, memb_name, memb_addr, &relax) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set memb_addr aligned */
|
|
memb_addr[H5FD_MEM_SUPER] =
|
|
((memb_addr[H5FD_MEM_SUPER] + TBLOCK_SIZE4096 - 1) / TBLOCK_SIZE4096) * TBLOCK_SIZE4096;
|
|
memb_addr[H5FD_MEM_DRAW] =
|
|
((memb_addr[H5FD_MEM_DRAW] + TBLOCK_SIZE4096 - 1) / TBLOCK_SIZE4096) * TBLOCK_SIZE4096;
|
|
|
|
/* Set split driver with new FAPLs */
|
|
if (H5Pset_fapl_multi(fapl_new, memb_map, memb_fapl_arr, (const char *const *)memb_name,
|
|
memb_addr, relax) < 0)
|
|
TEST_ERROR;
|
|
}
|
|
else {
|
|
/* Get current multi settings */
|
|
if (H5Pget_fapl_multi(fapl_new, memb_map, NULL, memb_name, memb_addr, &relax) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Populate memb_fapl_arr */
|
|
/* Set memb_addr aligned */
|
|
for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) {
|
|
memb_fapl_arr[mt] = memb_fapl;
|
|
memb_addr[mt] =
|
|
((memb_addr[mt] + TBLOCK_SIZE4096 - 1) / TBLOCK_SIZE4096) * TBLOCK_SIZE4096;
|
|
}
|
|
|
|
/* Set multi driver with new FAPLs */
|
|
if (H5Pset_fapl_multi(fapl_new, memb_map, memb_fapl_arr, (const char *const *)memb_name,
|
|
memb_addr, relax) < 0)
|
|
TEST_ERROR;
|
|
|
|
} /* end else */
|
|
|
|
/* Free memb_name */
|
|
for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++)
|
|
free(memb_name[mt]);
|
|
|
|
/* Close memb_fapl */
|
|
if (H5Pclose(memb_fapl) < 0)
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
|
|
/* File creation property list */
|
|
if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set the strategy to paged aggregation and persisting free space */
|
|
/* The alignment to use will be the library's default file space page size */
|
|
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, true, (hsize_t)1) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 2 small raw data blocks */
|
|
saddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE30);
|
|
saddr2 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Should be on the second page and page aligned on 4096 (default file space page size) */
|
|
if (saddr1 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Should be next to the block with saddr1 */
|
|
if (saddr2 != (saddr1 + TBLOCK_SIZE30))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 2 large raw data blocks */
|
|
gaddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE5000);
|
|
gaddr2 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE8000);
|
|
|
|
/* Should be on the 3rd page and page aligned */
|
|
if (gaddr1 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Should be on the 4th page and page aligned */
|
|
if (gaddr2 % TBLOCK_SIZE4096)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file creation property list */
|
|
if (H5Pclose(fcpl) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case 2: Verify that the alignment in use is the alignment set
|
|
* via H5Pset_alignment when paged aggregation not enabled.
|
|
*/
|
|
/* fapl_new has latest format and H5Pset_alignment set */
|
|
/* Disable small data block mechanism */
|
|
if (H5Pset_small_data_block_size(fapl_new, (hsize_t)0) < 0)
|
|
TEST_ERROR;
|
|
/* Disable metadata block mechanism */
|
|
if (H5Pset_meta_block_size(fapl_new, (hsize_t)0) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create the file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 2 small metadata blocks */
|
|
addr1 = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE30);
|
|
addr2 = H5MF_alloc(f, H5FD_MEM_SUPER, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Should be aligned on 16 */
|
|
if (addr1 % TEST_ALIGN16 || addr2 % TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
|
|
/* addr2 should be right next to the block with addr1 */
|
|
if ((addr1 + TBLOCK_SIZE30) % TEST_ALIGN16)
|
|
if (addr2 != (((addr1 + TBLOCK_SIZE30) / TEST_ALIGN16) + 1) * TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 2 small raw data blocks */
|
|
saddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE80);
|
|
saddr2 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE100);
|
|
|
|
/* Should be aligned on 16 */
|
|
if (saddr1 % TEST_ALIGN16 || saddr2 % TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
|
|
if (!multi && !split) {
|
|
/* saddr1 should be right next to the block with addr2 */
|
|
if ((addr2 + TBLOCK_SIZE50) % TEST_ALIGN16)
|
|
if (saddr1 != (((addr2 + TBLOCK_SIZE50) / TEST_ALIGN16) + 1) * TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* saddr2 should be right next to the block with saddr1 */
|
|
if ((saddr1 + TBLOCK_SIZE80) % TEST_ALIGN16)
|
|
if (saddr2 != (((saddr1 + TBLOCK_SIZE80) / TEST_ALIGN16) + 1) * TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case 3: Verify that the alignment in use is the alignment set
|
|
* via H5Pset_alignment when paged aggregation not enabled.
|
|
*/
|
|
/* File creation property list */
|
|
if ((fcpl2 = H5Pcreate(H5P_FILE_CREATE)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set file space page size */
|
|
if (H5Pset_file_space_page_size(fcpl2, (hsize_t)TBLOCK_SIZE8192) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set strategy to H5F_FSPACE_STRATEGY_AGGR but meta/raw data block is 0 as set in fapl_new */
|
|
if (H5Pset_file_space_strategy(fcpl2, H5F_FSPACE_STRATEGY_AGGR, false, (hsize_t)1) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* fapl_new has latest format, H5Pset_alignment set, and disable meta/raw block */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl2, fapl_new)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
TEST_ERROR;
|
|
|
|
/* Allocate 2 small raw data blocks */
|
|
saddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE30);
|
|
saddr2 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE50);
|
|
|
|
/* Should be aligned on 16 */
|
|
if (saddr1 % TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
if (saddr2 % TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
|
|
/* saddr2 should be right next to the block with saddr1 */
|
|
if ((saddr1 + TBLOCK_SIZE30) % TEST_ALIGN16)
|
|
if (saddr2 != (((saddr1 + TBLOCK_SIZE30) / TEST_ALIGN16) + 1) * TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
|
|
/* Allocate a large raw data block */
|
|
gaddr1 = H5MF_alloc(f, H5FD_MEM_DRAW, (hsize_t)TBLOCK_SIZE5000);
|
|
|
|
/* Should be aligned on 16 */
|
|
if (gaddr1 % TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
|
|
/* gaddr1 is right next to the block with saddr2 */
|
|
if ((saddr2 + TBLOCK_SIZE50) % TEST_ALIGN16)
|
|
if (gaddr1 != (((saddr2 + TBLOCK_SIZE50) / TEST_ALIGN16) + 1) * TEST_ALIGN16)
|
|
TEST_ERROR;
|
|
|
|
/* There is no free-space manager involved for H5F_FSPACE_STRATEGY_AGGR strategy */
|
|
if (f->shared->fs_man[H5FD_MEM_DRAW] || f->shared->fs_man[H5FD_MEM_SUPER])
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Fclose(fid) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pclose(fcpl2) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pclose(fapl_new) < 0)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
}
|
|
else {
|
|
SKIPPED();
|
|
puts(" Current VFD doesn't support persisting free-space or paged aggregation strategy");
|
|
}
|
|
|
|
return (0);
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
H5Pclose(fcpl);
|
|
H5Pclose(fapl_new);
|
|
}
|
|
H5E_END_TRY
|
|
return (1);
|
|
|
|
} /* test_page_alignment() */
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */
|
|
hid_t new_fapl = H5I_INVALID_HID; /* File access property list for alignment & aggr setting */
|
|
unsigned nerrors = 0; /* Cumulative error count */
|
|
test_type_t curr_test; /* Current test being worked on */
|
|
const char *env_h5_drvr; /* File Driver value from environment */
|
|
bool api_ctx_pushed = false; /* Whether API context pushed */
|
|
|
|
/* Get the VFD to use */
|
|
env_h5_drvr = getenv(HDF5_DRIVER);
|
|
if (env_h5_drvr == NULL)
|
|
env_h5_drvr = "nomatch";
|
|
|
|
h5_reset();
|
|
|
|
fapl = h5_fileaccess();
|
|
|
|
/* Push API context */
|
|
if (H5CX_push() < 0)
|
|
FAIL_STACK_ERROR;
|
|
api_ctx_pushed = true;
|
|
|
|
/* Make a copy of the FAPL before adjusting the alignment */
|
|
if ((new_fapl = H5Pcopy(fapl)) < 0)
|
|
TEST_ERROR;
|
|
/* For old library format--interaction with file allocation */
|
|
nerrors += test_mf_eoa(env_h5_drvr, fapl);
|
|
nerrors += test_mf_eoa_shrink(env_h5_drvr, fapl);
|
|
nerrors += test_mf_eoa_extend(env_h5_drvr, fapl);
|
|
|
|
/* For old library format */
|
|
nerrors += test_dichotomy(new_fapl);
|
|
|
|
/* For old library format--interaction with free-space manager */
|
|
nerrors += test_mf_fs_start(fapl);
|
|
nerrors += test_mf_fs_alloc_free(fapl);
|
|
nerrors += test_mf_fs_extend(fapl);
|
|
nerrors += test_mf_fs_absorb(env_h5_drvr, fapl);
|
|
|
|
/* For old library format--interaction with meta/sdata aggregator */
|
|
nerrors += test_mf_aggr_alloc1(env_h5_drvr, fapl);
|
|
nerrors += test_mf_aggr_alloc2(env_h5_drvr, fapl);
|
|
nerrors += test_mf_aggr_alloc3(env_h5_drvr, fapl);
|
|
nerrors += test_mf_aggr_alloc4(env_h5_drvr, fapl);
|
|
nerrors += test_mf_aggr_alloc5(env_h5_drvr, fapl);
|
|
nerrors += test_mf_aggr_alloc6(env_h5_drvr, fapl);
|
|
nerrors += test_mf_aggr_alloc7(env_h5_drvr, fapl);
|
|
nerrors += test_mf_aggr_extend(env_h5_drvr, fapl);
|
|
nerrors += test_mf_aggr_absorb(env_h5_drvr, fapl);
|
|
|
|
/* For old library format--tests for alignment */
|
|
for (curr_test = TEST_NORMAL; curr_test < TEST_NTESTS; curr_test++) {
|
|
|
|
switch (curr_test) {
|
|
case TEST_NORMAL: /* set alignment = 1024 */
|
|
if (H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN1024) < 0)
|
|
TEST_ERROR;
|
|
break;
|
|
|
|
case TEST_AGGR_SMALL: /* set alignment = 4096 */
|
|
if (H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN4096) < 0)
|
|
TEST_ERROR;
|
|
break;
|
|
|
|
case TEST_NTESTS:
|
|
default:
|
|
TEST_ERROR;
|
|
break;
|
|
} /* end switch */
|
|
|
|
nerrors += test_mf_align_eoa(env_h5_drvr, fapl, new_fapl);
|
|
nerrors += test_mf_align_fs(env_h5_drvr, fapl, new_fapl);
|
|
nerrors += test_mf_align_alloc1(env_h5_drvr, fapl, new_fapl);
|
|
nerrors += test_mf_align_alloc2(env_h5_drvr, fapl, new_fapl);
|
|
nerrors += test_mf_align_alloc3(env_h5_drvr, fapl, new_fapl);
|
|
nerrors += test_mf_align_alloc4(env_h5_drvr, fapl, new_fapl);
|
|
nerrors += test_mf_align_alloc5(env_h5_drvr, fapl, new_fapl);
|
|
nerrors += test_mf_align_alloc6(env_h5_drvr, fapl, new_fapl);
|
|
} /* end for */
|
|
|
|
/* For old and new format--interaction with temporary file space allocation */
|
|
nerrors += test_mf_tmp(env_h5_drvr, fapl, false);
|
|
nerrors += test_mf_tmp(env_h5_drvr, fapl, true);
|
|
|
|
/* For old and new format--free-space merge/shrunk away */
|
|
|
|
/* Temporary: modify to skip testing for multi/split driver:
|
|
fail file create when persisting free-space or using paged aggregation strategy */
|
|
nerrors += test_mf_fs_gone(env_h5_drvr, fapl, false);
|
|
nerrors += test_mf_fs_gone(env_h5_drvr, fapl, true);
|
|
|
|
/* Temporary: modify to skip testing multi/split driver:
|
|
fail file create when persisting free-space or using paged aggregation strategy */
|
|
nerrors += test_mf_strat_thres_gone(env_h5_drvr, fapl, false);
|
|
nerrors += test_mf_strat_thres_gone(env_h5_drvr, fapl, true);
|
|
|
|
/* For old and new format--persisting free-space */
|
|
|
|
/* Temporary: Modify to skip testing for multi/split driver:
|
|
fail file create when persisting free-space or using paged aggregation strategy */
|
|
nerrors += test_mf_fs_persist(env_h5_drvr, fapl, false);
|
|
nerrors += test_mf_fs_persist(env_h5_drvr, fapl, true);
|
|
|
|
/* Temporary: modify to skip testing for multi/split driver:
|
|
fail file create when persisting free-space or using paged aggregation strategy */
|
|
nerrors += test_mf_strat_thres_persist(env_h5_drvr, fapl, false);
|
|
nerrors += test_mf_strat_thres_persist(env_h5_drvr, fapl, true);
|
|
|
|
/* Temporary skipped for multi/split drivers:
|
|
fail file create when persisting free-space or using paged aggregation strategy */
|
|
#ifdef PB_OUT
|
|
/* Tests specific for multi and split files--persisting free-space */
|
|
nerrors += test_mf_fs_persist_split();
|
|
nerrors += test_mf_fs_persist_multi();
|
|
#endif
|
|
|
|
/*
|
|
* Tests specific for file space paging
|
|
*/
|
|
/* Temporary: The following 7 tests are modified to skip testing for multi/split driver:
|
|
fail file create when persisting free-space or using paged aggregation strategy */
|
|
nerrors += test_page_small(env_h5_drvr, fapl);
|
|
nerrors += test_page_large(env_h5_drvr, fapl);
|
|
nerrors += test_page_large_try_extend(env_h5_drvr, fapl);
|
|
nerrors += test_page_small_try_extend(env_h5_drvr, fapl);
|
|
nerrors += test_page_try_shrink(env_h5_drvr, fapl);
|
|
nerrors += test_page_alloc_xfree(env_h5_drvr, fapl); /* can handle multi/split */
|
|
nerrors += test_page_alignment(env_h5_drvr, fapl); /* can handle multi/split */
|
|
|
|
/* tests for specific bugs */
|
|
nerrors += test_mf_bug1(env_h5_drvr, fapl);
|
|
|
|
if (H5Pclose(new_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
h5_cleanup(FILENAME, fapl);
|
|
|
|
/* Pop API context */
|
|
if (api_ctx_pushed && H5CX_pop(false) < 0)
|
|
FAIL_STACK_ERROR;
|
|
api_ctx_pushed = false;
|
|
|
|
if (nerrors)
|
|
goto error;
|
|
puts("All free-space manager tests for file memory passed.");
|
|
|
|
return (0);
|
|
|
|
error:
|
|
puts("*** TESTS FAILED ***");
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Pclose(new_fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
if (api_ctx_pushed)
|
|
H5CX_pop(false);
|
|
|
|
return (1);
|
|
} /* main() */
|