From a3668504d93f7015661ad63c29190bceb2fd2fe4 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 12 Jun 2004 17:33:00 -0500 Subject: [svn-r8665] Purpose: Code optimization Description: Allow global heap collections to grow in size (up to a 64K limit) if they are able to. This allows them to grow to a more reasonable size than the 4K minimum size. Platforms tested: Solaris 2.7 (arabica) FreeBSD 4.10 (sleipnir) w/parallel Too minor to require h5committest --- src/H5FD.c | 767 ++++++++++++++++++++++++++++++------------------------ src/H5FDprivate.h | 4 + src/H5HG.c | 223 +++++++++++++--- src/H5MF.c | 76 ++++++ src/H5MFprivate.h | 4 + 5 files changed, 694 insertions(+), 380 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index cf9f058..fb76a9f 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -25,6 +25,10 @@ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ +/* Pablo information */ +/* (Put before include files to avoid problems with inline functions) */ +#define PABLO_MASK H5FD_mask + /* Packages needed by this file */ #include "H5private.h" /*library functions */ #include "H5Dprivate.h" /*datasets */ @@ -36,13 +40,7 @@ #include "H5MMprivate.h" /*memory management */ #include "H5Pprivate.h" /*property lists */ -#ifdef H5_HAVE_FPHDF5 -#include "H5FDfphdf5.h" /*Flexible Parallel HDF5 driver */ -#include "H5FPprivate.h" /*Flexible Parallel HDF5 */ -#endif /* H5_HAVE_FPHDF5 */ - /* Interface initialization */ -#define PABLO_MASK H5FD_mask #define INTERFACE_INIT H5FD_init_interface static int interface_initialize_g = 0; @@ -110,17 +108,16 @@ H5FD_init_interface(void) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5FD_init_interface); + FUNC_ENTER_NOAPI_NOINIT(H5FD_init_interface) - if (H5I_init_group(H5I_VFL, H5I_VFL_HASHSIZE, 0, - (H5I_free_t)H5FD_free_cls)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize interface"); + if (H5I_init_group(H5I_VFL, H5I_VFL_HASHSIZE, 0, (H5I_free_t)H5FD_free_cls)<0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize interface") /* Reset the file serial numbers */ HDmemset(file_serial_no,0,sizeof(file_serial_no)); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -149,7 +146,7 @@ H5FD_term_interface(void) { int n = 0; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_term_interface); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_term_interface) if (interface_initialize_g) { if ((n=H5I_nmembers(H5I_VFL))) { @@ -160,7 +157,7 @@ H5FD_term_interface(void) n = 1; /*H5I*/ } } - FUNC_LEAVE_NOAPI(n); + FUNC_LEAVE_NOAPI(n) } @@ -185,11 +182,11 @@ H5FD_term_interface(void) static herr_t H5FD_free_cls(H5FD_class_t *cls) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_free_cls); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_free_cls) H5MM_xfree(cls); - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } @@ -221,45 +218,42 @@ H5FDregister(const H5FD_class_t *cls) H5FD_class_t *saved=NULL; H5FD_mem_t type; - FUNC_ENTER_API(H5FDregister, FAIL); + FUNC_ENTER_API(H5FDregister, FAIL) H5TRACE1("i","x",cls); /* Check arguments */ if (!cls) - HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "null class pointer is disallowed"); - + HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "null class pointer is disallowed") if (!cls->open || !cls->close) - HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`open' and/or `close' methods are not defined"); - + HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`open' and/or `close' methods are not defined") if (!cls->get_eoa || !cls->set_eoa) - HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`get_eoa' and/or `set_eoa' methods are not defined"); - + HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`get_eoa' and/or `set_eoa' methods are not defined") if (!cls->get_eof) - HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`get_eof' method is not defined"); + HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`get_eof' method is not defined") if (!cls->read || !cls->write) - HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`read' and/or `write' method is not defined"); + HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`read' and/or `write' method is not defined") for (type=H5FD_MEM_DEFAULT; typefl_map[type]fl_map[type]>=H5FD_MEM_NTYPES) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid free-list mapping"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid free-list mapping") } /* Copy the class structure so the caller can reuse or free it */ if (NULL==(saved=H5MM_malloc(sizeof(H5FD_class_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for file driver class struct"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for file driver class struct") *saved = *cls; /* Create the new class ID */ if ((ret_value=H5I_register(H5I_VFL, saved))<0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register file driver ID"); + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register file driver ID") done: if(ret_value<0) if(saved) H5MM_xfree(saved); - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5FDregister() */ /*------------------------------------------------------------------------- @@ -286,19 +280,19 @@ H5FDunregister(hid_t driver_id) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5FDunregister, FAIL); + FUNC_ENTER_API(H5FDunregister, FAIL) H5TRACE1("e","i",driver_id); /* Check arguments */ if (NULL==H5I_object_verify(driver_id,H5I_VFL)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver") /* The H5FD_class_t struct will be freed by this function */ if (H5I_dec_ref(driver_id)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to unregister file driver"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to unregister file driver") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -336,30 +330,30 @@ H5FD_get_class(hid_t id) H5FD_class_t *ret_value=NULL; hid_t driver_id = -1; - FUNC_ENTER_NOAPI(H5FD_get_class, NULL); + FUNC_ENTER_NOAPI(H5FD_get_class, NULL) if (H5I_VFL==H5I_get_type(id)) { ret_value = H5I_object(id); } else { /* Get the plist structure */ if(NULL == (plist = H5I_object(id))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") if (TRUE==H5P_isa_class(id,H5P_FILE_ACCESS)) { if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID") ret_value = H5FD_get_class(driver_id); } else if (TRUE==H5P_isa_class(id,H5P_DATASET_XFER)) { if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID") ret_value = H5FD_get_class(driver_id); } else { - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a driver id, file access property list or data transfer property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a driver id, file access property list or data transfer property list") } } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -386,7 +380,7 @@ H5FD_sb_size(H5FD_t *file) { hsize_t ret_value=0; - FUNC_ENTER_NOAPI(H5FD_sb_size, 0); + FUNC_ENTER_NOAPI(H5FD_sb_size, 0) assert(file && file->cls); @@ -394,7 +388,7 @@ H5FD_sb_size(H5FD_t *file) ret_value = (file->cls->sb_size)(file); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -424,15 +418,15 @@ H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sb_encode, FAIL); + FUNC_ENTER_NOAPI(H5FD_sb_encode, FAIL) assert(file && file->cls); if (file->cls->sb_encode && (file->cls->sb_encode)(file, name/*out*/, buf/*out*/)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver sb_encode request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver sb_encode request failed") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -457,15 +451,15 @@ H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sb_decode, FAIL); + FUNC_ENTER_NOAPI(H5FD_sb_decode, FAIL) assert(file && file->cls); if (file->cls->sb_decode && (file->cls->sb_decode)(file, name, buf)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver sb_decode request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver sb_decode request failed") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -586,7 +580,7 @@ H5FD_fapl_get(H5FD_t *file) { void *ret_value=NULL; - FUNC_ENTER_NOAPI(H5FD_fapl_get, NULL); + FUNC_ENTER_NOAPI(H5FD_fapl_get, NULL) assert(file); @@ -594,8 +588,8 @@ H5FD_fapl_get(H5FD_t *file) ret_value = (file->cls->fapl_get)(file); done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_fapl_get() */ /*------------------------------------------------------------------------- @@ -662,7 +656,7 @@ H5FD_fapl_copy(hid_t driver_id, const void *old_fapl, void **copied_fapl) H5FD_class_t *driver=NULL; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_fapl_copy, FAIL); + FUNC_ENTER_NOAPI(H5FD_fapl_copy, FAIL) /* Check args */ if (NULL==(driver=H5I_object(driver_id))) @@ -673,7 +667,7 @@ H5FD_fapl_copy(hid_t driver_id, const void *old_fapl, void **copied_fapl) HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "can't copy driver file access property list") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -683,7 +677,6 @@ done: * Purpose: Closes a driver for a dataset transfer property list * * Return: Success: non-negative - * * Failure: negative * * Programmer: Robb Matzke @@ -712,8 +705,8 @@ H5FD_fapl_close(hid_t driver_id, void *fapl) } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_fapl_close() */ /*------------------------------------------------------------------------- @@ -780,19 +773,19 @@ H5FD_dxpl_copy(hid_t driver_id, const void *old_dxpl, void **copied_dxpl) H5FD_class_t *driver=NULL; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_dxpl_copy, FAIL); + FUNC_ENTER_NOAPI(H5FD_dxpl_copy, FAIL) /* Check args */ if (NULL==(driver=H5I_object(driver_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID") /* Copy the file access property list */ if(H5FD_pl_copy(driver->dxpl_copy,driver->dxpl_size,old_dxpl,copied_dxpl)<0) HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "can't copy driver data transfer property list") done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_dxpl_copy() */ /*------------------------------------------------------------------------- @@ -801,7 +794,6 @@ done: * Purpose: Closes a driver for a dataset transfer property list * * Return: Success: non-negative - * * Failure: negative * * Programmer: Robb Matzke @@ -830,8 +822,8 @@ H5FD_dxpl_close(hid_t driver_id, void *dxpl) } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_dxpl_close() */ /*------------------------------------------------------------------------- @@ -894,20 +886,20 @@ H5FDopen(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { H5FD_t *ret_value=NULL; - FUNC_ENTER_API(H5FDopen, NULL); + FUNC_ENTER_API(H5FDopen, NULL) /* Check arguments */ if(H5P_DEFAULT == fapl_id) fapl_id = H5P_FILE_ACCESS_DEFAULT; else if (TRUE!=H5P_isa_class(fapl_id,H5P_FILE_ACCESS)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") if (NULL==(ret_value=H5FD_open(name, flags, fapl_id, maxaddr))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to open file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to open file") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -943,60 +935,61 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) H5P_genplist_t *plist; /* Property list pointer */ H5FD_t *ret_value; - FUNC_ENTER_NOAPI(H5FD_open, NULL); + FUNC_ENTER_NOAPI(H5FD_open, NULL) /* Get file access property list */ if(NULL == (plist = H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") if (0==maxaddr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "zero format address range"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "zero format address range") if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID") /* Get driver info */ if (NULL==(driver=H5I_object(driver_id))) - HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid driver ID in file access property list"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid driver ID in file access property list") if (NULL==driver->open) - HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file driver has no `open' method"); + HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file driver has no `open' method") /* Dispatch to file driver */ if (HADDR_UNDEF==maxaddr) maxaddr = driver->maxaddr; if (NULL==(file=(driver->open)(name, flags, fapl_id, maxaddr))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed") /* * Fill in public fields. We must increment the reference count on the * driver ID to prevent it from being freed while this file is open. */ file->driver_id = driver_id; - H5I_inc_ref(file->driver_id); + if(H5I_inc_ref(file->driver_id)<0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver") file->cls = driver; file->maxaddr = maxaddr; HDmemset(file->fl, 0, sizeof(file->fl)); if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(meta_block_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get meta data block size"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get meta data block size") file->def_meta_block_size = meta_block_size; if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(sdata_block_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' block size"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' block size") file->def_sdata_block_size = sdata_block_size; file->accum_loc = HADDR_UNDEF; if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(file->threshold)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold") if(H5P_get(plist, H5F_ACS_ALIGN_NAME, &(file->alignment)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment") /* Retrieve the VFL driver feature flags */ if (H5FD_query(file, &(file->feature_flags))<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to query file driver"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to query file driver") /* Increment the global serial number & assign it to this H5FD_t object */ if(++file_serial_no[0]==0) { /* (Just error out if we wrap both numbers around for now...) */ if(++file_serial_no[1]==0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to get file serial number"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to get file serial number") } /* end if */ HDmemcpy(file->fileno,file_serial_no,sizeof(file_serial_no)); @@ -1005,7 +998,7 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) done: /* Can't cleanup 'file' information, since we don't know what type it is */ - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -1034,17 +1027,17 @@ H5FDclose(H5FD_t *file) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5FDclose, FAIL); + FUNC_ENTER_API(H5FDclose, FAIL) H5TRACE1("e","x",file); if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") if (H5FD_close(file)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to close file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to close file") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -1078,17 +1071,18 @@ H5FD_close(H5FD_t *file) const H5FD_class_t *driver; herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FD_close, FAIL); + FUNC_ENTER_NOAPI(H5FD_close, FAIL) /* check args */ assert(file && file->cls); /* Free the freelist (this call never fails) */ - H5FD_free_freelist(file); + (void)H5FD_free_freelist(file); /* Prepare to close file by clearing all public fields */ driver = file->cls; - H5I_dec_ref(file->driver_id); + if(H5I_dec_ref(file->driver_id)<0) + HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID") /* * Dispatch to the driver for actual close. If the driver fails to @@ -1097,10 +1091,10 @@ H5FD_close(H5FD_t *file) assert(driver->close); if ((driver->close)(file) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "close failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "close failed") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -1125,7 +1119,7 @@ H5FD_free_freelist(H5FD_t *file) #endif /* H5F_DEBUG */ herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FD_free_freelist, FAIL); + FUNC_ENTER_NOAPI(H5FD_free_freelist, FAIL) /* check args */ assert(file && file->cls); @@ -1170,7 +1164,7 @@ H5FD_free_freelist(H5FD_t *file) } done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -1203,13 +1197,13 @@ H5FDcmp(const H5FD_t *f1, const H5FD_t *f2) { int ret_value; - FUNC_ENTER_API(H5FDcmp, -1); /*return value is arbitrary*/ + FUNC_ENTER_API(H5FDcmp, -1) /*return value is arbitrary*/ H5TRACE2("Is","xx",f1,f2); ret_value = H5FD_cmp(f1, f2); done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -1234,32 +1228,32 @@ H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2) { int ret_value; - FUNC_ENTER_NOAPI(H5FD_cmp, -1); /*return value is arbitrary*/ + FUNC_ENTER_NOAPI(H5FD_cmp, -1) /*return value is arbitrary*/ if ((!f1 || !f1->cls) && (!f2 || !f2->cls)) - HGOTO_DONE(0); + HGOTO_DONE(0) if (!f1 || !f1->cls) - HGOTO_DONE(-1); + HGOTO_DONE(-1) if (!f2 || !f2->cls) - HGOTO_DONE(1); + HGOTO_DONE(1) if (f1->cls < f2->cls) - HGOTO_DONE(-1); + HGOTO_DONE(-1) if (f1->cls > f2->cls) - HGOTO_DONE(1); + HGOTO_DONE(1) /* Files are same driver; no cmp callback */ if (!f1->cls->cmp) { if (f1f2) - HGOTO_DONE(1); - HGOTO_DONE(0); + HGOTO_DONE(1) + HGOTO_DONE(0) } ret_value = (f1->cls->cmp)(f1, f2); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -1284,7 +1278,7 @@ H5FDquery(const H5FD_t *f, unsigned long *flags/*out*/) { int ret_value; - FUNC_ENTER_API(H5FDquery, FAIL); + FUNC_ENTER_API(H5FDquery, FAIL) H5TRACE2("Is","xx",f,flags); assert(f); @@ -1293,7 +1287,7 @@ H5FDquery(const H5FD_t *f, unsigned long *flags/*out*/) ret_value = H5FD_query(f, flags); done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -1318,7 +1312,7 @@ H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/) { int ret_value=0; - FUNC_ENTER_NOAPI(H5FD_query, FAIL); + FUNC_ENTER_NOAPI(H5FD_query, FAIL) assert(f); assert(flags); @@ -1330,7 +1324,7 @@ H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/) *flags=0; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -1380,28 +1374,28 @@ H5FDalloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) { haddr_t ret_value = HADDR_UNDEF; - FUNC_ENTER_API(H5FDalloc, HADDR_UNDEF); + FUNC_ENTER_API(H5FDalloc, HADDR_UNDEF) H5TRACE4("a","xMtih",file,type,dxpl_id,size); /* Check args */ if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer") if (type<0 || type>=H5FD_MEM_NTYPES) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid request type"); - if (size<=0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "zero-size request"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid request type") + if (size==0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "zero-size request") if (H5P_DEFAULT == dxpl_id) dxpl_id= H5P_DATASET_XFER_DEFAULT; else if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list") /* Do the real work */ if (HADDR_UNDEF==(ret_value=H5FD_alloc(file, type, dxpl_id, size))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "unable to allocate file memory"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "unable to allocate file memory") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -1409,13 +1403,6 @@ done: * Function: H5FD_alloc * Purpose: Private version of H5FDalloc(). * - * For FPHDF5, the dxpl_id is meaningless. The only place it - * is likely to be used is in the H5FD_free() function where - * it can make a call to H5FD_write() (which needs this - * property list). FPHDF5 doesn't have metadata accumulation - * turned on, so it won't ever call the H5FD_write() - * function. - * * Return: Success: The format address of the new file memory. * Failure: The undefined address HADDR_UNDEF * Programmer: Robb Matzke @@ -1427,9 +1414,6 @@ done: * Bill Wendling, 2002/12/02 * Split apart into subfunctions for each separate task. * - * Bill Wendling, 2003/02/19 - * Added support for FPHDF5. - * *------------------------------------------------------------------------- */ haddr_t @@ -1438,7 +1422,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) H5FD_mem_t mapped_type; haddr_t ret_value = HADDR_UNDEF; - FUNC_ENTER_NOAPI(H5FD_alloc, HADDR_UNDEF); + FUNC_ENTER_NOAPI(H5FD_alloc, HADDR_UNDEF) /* check args */ assert(file); @@ -1446,58 +1430,6 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) assert(type >= 0 && type < H5FD_MEM_NTYPES); assert(size > 0); -#ifdef H5_HAVE_FPHDF5 - /* - * When we're using the FPHDF5 driver, allocate from the SAP. If this - * is the SAP executing this code, then skip the send to the SAP and - * try to do the actual allocations. - */ - if (H5FD_is_fphdf5_driver(file) && !H5FD_fphdf5_is_sap(file)) { - unsigned req_id; - unsigned capt_only = 0; - H5FP_status_t status; - H5P_genplist_t *plist; - H5FP_alloc_t fp_alloc; - - /* Get the data xfer property list */ - if ((plist = H5I_object(dxpl_id)) == NULL) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, HADDR_UNDEF, "not a dataset transfer list"); - - if (H5P_exist_plist(plist, H5FD_FPHDF5_CAPTN_ALLOC_ONLY) > 0) - if (H5P_get(plist, H5FD_FPHDF5_CAPTN_ALLOC_ONLY, &capt_only) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, HADDR_UNDEF, - "can't remove FPHDF5 property"); - - /* - * If the captain is the only one who should allocate resources, - * then do just that... - */ - if (!capt_only || H5FD_fphdf5_is_captain(file)) { - /* Send the request to the SAP */ - if (H5FP_request_allocate(file, type, size, &fp_alloc.addr, - &fp_alloc.eoa, &req_id, &status) != SUCCEED) - /* FIXME: Should we check the "status" variable here? */ - HGOTO_ERROR(H5E_FPHDF5, H5E_CANTALLOC, HADDR_UNDEF, - "server couldn't allocate from file"); - } - - if (capt_only) { - int mrc; - - if ((mrc = MPI_Bcast(&fp_alloc, 1, H5FP_alloc, - (int)H5FP_capt_barrier_rank, - H5FP_SAP_BARRIER_COMM)) != MPI_SUCCESS) - HMPI_GOTO_ERROR(HADDR_UNDEF, "MPI_Bcast failed", mrc); - } - - - /* Set the EOA for all processes. This doesn't fail. */ - file->cls->set_eoa(file, fp_alloc.eoa); - - /* We've succeeded -- return the value */ - HGOTO_DONE(fp_alloc.addr); - } -#endif /* H5_HAVE_FPHDF5 */ #ifdef H5F_DEBUG if (H5DEBUG(F)) @@ -1514,7 +1446,7 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) /* Try to allocate from the free list first */ if ((ret_value = H5FD_alloc_from_free_list(file, type, mapped_type, size)) != HADDR_UNDEF) - HGOTO_DONE(ret_value); + HGOTO_DONE(ret_value) #ifdef H5F_DEBUG if (H5DEBUG(F)) @@ -1524,15 +1456,15 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) if (type != H5FD_MEM_DRAW) { /* Handle metadata differently from "raw" data */ if ((ret_value = H5FD_alloc_metadata(file, type, dxpl_id, size)) == HADDR_UNDEF) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't allocate for metadata"); + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't allocate for metadata") } else { /* Allocate "raw" data */ if ((ret_value = H5FD_alloc_raw(file, type, dxpl_id, size)) == HADDR_UNDEF) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't allocate for raw data"); + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't allocate for raw data") } done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -1555,7 +1487,7 @@ H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type, { haddr_t ret_value = HADDR_UNDEF; - FUNC_ENTER_NOAPI(H5FD_alloc_from_free_list, HADDR_UNDEF); + FUNC_ENTER_NOAPI(H5FD_alloc_from_free_list, HADDR_UNDEF) assert(file); assert(type >= 0 && type < H5FD_MEM_NTYPES); @@ -1622,7 +1554,7 @@ H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type, if (size == file->maxsize) file->maxsize = 0; /*unknown*/ - HGOTO_DONE(ret_value); + HGOTO_DONE(ret_value) } } @@ -1676,7 +1608,7 @@ H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type, if (size == file->maxsize) file->maxsize = 0; /*unknown*/ - HGOTO_DONE(ret_value); + HGOTO_DONE(ret_value) } } else { if (cur->size > size && (!best || cur->size < best->size)) @@ -1710,7 +1642,7 @@ H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type, } else { best->addr += size; /* Reduce size of block on free list */ best->size -= size; - HGOTO_DONE(ret_value); + HGOTO_DONE(ret_value) } } else { /* @@ -1729,48 +1661,31 @@ H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type, */ if (type == H5FD_MEM_DRAW && (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && - H5F_addr_overlap(ret_value, size, file->accum_loc, - file->accum_size)) { + H5F_addr_overlap(ret_value, size, file->accum_loc, file->accum_size)) { ret_value = HADDR_UNDEF; } else { /* Attempt to allocate memory for temporary node */ - tmp = H5FL_MALLOC(H5FD_free_t); + if((tmp = H5FL_MALLOC(H5FD_free_t))==NULL) + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "free block allocation failed") -#ifdef H5F_DEBUG - if (H5DEBUG(F)) - HDfprintf(H5DEBUG(F), - "%s: 3 pieces, begin best->addr=%a, best->size=%Hd, " - "head=%Hd, size=%Hd\n", - FUNC, best->addr, best->size, head, size); -#endif /* H5F_DEBUG */ - - assert(tmp); /* bark in debug mode */ - - if (tmp) { - if ((tmp->size = (best->size - head - size))) { - tmp->addr = best->addr + head + size; - tmp->next = best->next; - best->next = tmp; - } else { - /* no tail piece */ - H5FL_FREE(H5FD_free_t,tmp); - } + if ((tmp->size = (best->size - (head + size)))) { + tmp->addr = best->addr + (head + size); + tmp->next = best->next; + best->next = tmp; } else { - /* - * Cannot keep the tail piece. Leak file memory. - * (Only happens if memory allocation fails) - */ + /* no tail piece */ + H5FL_FREE(H5FD_free_t,tmp); } best->size = head; - HGOTO_DONE(ret_value); - } - } - } - } + HGOTO_DONE(ret_value) + } /* end else */ + } /* end else */ + } /* end if */ + } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -1793,7 +1708,7 @@ H5FD_alloc_metadata(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) { haddr_t ret_value = HADDR_UNDEF; - FUNC_ENTER_NOAPI(H5FD_alloc_metadata, HADDR_UNDEF); + FUNC_ENTER_NOAPI(H5FD_alloc_metadata, HADDR_UNDEF) /* check args */ assert(file); @@ -1863,8 +1778,7 @@ H5FD_alloc_metadata(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) if (file->eoma != 0) if (H5FD_free(file, H5FD_MEM_DEFAULT, dxpl_id, file->eoma, file->cur_meta_block_size) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, - "can't free metadata block"); + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free metadata block") /* Point the metadata block at the newly allocated block */ file->eoma = new_meta; @@ -1888,7 +1802,7 @@ H5FD_alloc_metadata(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) } done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -1909,7 +1823,7 @@ H5FD_alloc_raw(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) { haddr_t ret_value = HADDR_UNDEF; - FUNC_ENTER_NOAPI(H5FD_alloc_raw, HADDR_UNDEF); + FUNC_ENTER_NOAPI(H5FD_alloc_raw, HADDR_UNDEF) /* check args */ assert(file); @@ -1971,8 +1885,7 @@ H5FD_alloc_raw(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) if (file->eosda != 0) if (H5FD_free(file, H5FD_MEM_DRAW, dxpl_id, file->eosda, file->cur_sdata_block_size) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, - "can't free 'small data' block"); + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free 'small data' block") /* * Point the "small data" block at the newly @@ -1999,7 +1912,7 @@ H5FD_alloc_raw(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) } done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -2026,7 +1939,7 @@ H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) { haddr_t ret_value = HADDR_UNDEF; - FUNC_ENTER_NOAPI_NOINIT(H5FD_real_alloc); + FUNC_ENTER_NOAPI_NOINIT(H5FD_real_alloc) /* check args */ assert(file); @@ -2040,16 +1953,14 @@ H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) */ if (file->cls->alloc) { if ((ret_value = (file->cls->alloc)(file, type, dxpl_id, size)) == HADDR_UNDEF) - HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, - "driver allocation request failed"); + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver allocation request failed") } else { if ((ret_value = H5FD_update_eoa(file, type, dxpl_id, size)) == HADDR_UNDEF) - HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, - "driver eoa update request failed"); + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver eoa update request failed") } done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_real_alloc() */ @@ -2074,7 +1985,7 @@ H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) hsize_t wasted; haddr_t ret_value = HADDR_UNDEF; - FUNC_ENTER_NOAPI_NOINIT(H5FD_update_eoa); + FUNC_ENTER_NOAPI_NOINIT(H5FD_update_eoa) /* check args */ assert(file); @@ -2103,29 +2014,29 @@ H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) /* Advance eoa to the next alignment by allocating the wasted */ if (H5F_addr_overflow(eoa, size) || eoa + wasted > file->maxaddr) - HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, - "file allocation request failed"); + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed") eoa += wasted; if (file->cls->set_eoa(file, eoa) < 0) - HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, - "file allocation request failed"); + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed") } /* allocate the aligned memory */ if (H5F_addr_overflow(eoa, size) || eoa + size > file->maxaddr) - HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed"); + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed") ret_value = eoa; eoa += size; if (file->cls->set_eoa(file, eoa) < 0) - HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed"); + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed") /* Free the wasted memory */ - if (wasted) - H5FD_free(file, type, dxpl_id, oldeoa, wasted); + if (wasted) { + if(H5FD_free(file, type, dxpl_id, oldeoa, wasted)<0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed") + } /* end if */ #ifdef H5F_DEBUG if (file->alignment * file->threshold != 1 && H5DEBUG(F)) @@ -2135,7 +2046,7 @@ H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) #endif /* H5F_DEBUG */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -2165,26 +2076,26 @@ H5FDfree(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t siz { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5FDfree, FAIL); + FUNC_ENTER_API(H5FDfree, FAIL) H5TRACE5("e","xMtiah",file,type,dxpl_id,addr,size); /* Check args */ if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") if (type<0 || type>=H5FD_MEM_NTYPES) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid request type"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid request type") if (H5P_DEFAULT == dxpl_id) dxpl_id= H5P_DATASET_XFER_DEFAULT; else if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list") /* Do the real work */ if (H5FD_free(file, type, dxpl_id, addr, size)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file deallocation request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "file deallocation request failed") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -2214,7 +2125,7 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si H5FD_mem_t mapped_type; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_free, FAIL); + FUNC_ENTER_NOAPI(H5FD_free, FAIL) /* Check args */ assert(file); @@ -2223,11 +2134,11 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si if (!H5F_addr_defined(addr) || addr>file->maxaddr || H5F_addr_overflow(addr, size) || addr+size>file->maxaddr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid region"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid region") /* Allow 0-sized free's to occur without penalty */ if(0==size) - HGOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED) /* Map request type to free list */ if (H5FD_MEM_DEFAULT==file->cls->fl_map[type]) { @@ -2294,7 +2205,7 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si /* Write out the part of the accumulator after the block to free */ /* (Use the driver's write call directly - to avoid looping back and writing to metadata accumulator) */ if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc))<0) - HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed") } /* end if */ /* Adjust the accumulator information */ @@ -2391,7 +2302,7 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si else { /* Allocate a new node to hold the free block's information */ if(NULL==(last = H5FL_MALLOC(H5FD_free_t))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate node for free space info"); + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate node for free space info") last->addr = addr; last->size = size; @@ -2410,7 +2321,7 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si eoa = file->cls->get_eoa(file); if(eoa == (last->addr+last->size)) { if(file->cls->set_eoa(file, last->addr) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed") /* Remove this free block from the list */ file->fl[mapped_type] = last->next; @@ -2421,13 +2332,13 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si } } else if (file->cls->free) { if ((file->cls->free)(file, type, dxpl_id, addr, size)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed") } else { /* leak memory */ } done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -2455,7 +2366,7 @@ H5FDrealloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsiz { haddr_t ret_value=HADDR_UNDEF; - FUNC_ENTER_API(H5FDrealloc, HADDR_UNDEF); + FUNC_ENTER_API(H5FDrealloc, HADDR_UNDEF) H5TRACE6("a","xMtiahh",file,type,dxpl_id,old_addr,old_size,new_size); /* Check args */ @@ -2463,13 +2374,13 @@ H5FDrealloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsiz dxpl_id= H5P_DATASET_XFER_DEFAULT; else if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list") if (HADDR_UNDEF==(ret_value=H5FD_realloc(file, type, dxpl_id, old_addr, old_size, new_size))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file reallocation request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file reallocation request failed") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -2499,7 +2410,7 @@ H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsi uint8_t *buf=_buf; haddr_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_realloc, HADDR_UNDEF); + FUNC_ENTER_NOAPI(H5FD_realloc, HADDR_UNDEF) if (new_size==old_size) { /*nothing to do*/ @@ -2508,16 +2419,18 @@ H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsi /* allocate memory */ assert(!H5F_addr_defined(old_addr)); if (HADDR_UNDEF==(new_addr=H5FD_alloc(file, type, dxpl_id, new_size))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed"); + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed") } else if (0==new_size) { /* free memory */ assert(H5F_addr_defined(old_addr)); - H5FD_free(file, type, dxpl_id, old_addr, old_size); + if(H5FD_free(file, type, dxpl_id, old_addr, old_size)<0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed") new_addr = HADDR_UNDEF; } else if (new_sizesizeof(size_t) and the @@ -2527,33 +2440,193 @@ H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsi * -QAK, 6/20/01 */ if (HADDR_UNDEF==(new_addr=H5FD_alloc(file, type, dxpl_id, new_size))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed"); + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed") H5_CHECK_OVERFLOW(old_size,hsize_t,size_t); if (old_size>sizeof(_buf) && NULL==(buf=H5MM_malloc((size_t)old_size))) { - H5FD_free(file, type, dxpl_id, new_addr, new_size); - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed"); + (void)H5FD_free(file, type, dxpl_id, new_addr, new_size); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed") } if (H5FD_read(file, type, dxpl_id, old_addr, (size_t)old_size, buf)<0 || H5FD_write(file, type, dxpl_id, new_addr, (size_t)old_size, buf)<0) { - H5FD_free(file, type, dxpl_id, new_addr, new_size); - H5MM_xfree(buf); - HGOTO_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, "unable to move file block"); + (void)H5FD_free(file, type, dxpl_id, new_addr, new_size); + if (buf!=_buf) + H5MM_xfree(buf); + HGOTO_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, "unable to move file block") } if (buf!=_buf) H5MM_xfree(buf); - H5FD_free(file, type, dxpl_id, old_addr, old_size); + if(H5FD_free(file, type, dxpl_id, old_addr, old_size)<0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed") } /* Set return value */ ret_value=new_addr; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- + * Function: H5FD_can_extend + * + * Purpose: Check if a block in the file can be extended. + * + * This is a simple check currently, which only checks for the + * block being at the end of the file. A more sophisticated check + * would also use the free space list to see if there is a block + * appropriately placed to accomodate the space requested. + * + * Return: Success: TRUE(1)/FALSE(0) + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Friday, June 11, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5FD_can_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t UNUSED extra_requested) +{ + haddr_t eoa; /* End of address space in the file */ + htri_t ret_value=FALSE; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_can_extend, FAIL) + + /* Retrieve the end of the address space */ + if (HADDR_UNDEF==(eoa=H5FD_get_eoa(file))) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed") + + /* Check if the block is exactly at the end of the file */ + if((addr+size)==eoa) + HGOTO_DONE(TRUE) + /* Check if block is inside the metadata or small data accumulator */ + else { + if(type!=H5FD_MEM_DRAW) { + if (file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) { + /* If the metadata block is at the end of the file, and + * the block to test adjoins the beginning of the metadata + * block, then it's extendable + */ + if (file->eoma + file->cur_meta_block_size == eoa && + (addr+size)==file->eoma) + HGOTO_DONE(TRUE) + } /* end if */ + } /* end if */ + else { + if (file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) { + /* If the small data block is at the end of the file, and + * the block to test adjoins the beginning of the small data + * block, then it's extendable + */ + if (file->eosda + file->cur_sdata_block_size == eoa && + (addr+size)==file->eosda) + HGOTO_DONE(TRUE) + } /* end if */ + } /* end else */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_can_extend() */ + + +/*------------------------------------------------------------------------- + * Function: H5FD_extend + * + * Purpose: Extend a block in the file. + * + * This is simple code currently, which only checks for the + * block being at the end of the file. A more sophisticated check + * would also use the free space list to see if there is a block + * appropriately placed to accomodate the space requested. + * + * Return: Success: TRUE(1)/FALSE(0) + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Saturday, June 12, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested) +{ + haddr_t eoa; /* End of address space in the file */ + hbool_t update_eoma=FALSE; /* Whether we need to update the eoma */ + hbool_t update_eosda=FALSE; /* Whether we need to update the eosda */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_extend, FAIL) + + /* Retrieve the end of the address space */ + if (HADDR_UNDEF==(eoa=H5FD_get_eoa(file))) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed") + + /* Check if the block is exactly at the end of the file */ + /* (Check if block is inside the metadata or small data accumulator) */ + if((addr+size)!=eoa) { + if(type!=H5FD_MEM_DRAW) { + if (file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) { + /* If the metadata block is at the end of the file, and + * the block to test adjoins the beginning of the metadata + * block, then it's extendable + */ + if (file->eoma + file->cur_meta_block_size == eoa && + (addr+size)==file->eoma) + update_eoma=TRUE; + else + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block") + } /* end if */ + else + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block") + } /* end if */ + else { + if (file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) { + /* If the small data block is at the end of the file, and + * the block to test adjoins the beginning of the small data + * block, then it's extendable + */ + if (file->eosda + file->cur_sdata_block_size == eoa && + (addr+size)==file->eosda) + update_eosda=TRUE; + else + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block") + } /* end if */ + else + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block") + } /* end else */ + } /* end else */ + + /* Check for overflowing the file */ + if (H5F_addr_overflow(eoa, extra_requested) || eoa + extra_requested > file->maxaddr) + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed") + + /* Extend the file */ + eoa += extra_requested; + if (file->cls->set_eoa(file, eoa) < 0) + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed") + + /* Update the metadata and/or small data block */ + assert(!(update_eoma && update_eosda)); + if(update_eoma) + file->eoma+=extra_requested; + if(update_eosda) + file->eosda+=extra_requested; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_extend() */ + + +/*------------------------------------------------------------------------- * Function: H5FDget_eoa * * Purpose: Returns the address of the first byte after the last @@ -2575,19 +2648,19 @@ H5FDget_eoa(H5FD_t *file) { haddr_t ret_value; - FUNC_ENTER_API(H5FDget_eoa, HADDR_UNDEF); + FUNC_ENTER_API(H5FDget_eoa, HADDR_UNDEF) H5TRACE1("a","x",file); /* Check args */ if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer") /* The real work */ if (HADDR_UNDEF==(ret_value=H5FD_get_eoa(file))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file get eoa request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file get eoa request failed") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -2612,15 +2685,15 @@ H5FD_get_eoa(H5FD_t *file) { haddr_t ret_value; - FUNC_ENTER_NOAPI(H5FD_get_eoa, HADDR_UNDEF); + FUNC_ENTER_NOAPI(H5FD_get_eoa, HADDR_UNDEF) assert(file && file->cls); /* Dispatch to driver */ if (HADDR_UNDEF==(ret_value=(file->cls->get_eoa)(file))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -2656,21 +2729,21 @@ H5FDset_eoa(H5FD_t *file, haddr_t addr) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5FDset_eoa, FAIL); + FUNC_ENTER_API(H5FDset_eoa, FAIL) H5TRACE2("e","xa",file,addr); /* Check args */ if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") if (!H5F_addr_defined(addr) || addr>file->maxaddr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid end-of-address value"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid end-of-address value") /* The real work */ if (H5FD_set_eoa(file, addr)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file set eoa request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file set eoa request failed") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -2695,17 +2768,17 @@ H5FD_set_eoa(H5FD_t *file, haddr_t addr) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_set_eoa, FAIL); + FUNC_ENTER_NOAPI(H5FD_set_eoa, FAIL) assert(file && file->cls); assert(H5F_addr_defined(addr) && addr<=file->maxaddr); /* Dispatch to driver */ if ((file->cls->set_eoa)(file, addr)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver set_eoa request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver set_eoa request failed") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -2740,19 +2813,19 @@ H5FDget_eof(H5FD_t *file) { haddr_t ret_value; - FUNC_ENTER_API(H5FDget_eof, HADDR_UNDEF); + FUNC_ENTER_API(H5FDget_eof, HADDR_UNDEF) H5TRACE1("a","x",file); /* Check arguments */ if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer") /* The real work */ if (HADDR_UNDEF==(ret_value=H5FD_get_eof(file))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file get eof request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file get eof request failed") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -2777,20 +2850,20 @@ H5FD_get_eof(H5FD_t *file) { haddr_t ret_value; - FUNC_ENTER_NOAPI(H5FD_get_eof, HADDR_UNDEF); + FUNC_ENTER_NOAPI(H5FD_get_eof, HADDR_UNDEF) assert(file && file->cls); /* Dispatch to driver */ if (file->cls->get_eof) { if (HADDR_UNDEF==(ret_value=(file->cls->get_eof)(file))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eof request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eof request failed") } else { ret_value = file->maxaddr; } done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -2821,28 +2894,28 @@ H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5FDread, FAIL); + FUNC_ENTER_API(H5FDread, FAIL) H5TRACE6("e","xMtiazx",file,type,dxpl_id,addr,size,buf); /* Check args */ if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") /* Get the default dataset transfer property list if the user didn't provide one */ if (H5P_DEFAULT == dxpl_id) dxpl_id= H5P_DATASET_XFER_DEFAULT; else if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list") if (!buf) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null result buffer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null result buffer") /* Do the real work */ if (H5FD_read(file, type, dxpl_id, addr, size, buf)<0) - HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file read request failed"); + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file read request failed") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -2872,7 +2945,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_read, FAIL); + FUNC_ENTER_NOAPI(H5FD_read, FAIL) assert(file && file->cls); assert(H5I_GENPROP_LST==H5I_get_type(dxpl_id)); @@ -2884,7 +2957,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz /* collective transfer. */ /* The no-op case */ if (0==size) - HGOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED) #endif /* H5_HAVE_PARALLEL */ /* Check if this information is in the metadata accumulator */ @@ -2908,7 +2981,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz /* Dispatch to driver */ if ((file->cls->read)(file, type, dxpl_id, addr, amount_read, read_buf)<0) - HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed"); + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed") /* Adjust the buffer, address & size */ read_buf+=amount_read; @@ -2943,7 +3016,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz if(size>0 && addr>=(file->accum_loc+file->accum_size)) { /* Dispatch to driver */ if ((file->cls->read)(file, type, dxpl_id, addr, size, read_buf)<0) - HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed"); + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed") /* Adjust the buffer, address & size */ read_buf+=size; @@ -2964,7 +3037,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz /* Flush current contents, if dirty */ if(file->accum_dirty) { if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0) - HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed") /* Reset accumulator dirty flag */ file->accum_dirty=FALSE; @@ -2975,7 +3048,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz if(size>file->accum_buf_size) { /* Grow the metadata accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ file->accum_buf_size=size; @@ -2988,7 +3061,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz /* Shrink the accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,new_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ file->accum_buf_size=new_size; @@ -3002,7 +3075,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz /* Read into accumulator */ if ((file->cls->read)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0) - HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed"); + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed") /* Copy into buffer */ HDmemcpy(buf,file->meta_accum,size); @@ -3010,18 +3083,18 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz else { /* Dispatch to driver */ if ((file->cls->read)(file, type, dxpl_id, addr, size, buf)<0) - HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed"); + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed") } /* end else */ } /* end else */ } /* end if */ else { /* Dispatch to driver */ if ((file->cls->read)(file, type, dxpl_id, addr, size, buf)<0) - HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed"); + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed") } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -3050,27 +3123,27 @@ H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5FDwrite, FAIL); + FUNC_ENTER_API(H5FDwrite, FAIL) H5TRACE6("e","xMtiazx",file,type,dxpl_id,addr,size,buf); /* Check args */ if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") /* Get the default dataset transfer property list if the user didn't provide one */ if (H5P_DEFAULT == dxpl_id) dxpl_id= H5P_DATASET_XFER_DEFAULT; else if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list") if (!buf) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null buffer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null buffer") /* The real work */ if (H5FD_write(file, type, dxpl_id, addr, size, buf)<0) - HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -3102,7 +3175,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si size_t old_offset; /* Offset of old data within the accumulator buffer */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_write, FAIL); + FUNC_ENTER_NOAPI(H5FD_write, FAIL) assert(file && file->cls); assert(H5I_GENPROP_LST==H5I_get_type(dxpl_id)); @@ -3114,7 +3187,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si /* collective transfer. */ /* The no-op case */ if (0==size) - HGOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED) #endif /* H5_HAVE_PARALLEL */ /* Check for accumulating metadata */ @@ -3135,7 +3208,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si /* Reallocate the metadata accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") } /* end if */ /* Move the existing metadata to the proper location */ @@ -3160,7 +3233,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si /* Reallocate the metadata accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") } /* end if */ /* Copy the new metadata to the end */ @@ -3192,7 +3265,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si /* Reallocate the metadata accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") } /* end if */ /* Calculate the proper offset of the existing metadata */ @@ -3223,7 +3296,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si /* Reallocate the metadata accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") } /* end if */ /* Copy the new metadata to the end */ @@ -3244,7 +3317,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si /* Write out the existing metadata accumulator, with dispatch to driver */ if(file->accum_dirty) { if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0) - HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed") /* Reset accumulator dirty flag */ file->accum_dirty=FALSE; } /* end if */ @@ -3254,7 +3327,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si if(size>file->accum_buf_size) { /* Grow the metadata accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ file->accum_buf_size=size; @@ -3267,7 +3340,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si /* Shrink the accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,tmp_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ file->accum_buf_size=tmp_size; @@ -3289,7 +3362,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si if(size>file->accum_buf_size) { /* Reallocate the metadata accumulator buffer */ if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ file->accum_buf_size=size; @@ -3307,11 +3380,11 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si else { /* Dispatch to driver */ if ((file->cls->write)(file, type, dxpl_id, addr, size, buf)<0) - HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed") } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -3339,24 +3412,24 @@ H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5FDflush, FAIL); + FUNC_ENTER_API(H5FDflush, FAIL) H5TRACE3("e","xiIu",file,dxpl_id,closing); /* Check args */ if (!file || !file->cls) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") if (H5P_DEFAULT == dxpl_id) dxpl_id= H5P_DATASET_XFER_DEFAULT; else if (TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list") /* Do the real work */ if (H5FD_flush(file,dxpl_id,closing)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file flush request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file flush request failed") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -3383,7 +3456,7 @@ H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_flush, FAIL); + FUNC_ENTER_NOAPI(H5FD_flush, FAIL) assert(file && file->cls); @@ -3392,17 +3465,17 @@ H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing) /* Flush the metadata contents */ /* Not certain if the type and dxpl should be the way they are... -QAK */ if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver write request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver write request failed") /* Reset the dirty flag */ file->accum_dirty=FALSE; } /* end if */ if (file->cls->flush && (file->cls->flush)(file,dxpl_id,closing)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver flush request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver flush request failed") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -3427,7 +3500,7 @@ H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_get_fileno, FAIL); + FUNC_ENTER_NOAPI(H5FD_get_fileno, FAIL) assert(file); assert(filenum); @@ -3436,8 +3509,8 @@ H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum) HDmemcpy(filenum,file->fileno,sizeof(file->fileno)); done: - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5F_get_fileno() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_get_fileno() */ /*-------------------------------------------------------------------------- @@ -3459,7 +3532,7 @@ herr_t H5FDget_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle) { herr_t ret_value; - FUNC_ENTER_API(H5FDget_vfd_handle, FAIL); + FUNC_ENTER_API(H5FDget_vfd_handle, FAIL) /* Check arguments */ assert(file); @@ -3467,7 +3540,7 @@ herr_t H5FDget_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle) ret_value=H5FD_get_vfd_handle(file, fapl, file_handle); done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } @@ -3489,14 +3562,14 @@ herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FD_get_vfd_handle, FAIL); + FUNC_ENTER_NOAPI(H5FD_get_vfd_handle, FAIL) assert(file_handle); if(file->cls->get_handle && ((ret_value=file->cls->get_handle(file, fapl, file_handle)) < 0)) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file handle for file driver"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file handle for file driver") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index f115be4..4266bb9 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -75,5 +75,9 @@ H5_DLL herr_t H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing); H5_DLL herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum); H5_DLL herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle); H5_DLL hssize_t H5FD_get_freespace(H5FD_t *file); +H5_DLL htri_t H5FD_can_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr, + hsize_t size, hsize_t extra_requested); +H5_DLL herr_t H5FD_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr, + hsize_t size, hsize_t extra_requested); #endif /* !_H5FDprivate_H */ diff --git a/src/H5HG.c b/src/H5HG.c index a605402..5418ee5b 100644 --- a/src/H5HG.c +++ b/src/H5HG.c @@ -38,6 +38,10 @@ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ +/* Pablo information */ +/* (Put before include files to avoid problems with inline functions) */ +#define PABLO_MASK H5HG_mask + #include "H5private.h" /* Generic Functions */ #include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ @@ -47,9 +51,6 @@ #include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ -/* Pablo information */ -#define PABLO_MASK H5HG_mask - /* Private macros */ /* @@ -77,6 +78,12 @@ #define H5HG_MINSIZE 4096 /* + * Limit global heap collections to the some reasonable size. This is + * fairly arbitrary... + */ +#define H5HG_MAXSIZE 65536 + +/* * Maximum length of the CWFS list, the list of remembered collections that * have free space. */ @@ -174,7 +181,7 @@ static int interface_initialize_g = 0; /* Declare a free list to manage the H5HG_t struct */ H5FL_DEFINE_STATIC(H5HG_heap_t); -/* Declare a free list to manage arrays of H5HG_obj_t's */ +/* Declare a free list to manage sequences of H5HG_obj_t's */ H5FL_SEQ_DEFINE_STATIC(H5HG_obj_t); /* Declare a PQ free list to manage heap chunks */ @@ -387,8 +394,30 @@ H5HG_load (H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1, uint8_t *begin = p; UINT16DECODE (p, idx); - assert (idxnalloc); + + /* Check if we need more room to store heap objects */ + if(idx>=heap->nalloc) { + size_t new_alloc; /* New allocation number */ + H5HG_obj_t *new_obj; /* New array of object descriptions */ + + /* Determine the new number of objects to index */ + new_alloc=MAX(heap->nalloc*2,(idx+1)); + + /* Reallocate array of objects */ + if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Reset new objects to zero */ + HDmemset(&new_obj[heap->nalloc],0,sizeof(H5HG_obj_t)*(new_alloc-heap->nalloc)); + + /* Update heap information */ + heap->nalloc=new_alloc; + heap->obj=new_obj; + } /* end if */ + + /* Check that we haven't double-allocated an index */ assert (NULL==heap->obj[idx].begin); + UINT16DECODE (p, heap->obj[idx].nrefs); p += 4; /*reserved*/ H5F_DECODE_LENGTH (f, p, heap->obj[idx].size); @@ -589,13 +618,14 @@ H5HG_clear(H5HG_heap_t *heap) *------------------------------------------------------------------------- */ static unsigned -H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, int cwfsno, size_t size) +H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size) { unsigned idx; uint8_t *p = NULL; size_t need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(size); + unsigned ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_alloc); + FUNC_ENTER_NOAPI_NOINIT(H5HG_alloc); /* Check args */ assert (heap); @@ -605,11 +635,29 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, int cwfsno, size_t size) * Find an ID for the new object. ID zero is reserved for the free space * object. */ - for (idx=1; idxnalloc; idx++) { + for (idx=1; idxnalloc; idx++) if (NULL==heap->obj[idx].begin) break; - } - assert (idx < heap->nalloc); + + /* Check if we need more room to store heap objects */ + if(idx>=heap->nalloc) { + size_t new_alloc; /* New allocation number */ + H5HG_obj_t *new_obj; /* New array of object descriptions */ + + /* Determine the new number of objects to index */ + new_alloc=MAX(heap->nalloc*2,(idx+1)); + + /* Reallocate array of objects */ + if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed"); + + /* Reset new objects to zero */ + HDmemset(&new_obj[heap->nalloc],0,sizeof(H5HG_obj_t)*(new_alloc-heap->nalloc)); + + /* Update heap information */ + heap->nalloc=new_alloc; + heap->obj=new_obj; + } /* end if */ /* Initialize the new object */ heap->obj[idx].nrefs = 0; @@ -624,16 +672,10 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, int cwfsno, size_t size) /* Fix the free space object */ if (need==heap->obj[0].size) { /* - * All free space has been exhausted from this collection. Remove the - * heap from the CWFS list. + * All free space has been exhausted from this collection. */ heap->obj[0].size = 0; heap->obj[0].begin = NULL; - if (cwfsno>=0) { - f->shared->ncwfs -= 1; - HDmemmove (f->shared->cwfs+cwfsno, f->shared->cwfs+cwfsno+1, - (f->shared->ncwfs-cwfsno)*sizeof(H5HG_heap_t*)); - } } else if (heap->obj[0].size-need >= H5HG_SIZEOF_OBJHDR (f)) { /* @@ -659,12 +701,106 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, int cwfsno, size_t size) assert(H5HG_ISALIGNED(heap->obj[0].size)); } + /* Mark the heap as dirty */ heap->cache_info.dirty = 1; - FUNC_LEAVE_NOAPI(idx); + + /* Set the return value */ + ret_value=idx; + +done: + FUNC_LEAVE_NOAPI(ret_value); } /*------------------------------------------------------------------------- + * Function: H5HG_extend + * + * Purpose: Extend a heap to hold an object of SIZE bytes. + * SIZE is the exact size of the object data to be + * stored. It will be increased to make room for the object + * header and then rounded up for alignment. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Saturday, June 12, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HG_extend (H5F_t *f, H5HG_heap_t *heap, size_t size) +{ + size_t need; /* Actual space needed to store object */ + size_t old_size; /* Previous size of the heap's chunk */ + uint8_t *new_chunk=NULL; /* Pointer to new chunk information */ + uint8_t *p = NULL; /* Pointer to raw heap info */ + unsigned u; /* Local index variable */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HG_extend); + + /* Check args */ + assert (f); + assert (heap); + + /* Compute total space need to add to this heap */ + need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(size); + + /* Decrement the amount needed in the heap by the amount of free space available */ + assert(need>heap->obj[0].size); + need -= heap->obj[0].size; + + /* Don't do anything less than double the size of the heap */ + need = MAX(heap->size,need); + + /* Extend the space allocated for this heap on disk */ + if(H5MF_extend(f,H5FD_MEM_GHEAP,heap->addr,(hsize_t)heap->size,(hsize_t)need)<0) + HGOTO_ERROR (H5E_HEAP, H5E_NOSPACE, FAIL, "can't extend heap on disk"); + + /* Re-allocate the heap information in memory */ + if (NULL==(new_chunk = H5FL_BLK_REALLOC (heap_chunk, heap->chunk, heap->size+need))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "new heap allocation failed"); + + /* Adjust the size of the heap */ + old_size=heap->size; + heap->size+=need; + + /* Encode the new size of the heap */ + p = new_chunk + H5HG_SIZEOF_MAGIC + 1 /* version */ + 3 /* reserved */; + H5F_ENCODE_LENGTH (f, p, heap->size); + + /* Move the pointers to the existing objects to their new locations */ + for (u=0; unalloc; u++) + if(heap->obj[u].begin) + heap->obj[u].begin = new_chunk + (heap->obj[u].begin - heap->chunk); + + /* Update the heap chunk pointer now */ + heap->chunk=new_chunk; + + /* Update the free space information for the heap */ + heap->obj[0].size+=need; + if(heap->obj[0].begin==NULL) + heap->obj[0].begin=heap->chunk+old_size; + p = heap->obj[0].begin; + UINT16ENCODE(p, 0); /*id*/ + UINT16ENCODE(p, 0); /*nrefs*/ + UINT32ENCODE(p, 0); /*reserved*/ + H5F_ENCODE_LENGTH (f, p, heap->obj[0].size); + assert(H5HG_ISALIGNED(heap->obj[0].size)); + + /* Mark the heap as dirty */ + heap->cache_info.dirty = 1; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5HG_extend() */ + + +/*------------------------------------------------------------------------- * Function: H5HG_insert * * Purpose: A new object is inserted into the global heap. It will be @@ -695,6 +831,7 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out* int cwfsno; unsigned idx; H5HG_heap_t *heap = NULL; + hbool_t found=0; /* Flag to indicate a heap with enough space was found */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HG_insert, FAIL); @@ -711,35 +848,53 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out* need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(size); for (cwfsno=0; cwfsnoshared->ncwfs; cwfsno++) { if (f->shared->cwfs[cwfsno]->obj[0].size>=need) { - /* - * Found. Move the collection forward in the CWFS list. - */ - heap = f->shared->cwfs[cwfsno]; - if (cwfsno>0) { - H5HG_heap_t *tmp = f->shared->cwfs[cwfsno]; - f->shared->cwfs[cwfsno] = f->shared->cwfs[cwfsno-1]; - f->shared->cwfs[cwfsno-1] = tmp; - --cwfsno; - } + found=1; break; - } - } + } /* end if */ + } /* end for */ + + /* + * If we didn't find any collection with enough free space the check if + * we can extend any of the collections to make enough room. + */ + if (!found) { + for (cwfsno=0; cwfsnoshared->ncwfs; cwfsno++) { + if((f->shared->cwfs[cwfsno]->size+need)<=H5HG_MAXSIZE && H5MF_can_extend(f,H5FD_MEM_GHEAP,f->shared->cwfs[cwfsno]->addr,(hsize_t)f->shared->cwfs[cwfsno]->size,(hsize_t)need)) { + if(H5HG_extend(f,f->shared->cwfs[cwfsno],size)<0) + HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL, "unable to extend global heap collection"); + found=1; + break; + } /* end if */ + } /* end for */ + } /* end if */ /* * If we didn't find any collection with enough free space then allocate a * new collection large enough for the message plus the collection header. */ - if (cwfsno>=f->shared->ncwfs) { + if (!found) { if (NULL==(heap=H5HG_create (f, dxpl_id, need+H5HG_SIZEOF_HDR (f)))) HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL, "unable to allocate a global heap collection"); assert (f->shared->ncwfs>0); assert (f->shared->cwfs[0]==heap); assert (f->shared->cwfs[0]->obj[0].size >= need); cwfsno = 0; - } + } /* end if */ + else { + /* Found a heap with enough space */ + heap = f->shared->cwfs[cwfsno]; + + /* Move the collection forward in the CWFS list, if it's not already at the front */ + if (cwfsno>0) { + H5HG_heap_t *tmp = f->shared->cwfs[cwfsno]; + f->shared->cwfs[cwfsno] = f->shared->cwfs[cwfsno-1]; + f->shared->cwfs[cwfsno-1] = tmp; + --cwfsno; + } /* end if */ + } /* end else */ /* Split the free space to make room for the new object */ - idx = H5HG_alloc (f, heap, cwfsno, size); + idx = H5HG_alloc (f, heap, size); assert (idx>0); /* Copy data into the heap */ @@ -797,6 +952,7 @@ H5HG_peek (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj) /* Load the heap and return a pointer to the object */ if (NULL==(heap=H5AC_find(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL))) HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap"); + assert (hobj->idx>0 && hobj->idxnalloc); ret_value = heap->obj[hobj->idx].begin + H5HG_SIZEOF_OBJHDR (f); assert (ret_value); @@ -860,6 +1016,7 @@ H5HG_read (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/) /* Load the heap */ if (NULL==(heap=H5AC_find(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL))) HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap"); + assert (hobj->idx>0 && hobj->idxnalloc); assert (heap->obj[hobj->idx].begin); size = heap->obj[hobj->idx].size; diff --git a/src/H5MF.c b/src/H5MF.c index 04c8b21..d4ab9d8 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -209,3 +209,79 @@ H5MF_realloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t done: FUNC_LEAVE_NOAPI(ret_value); } + + +/*------------------------------------------------------------------------- + * Function: H5MF_can_extend + * + * Purpose: Check if a block in the file can be extended. + * + * This is a simple check currently, which only checks for the + * block being at the end of the file. A more sophisticated check + * would also use the free space list to see if there is a block + * appropriately placed to accomodate the space requested. + * + * Return: Success: TRUE(1)/FALSE(0) + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Friday, June 11, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5MF_can_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested) +{ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5MF_can_extend, FAIL); + + /* Convert old relative address to absolute address */ + addr += f->shared->base_addr; + + /* Pass the request down to the virtual file layer */ + if((ret_value=H5FD_can_extend(f->shared->lf, type, addr, size, extra_requested))<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5MF_can_extend() */ + + +/*------------------------------------------------------------------------- + * Function: H5MF_extend + * + * Purpose: Extend a block in the file. + * + * Return: Success: TRUE(1)/FALSE(0) + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Saturday, June 12, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested) +{ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5MF_extend, FAIL); + + /* Convert old relative address to absolute address */ + addr += f->shared->base_addr; + + /* Pass the request down to the virtual file layer */ + if((ret_value=H5FD_extend(f->shared->lf, type, addr, size, extra_requested))<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5MF_extend() */ + diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 2a9b23d..14b2761 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -48,5 +48,9 @@ H5_DLL herr_t H5MF_xfree(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size); H5_DLL haddr_t H5MF_realloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size, hsize_t new_size); +H5_DLL htri_t H5MF_can_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, + hsize_t size, hsize_t extra_requested); +H5_DLL htri_t H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, + hsize_t extra_requested); #endif -- cgit v0.12