diff options
Diffstat (limited to 'src')
54 files changed, 2535 insertions, 1596 deletions
@@ -1824,6 +1824,40 @@ done: /*------------------------------------------------------------------------- + * Function: H5AC_dump_cache + * + * Purpose: Dumps a summary of the contents of the metadata cache + * to stdout. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * Sunday, October 10, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_dump_cache(const H5F_t *f) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5AC_dump_cache, FAIL) + + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->cache); + + if ( H5C_dump_cache(f->shared->cache, H5F_OPEN_NAME(f)) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_dump_cache() failed.") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC_dump_cache() */ + + +/*------------------------------------------------------------------------- * Function: H5AC_get_cache_auto_resize_config * * Purpose: Wrapper function for H5C_get_cache_auto_resize_config(). @@ -2465,7 +2499,9 @@ H5AC_open_trace_file(H5AC_t * cache_ptr, #else /* H5_HAVE_PARALLEL */ - sprintf(file_name, "%s", trace_file_name); + HDsnprintf(file_name, + (size_t)(H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 1), + "%s", trace_file_name); #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 79f355c..456eb0d 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -372,6 +372,8 @@ H5_DLL herr_t H5AC_set_write_done_callback(H5C_t * cache_ptr, void (* write_done)(void)); H5_DLL herr_t H5AC_stats(const H5F_t *f); +H5_DLL herr_t H5AC_dump_cache(const H5F_t *f); + H5_DLL herr_t H5AC_get_cache_auto_resize_config(const H5AC_t * cache_ptr, H5AC_cache_config_t *config_ptr); @@ -120,6 +120,8 @@ 4 + /*type, level, num entries */ \ 2*H5F_SIZEOF_ADDR(F)) /*left and right sibling addresses */ +/* Default initializer for H5B_ins_ud_t */ +#define H5B_INS_UD_T_NULL {NULL, HADDR_UNDEF, H5AC__NO_FLAGS_SET} /******************/ /* Local Typedefs */ @@ -131,24 +133,32 @@ typedef struct H5B_iter_ud_t { void *udata; /* Node type's 'udata' for loading & iterator callback */ } H5B_info_ud_t; +/* Convenience struct for the arguments needed to unprotect a b-tree after a + * call to H5B_iterate_helper() or H5B_split() */ +typedef struct H5B_ins_ud_t { + H5B_t *bt; /* B-tree */ + haddr_t addr; /* B-tree address */ + unsigned cache_flags; /* Cache flags for H5AC_unprotect() */ +} H5B_ins_ud_t; + /********************/ /* Local Prototypes */ /********************/ -static H5B_ins_t H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, +static H5B_ins_t H5B_insert_helper(H5F_t *f, hid_t dxpl_id, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, uint8_t *lt_key, hbool_t *lt_key_changed, uint8_t *md_key, void *udata, uint8_t *rt_key, hbool_t *rt_key_changed, - haddr_t *retval); + H5B_ins_ud_t *split_bt_ud/*out*/); static herr_t H5B_insert_child(H5B_t *bt, unsigned *bt_flags, unsigned idx, haddr_t child, H5B_ins_t anchor, const void *md_key); -static herr_t H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt, - unsigned *old_bt_flags, haddr_t old_addr, - unsigned idx, void *udata, haddr_t *new_addr/*out*/); +static herr_t H5B_split(H5F_t *f, hid_t dxpl_id, H5B_ins_ud_t *bt_ud, + unsigned idx, void *udata, + H5B_ins_ud_t *split_bt_ud/*out*/); static H5B_t * H5B_copy(const H5B_t *old_bt); @@ -374,7 +384,7 @@ done: * The UDATA pointer is passed to the sizeof_rkey() method but is * otherwise unused. * - * The OLD_BT argument is a pointer to a protected B-tree + * The BT_UD argument is a pointer to a protected B-tree * node. * * Return: Non-negative on success (The address of the new node is @@ -387,14 +397,12 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt, unsigned *old_bt_flags, - haddr_t old_addr, unsigned idx, void *udata, haddr_t *new_addr_p/*out*/) +H5B_split(H5F_t *f, hid_t dxpl_id, H5B_ins_ud_t *bt_ud, unsigned idx, + void *udata, H5B_ins_ud_t *split_bt_ud/*out*/) { H5P_genplist_t *dx_plist; /* Data transfer property list */ - H5B_shared_t *shared; /* Pointer to shared B-tree info */ + H5B_shared_t *shared; /* Pointer to shared B-tree info */ H5B_cache_ud_t cache_udata; /* User-data for metadata cache callback */ - unsigned new_bt_flags = H5AC__NO_FLAGS_SET; - H5B_t *new_bt = NULL; unsigned nleft, nright; /* Number of keys in left & right halves */ double split_ratios[3]; /* B-tree split ratios */ herr_t ret_value = SUCCEED; /* Return value */ @@ -405,16 +413,18 @@ H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt, unsigned *old_bt_flags, * Check arguments. */ HDassert(f); - HDassert(old_bt); - HDassert(old_bt_flags); - HDassert(H5F_addr_defined(old_addr)); + HDassert(bt_ud); + HDassert(bt_ud->bt); + HDassert(H5F_addr_defined(bt_ud->addr)); + HDassert(split_bt_ud); + HDassert(!split_bt_ud->bt); /* * Initialize variables. */ - shared = (H5B_shared_t *)H5RC_GET_OBJ(old_bt->rc_shared); + shared = (H5B_shared_t *)H5RC_GET_OBJ(bt_ud->bt->rc_shared); HDassert(shared); - HDassert(old_bt->nchildren == shared->two_k); + HDassert(bt_ud->bt->nchildren == shared->two_k); /* Get the dataset transfer property list */ if(NULL == (dx_plist = (H5P_genplist_t *)H5I_object(dxpl_id))) @@ -428,11 +438,11 @@ H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt, unsigned *old_bt_flags, if(H5DEBUG(B)) { const char *side; - if(!H5F_addr_defined(old_bt->left) && !H5F_addr_defined(old_bt->right)) + if(!H5F_addr_defined(bt_ud->bt->left) && !H5F_addr_defined(bt_ud->bt->right)) side = "ONLY"; - else if(!H5F_addr_defined(old_bt->right)) + else if(!H5F_addr_defined(bt_ud->bt->right)) side = "RIGHT"; - else if(!H5F_addr_defined(old_bt->left)) + else if(!H5F_addr_defined(bt_ud->bt->left)) side = "LEFT"; else side = "MIDDLE"; @@ -445,9 +455,9 @@ H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt, unsigned *old_bt_flags, * Decide how to split the children of the old node among the old node * and the new node. */ - if(!H5F_addr_defined(old_bt->right)) + if(!H5F_addr_defined(bt_ud->bt->right)) nleft = (unsigned)((double)shared->two_k * split_ratios[2]); /*right*/ - else if(!H5F_addr_defined(old_bt->left)) + else if(!H5F_addr_defined(bt_ud->bt->left)) nleft = (unsigned)((double)shared->two_k * split_ratios[0]); /*left*/ else nleft = (unsigned)((double)shared->two_k * split_ratios[1]); /*middle*/ @@ -470,69 +480,66 @@ H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt, unsigned *old_bt_flags, /* * Create the new B-tree node. */ - if(H5B_create(f, dxpl_id, shared->type, udata, new_addr_p/*out*/) < 0) + if(H5B_create(f, dxpl_id, shared->type, udata, &split_bt_ud->addr/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create B-tree") cache_udata.f = f; cache_udata.type = shared->type; - cache_udata.rc_shared = old_bt->rc_shared; - if(NULL == (new_bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, *new_addr_p, &cache_udata, H5AC_WRITE))) + cache_udata.rc_shared = bt_ud->bt->rc_shared; + if(NULL == (split_bt_ud->bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, split_bt_ud->addr, &cache_udata, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree") - new_bt->level = old_bt->level; + split_bt_ud->bt->level = bt_ud->bt->level; /* * Copy data from the old node to the new node. */ - /* this function didn't used to mark the new bt entry as dirty. Since - * we just inserted the entry, this doesn't matter unless the entry - * somehow gets flushed between the insert and the protect. At present, - * I don't think this can happen, but it doesn't hurt to mark the entry - * dirty again. - * -- JRM - */ - new_bt_flags |= H5AC__DIRTIED_FLAG; - HDmemcpy(new_bt->native, - old_bt->native + nleft * shared->type->sizeof_nkey, + split_bt_ud->cache_flags = H5AC__DIRTIED_FLAG; + HDmemcpy(split_bt_ud->bt->native, + bt_ud->bt->native + nleft * shared->type->sizeof_nkey, (nright + 1) * shared->type->sizeof_nkey); - HDmemcpy(new_bt->child, - &old_bt->child[nleft], + HDmemcpy(split_bt_ud->bt->child, + &bt_ud->bt->child[nleft], nright * sizeof(haddr_t)); - new_bt->nchildren = nright; + split_bt_ud->bt->nchildren = nright; /* * Truncate the old node. */ - *old_bt_flags |= H5AC__DIRTIED_FLAG; - old_bt->nchildren = nleft; + bt_ud->cache_flags |= H5AC__DIRTIED_FLAG; + bt_ud->bt->nchildren = nleft; /* * Update sibling pointers. */ - new_bt->left = old_addr; - new_bt->right = old_bt->right; + split_bt_ud->bt->left = bt_ud->addr; + split_bt_ud->bt->right = bt_ud->bt->right; - if(H5F_addr_defined(old_bt->right)) { + if(H5F_addr_defined(bt_ud->bt->right)) { H5B_t *tmp_bt; H5B_cache_ud_t cache_udata2; /* User-data for metadata cache callback */ cache_udata2.f = f; cache_udata2.type = shared->type; - cache_udata2.rc_shared = old_bt->rc_shared; - if(NULL == (tmp_bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, old_bt->right, &cache_udata2, H5AC_WRITE))) + cache_udata2.rc_shared = bt_ud->bt->rc_shared; + if(NULL == (tmp_bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, bt_ud->bt->right, &cache_udata2, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load right sibling") - tmp_bt->left = *new_addr_p; + tmp_bt->left = split_bt_ud->addr; - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, old_bt->right, tmp_bt, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt_ud->bt->right, tmp_bt, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") } /* end if */ - old_bt->right = *new_addr_p; + bt_ud->bt->right = split_bt_ud->addr; done: - if(new_bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, *new_addr_p, new_bt, new_bt_flags) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") + if(ret_value < 0) { + if(split_bt_ud->bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, split_bt_ud->addr, split_bt_ud->bt, split_bt_ud->cache_flags) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") + split_bt_ud->bt = NULL; + split_bt_ud->addr = HADDR_UNDEF; + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5B_split() */ @@ -541,8 +548,7 @@ done: /*------------------------------------------------------------------------- * Function: H5B_insert * - * Purpose: Adds a new item to the B-tree. If the root node of - * the B-tree splits then the B-tree gets a new address. + * Purpose: Adds a new item to the B-tree. * * Return: Non-negative on success/Negative on failure * @@ -565,10 +571,11 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, uint8_t *rt_key=(uint8_t*)_rt_key; hbool_t lt_key_changed = FALSE, rt_key_changed = FALSE; - haddr_t child, old_root; + haddr_t old_root_addr = HADDR_UNDEF; unsigned level; - H5B_t *bt; - H5B_t *new_bt; /* Copy of B-tree info */ + H5B_ins_ud_t bt_ud = H5B_INS_UD_T_NULL; /* (Old) root node */ + H5B_ins_ud_t split_bt_ud = H5B_INS_UD_T_NULL; /* Split B-tree node */ + H5B_t *new_root_bt = NULL; /* New root node */ H5RC_t *rc_shared; /* Ref-counted shared info */ H5B_shared_t *shared; /* Pointer to shared B-tree info */ H5B_cache_ud_t cache_udata; /* User-data for metadata cache callback */ @@ -583,118 +590,111 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, HDassert(type->sizeof_nkey <= sizeof _lt_key); HDassert(H5F_addr_defined(addr)); - if((int)(my_ins = H5B_insert_helper(f, dxpl_id, addr, type, lt_key, - <_key_changed, md_key, udata, rt_key, &rt_key_changed, &child/*out*/)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to insert key") - if(H5B_INS_NOOP == my_ins) - HGOTO_DONE(SUCCEED) - HDassert(H5B_INS_RIGHT == my_ins); - /* Get shared info for B-tree */ if(NULL == (rc_shared = (type->get_shared)(f, udata))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree's shared ref. count object") + HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree's shared ref. count object") shared = (H5B_shared_t *)H5RC_GET_OBJ(rc_shared); HDassert(shared); - /* the current root */ + /* Protect the root node */ cache_udata.f = f; cache_udata.type = type; cache_udata.rc_shared = rc_shared; - if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, &cache_udata, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to locate root of B-tree") + bt_ud.addr = addr; + if(NULL == (bt_ud.bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, &cache_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to locate root of B-tree") + + /* Insert the object */ + if((int)(my_ins = H5B_insert_helper(f, dxpl_id, &bt_ud, type, lt_key, + <_key_changed, md_key, udata, rt_key, &rt_key_changed, + &split_bt_ud/*out*/)) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to insert key") + if(H5B_INS_NOOP == my_ins) { + HDassert(!split_bt_ud.bt); + HGOTO_DONE(SUCCEED) + } /* end if */ + HDassert(H5B_INS_RIGHT == my_ins); + HDassert(split_bt_ud.bt); + HDassert(H5F_addr_defined(split_bt_ud.addr)); - level = bt->level; + /* Get level of old root */ + level = bt_ud.bt->level; + /* update left and right keys */ if(!lt_key_changed) - HDmemcpy(lt_key, H5B_NKEY(bt,shared,0), type->sizeof_nkey); - - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release new child") - bt = NULL; - - /* the new node */ - if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, child, &cache_udata, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load new node") - + HDmemcpy(lt_key, H5B_NKEY(bt_ud.bt,shared,0), type->sizeof_nkey); if(!rt_key_changed) - HDmemcpy(rt_key, H5B_NKEY(bt,shared,bt->nchildren), type->sizeof_nkey); - - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, child, bt, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release new child") - bt = NULL; + HDmemcpy(rt_key, H5B_NKEY(split_bt_ud.bt,shared,split_bt_ud.bt->nchildren), type->sizeof_nkey); /* - * Copy the old root node to some other file location and make the new - * root at the old root's previous address. This prevents the B-tree - * from "moving". + * Copy the old root node to some other file location and make the new root + * at the old root's previous address. This prevents the B-tree from + * "moving". */ H5_CHECK_OVERFLOW(shared->sizeof_rnode,size_t,hsize_t); - if(HADDR_UNDEF == (old_root = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)shared->sizeof_rnode))) + if(HADDR_UNDEF == (old_root_addr = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)shared->sizeof_rnode))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "unable to allocate file space to move root") - /* update the new child's left pointer */ - if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, child, &cache_udata, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load new child") - - bt->left = old_root; - - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, child, bt, H5AC__DIRTIED_FLAG) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release new child") - bt = NULL; /* Make certain future references will be caught */ - /* - * Move the node to the new location by checking it out & checking it in - * at the new location -QAK + * Move the node to the new location */ - /* Bring the old root into the cache if it's not already */ - if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, &cache_udata, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load new child") - - /* Make certain the old root info is marked as dirty before moving it, */ - /* so it is certain to be written out at the new location */ /* Make a copy of the old root information */ - if(NULL == (new_bt = H5B_copy(bt))) { - HCOMMON_ERROR(H5E_BTREE, H5E_CANTCOPY, "unable to copy old root"); + if(NULL == (new_root_bt = H5B_copy(bt_ud.bt))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to copy old root"); - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__DIRTIED_FLAG) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release new child") - - HGOTO_DONE(FAIL) - } /* end if */ - - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__DIRTIED_FLAG) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release new child") - bt = NULL; /* Make certain future references will be caught */ + /* Unprotect the old root so we can move it. Also force it to be marked + * dirty so it is written to the new location. */ + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt_ud.addr, bt_ud.bt, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release old root") + bt_ud.bt = NULL; /* Make certain future references will be caught */ /* Move the location of the old root on the disk */ - if(H5AC_move_entry(f, H5AC_BT, addr, old_root) < 0) + if(H5AC_move_entry(f, H5AC_BT, bt_ud.addr, old_root_addr) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to move B-tree root node") + bt_ud.addr = old_root_addr; + + /* Update the split b-tree's left pointer to point to the new location */ + split_bt_ud.bt->left = bt_ud.addr; + split_bt_ud.cache_flags |= H5AC__DIRTIED_FLAG; /* clear the old root info at the old address (we already copied it) */ - new_bt->left = HADDR_UNDEF; - new_bt->right = HADDR_UNDEF; + new_root_bt->left = HADDR_UNDEF; + new_root_bt->right = HADDR_UNDEF; /* Set the new information for the copy */ - new_bt->level = level + 1; - new_bt->nchildren = 2; + new_root_bt->level = level + 1; + new_root_bt->nchildren = 2; - new_bt->child[0] = old_root; - HDmemcpy(H5B_NKEY(new_bt, shared, 0), lt_key, shared->type->sizeof_nkey); + new_root_bt->child[0] = bt_ud.addr; + HDmemcpy(H5B_NKEY(new_root_bt, shared, 0), lt_key, shared->type->sizeof_nkey); - new_bt->child[1] = child; - HDmemcpy(H5B_NKEY(new_bt, shared, 1), md_key, shared->type->sizeof_nkey); - HDmemcpy(H5B_NKEY(new_bt, shared, 2), rt_key, shared->type->sizeof_nkey); + new_root_bt->child[1] = split_bt_ud.addr; + HDmemcpy(H5B_NKEY(new_root_bt, shared, 1), md_key, shared->type->sizeof_nkey); + HDmemcpy(H5B_NKEY(new_root_bt, shared, 2), rt_key, shared->type->sizeof_nkey); /* Insert the modified copy of the old root into the file again */ - if(H5AC_insert_entry(f, dxpl_id, H5AC_BT, addr, new_bt, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to flush old B-tree root node") + if(H5AC_insert_entry(f, dxpl_id, H5AC_BT, addr, new_root_bt, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to add old B-tree root node to cache") + +done: + if(ret_value < 0) + if(new_root_bt && H5B_node_dest(new_root_bt) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "unable to free B-tree root node"); + + if(bt_ud.bt) + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt_ud.addr, bt_ud.bt, bt_ud.cache_flags) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to unprotect old root") + + if(split_bt_ud.bt) + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, split_bt_ud.addr, split_bt_ud.bt, split_bt_ud.cache_flags) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to unprotect new child") #ifdef H5B_DEBUG - H5B_assert(f, dxpl_id, addr, type, udata); + if(ret_value >= 0) + H5B_assert(f, dxpl_id, addr, type, udata); #endif -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B_insert() */ @@ -725,6 +725,7 @@ H5B_insert_child(H5B_t *bt, unsigned *bt_flags, unsigned idx, HDassert(bt); HDassert(bt_flags); + HDassert(H5F_addr_defined(child)); shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); HDassert(shared); HDassert(bt->nchildren < shared->two_k); @@ -803,20 +804,21 @@ H5B_insert_child(H5B_t *bt, unsigned *bt_flags, unsigned idx, *------------------------------------------------------------------------- */ static H5B_ins_t -H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, +H5B_insert_helper(H5F_t *f, hid_t dxpl_id, H5B_ins_ud_t *bt_ud, + const H5B_class_t *type, uint8_t *lt_key, hbool_t *lt_key_changed, uint8_t *md_key, void *udata, uint8_t *rt_key, hbool_t *rt_key_changed, - haddr_t *new_node_p/*out*/) + H5B_ins_ud_t *split_bt_ud/*out*/) { - unsigned bt_flags = H5AC__NO_FLAGS_SET, twin_flags = H5AC__NO_FLAGS_SET; - H5B_t *bt = NULL, *twin = NULL; + H5B_t *bt; /* Convenience pointer to B-tree */ H5RC_t *rc_shared; /* Ref-counted shared info */ - H5B_shared_t *shared; /* Pointer to shared B-tree info */ + H5B_shared_t *shared; /* Pointer to shared B-tree info */ H5B_cache_ud_t cache_udata; /* User-data for metadata cache callback */ unsigned lt = 0, idx = 0, rt; /* Left, final & right index values */ int cmp = -1; /* Key comparison value */ - haddr_t child_addr = HADDR_UNDEF; + H5B_ins_ud_t child_bt_ud = H5B_INS_UD_T_NULL; /* Child B-tree */ + H5B_ins_ud_t new_child_bt_ud = H5B_INS_UD_T_NULL; /* Newly split child B-tree */ H5B_ins_t my_ins = H5B_INS_ERROR; H5B_ins_t ret_value = H5B_INS_ERROR; /* Return value */ @@ -826,7 +828,9 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * Check arguments */ HDassert(f); - HDassert(H5F_addr_defined(addr)); + HDassert(bt_ud); + HDassert(bt_ud->bt); + HDassert(H5F_addr_defined(bt_ud->addr)); HDassert(type); HDassert(type->decode); HDassert(type->cmp3); @@ -835,7 +839,12 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type HDassert(lt_key_changed); HDassert(rt_key); HDassert(rt_key_changed); - HDassert(new_node_p); + HDassert(split_bt_ud); + HDassert(!split_bt_ud->bt); + HDassert(!H5F_addr_defined(split_bt_ud->addr)); + HDassert(split_bt_ud->cache_flags == H5AC__NO_FLAGS_SET); + + bt = bt_ud->bt; *lt_key_changed = FALSE; *rt_key_changed = FALSE; @@ -851,11 +860,6 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * data. When the search completes IDX points to the child that * should get the new data. */ - cache_udata.f = f; - cache_udata.type = type; - cache_udata.rc_shared = rc_shared; - if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, &cache_udata, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to load node") rt = bt->nchildren; while(lt < rt && cmp) { @@ -866,6 +870,11 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type lt = idx + 1; } /* end while */ + /* Set up user data for cache callbacks */ + cache_udata.f = f; + cache_udata.type = type; + cache_udata.rc_shared = rc_shared; + if(0 == bt->nchildren) { /* * The value being inserted will be the only value in this tree. We @@ -876,13 +885,13 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type H5B_NKEY(bt, shared, 1), bt->child + 0/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, H5B_INS_ERROR, "unable to create leaf node") bt->nchildren = 1; - bt_flags |= H5AC__DIRTIED_FLAG; + bt_ud->cache_flags |= H5AC__DIRTIED_FLAG; idx = 0; if(type->follow_min) { if((int)(my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), - rt_key_changed, &child_addr/*out*/)) < 0) + rt_key_changed, &new_child_bt_ud.addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert first leaf node") } /* end if */ else @@ -893,10 +902,14 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * The value being inserted is less than any value in this tree. * Follow the minimum branch out of this node to a subtree. */ - if((int)(my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, + child_bt_ud.addr = bt->child[idx]; + if(NULL == (child_bt_ud.bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, child_bt_ud.addr, &cache_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to load node") + + if((int)(my_ins = H5B_insert_helper(f, dxpl_id, &child_bt_ud, type, H5B_NKEY(bt,shared,idx), lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), rt_key_changed, - &child_addr/*out*/)) < 0) + &new_child_bt_ud/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum subtree") } else if(type->follow_min) { /* @@ -906,7 +919,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ if((int)(my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), - rt_key_changed, &child_addr/*out*/)) < 0) + rt_key_changed, &new_child_bt_ud.addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") } else { /* @@ -917,7 +930,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type my_ins = H5B_INS_LEFT; HDmemcpy(md_key, H5B_NKEY(bt,shared,idx), type->sizeof_nkey); if((type->new_node)(f, dxpl_id, H5B_INS_LEFT, H5B_NKEY(bt, shared, idx), udata, - md_key, &child_addr/*out*/) < 0) + md_key, &new_child_bt_ud.addr/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") *lt_key_changed = TRUE; } /* end else */ @@ -935,9 +948,14 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * Follow the maximum branch out of this node to a subtree. */ idx = bt->nchildren - 1; - if((int)(my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, + child_bt_ud.addr = bt->child[idx]; + if(NULL == (child_bt_ud.bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, child_bt_ud.addr, &cache_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to load node") + + if((int)(my_ins = H5B_insert_helper(f, dxpl_id, &child_bt_ud, type, H5B_NKEY(bt, shared, idx), lt_key_changed, md_key, udata, - H5B_NKEY(bt, shared, idx + 1), rt_key_changed, &child_addr/*out*/)) < 0) + H5B_NKEY(bt, shared, idx + 1), rt_key_changed, + &new_child_bt_ud/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum subtree") } else if(type->follow_max) { /* @@ -948,7 +966,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type idx = bt->nchildren - 1; if((int)(my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), - rt_key_changed, &child_addr/*out*/)) < 0) + rt_key_changed, &new_child_bt_ud.addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") } else { /* @@ -960,7 +978,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type my_ins = H5B_INS_RIGHT; HDmemcpy(md_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); if((type->new_node)(f, dxpl_id, H5B_INS_RIGHT, md_key, udata, - H5B_NKEY(bt, shared, idx + 1), &child_addr/*out*/) < 0) + H5B_NKEY(bt, shared, idx + 1), &new_child_bt_ud.addr/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") *rt_key_changed = TRUE; } /* end else */ @@ -985,9 +1003,13 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * Follow a branch out of this node to another subtree. */ HDassert(idx < bt->nchildren); - if((int)(my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, + child_bt_ud.addr = bt->child[idx]; + if(NULL == (child_bt_ud.bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, child_bt_ud.addr, &cache_udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to load node") + + if((int)(my_ins = H5B_insert_helper(f, dxpl_id, &child_bt_ud, type, H5B_NKEY(bt, shared, idx), lt_key_changed, md_key, udata, - H5B_NKEY(bt, shared, idx + 1), rt_key_changed, &child_addr/*out*/)) < 0) + H5B_NKEY(bt, shared, idx + 1), rt_key_changed, &new_child_bt_ud/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert subtree") } else { /* @@ -996,7 +1018,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type HDassert(idx < bt->nchildren); if((int)(my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), - rt_key_changed, &child_addr/*out*/)) < 0) + rt_key_changed, &new_child_bt_ud.addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert leaf node") } HDassert((int)my_ins >= 0); @@ -1005,18 +1027,20 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * Update the left and right keys of the current node. */ if(*lt_key_changed) { - bt_flags |= H5AC__DIRTIED_FLAG; + bt_ud->cache_flags |= H5AC__DIRTIED_FLAG; if(idx > 0) { HDassert(type->critical_key == H5B_LEFT); + HDassert(!(H5B_INS_LEFT == my_ins || H5B_INS_RIGHT == my_ins)); *lt_key_changed = FALSE; } /* end if */ else HDmemcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); } /* end if */ if(*rt_key_changed) { - bt_flags |= H5AC__DIRTIED_FLAG; + bt_ud->cache_flags |= H5AC__DIRTIED_FLAG; if(idx + 1 < bt->nchildren) { HDassert(type->critical_key == H5B_RIGHT); + HDassert(!(H5B_INS_LEFT == my_ins || H5B_INS_RIGHT == my_ins)); *rt_key_changed = FALSE; } /* end if */ else @@ -1026,9 +1050,10 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type /* * The insertion simply changed the address for the child. */ - bt->child[idx] = child_addr; - bt_flags |= H5AC__DIRTIED_FLAG; - ret_value = H5B_INS_NOOP; + HDassert(!child_bt_ud.bt); + HDassert(bt->level == 0); + bt->child[idx] = new_child_bt_ud.addr; + bt_ud->cache_flags |= H5AC__DIRTIED_FLAG; } else if(H5B_INS_LEFT == my_ins || H5B_INS_RIGHT == my_ins) { hbool_t *tmp_bt_flags_ptr = NULL; H5B_t *tmp_bt; @@ -1037,26 +1062,24 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * If this node is full then split it before inserting the new child. */ if(bt->nchildren == shared->two_k) { - if(H5B_split(f, dxpl_id, bt, &bt_flags, addr, idx, udata, new_node_p/*out*/) < 0) + if(H5B_split(f, dxpl_id, bt_ud, idx, udata, split_bt_ud/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, H5B_INS_ERROR, "unable to split node") - if(NULL == (twin = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, *new_node_p, &cache_udata, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to load node") if(idx < bt->nchildren) { tmp_bt = bt; - tmp_bt_flags_ptr = &bt_flags; + tmp_bt_flags_ptr = &bt_ud->cache_flags; } else { idx -= bt->nchildren; - tmp_bt = twin; - tmp_bt_flags_ptr = &twin_flags; + tmp_bt = split_bt_ud->bt; + tmp_bt_flags_ptr = &split_bt_ud->cache_flags; } } /* end if */ else { tmp_bt = bt; - tmp_bt_flags_ptr = &bt_flags; + tmp_bt_flags_ptr = &bt_ud->cache_flags; } /* end else */ /* Insert the child */ - if(H5B_insert_child(tmp_bt, tmp_bt_flags_ptr, idx, child_addr, my_ins, md_key) < 0) + if(H5B_insert_child(tmp_bt, tmp_bt_flags_ptr, idx, new_child_bt_ud.addr, my_ins, md_key) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert child") } @@ -1064,8 +1087,8 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * If this node split, return the mid key (the one that is shared * by the left and right node). */ - if(twin) { - HDmemcpy(md_key, H5B_NKEY(twin, shared, 0), type->sizeof_nkey); + if(split_bt_ud->bt) { + HDmemcpy(md_key, H5B_NKEY(split_bt_ud->bt, shared, 0), type->sizeof_nkey); ret_value = H5B_INS_RIGHT; #ifdef H5B_DEBUG /* @@ -1073,7 +1096,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * in the new node. */ cmp = (type->cmp2)(H5B_NKEY(bt, shared, bt->nchildren), udata, - H5B_NKEY(twin, shared, 0)); + H5B_NKEY(split_bt_ud->bt, shared, 0)); HDassert(0 == cmp); #endif } /* end if */ @@ -1081,12 +1104,13 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type ret_value = H5B_INS_NOOP; done: - { - herr_t e1 = (bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, bt_flags) < 0); - herr_t e2 = (twin && H5AC_unprotect(f, dxpl_id, H5AC_BT, *new_node_p, twin, twin_flags) < 0); - if(e1 || e2) /*use vars to prevent short-circuit of side effects */ - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release node(s)") - } + if(child_bt_ud.bt) + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, child_bt_ud.addr, child_bt_ud.bt, child_bt_ud.cache_flags) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to unprotect child") + + if(new_child_bt_ud.bt) + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, new_child_bt_ud.addr, new_child_bt_ud.bt, new_child_bt_ud.cache_flags) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to unprotect new child") FUNC_LEAVE_NOAPI(ret_value) } diff --git a/src/H5Bdbg.c b/src/H5Bdbg.c index 55d9617..23ea9c8 100644 --- a/src/H5Bdbg.c +++ b/src/H5Bdbg.c @@ -177,7 +177,7 @@ H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void H5RC_t *rc_shared; /* Ref-counted shared info */ H5B_shared_t *shared; /* Pointer to shared B-tree info */ H5B_cache_ud_t cache_udata; /* User-data for metadata cache callback */ - int i, ncell, cmp; + int ncell, cmp; static int ncalls = 0; herr_t status; herr_t ret_value = SUCCEED; /* Return value */ @@ -210,7 +210,7 @@ H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void HDassert(bt); shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); HDassert(shared); - cur = H5MM_calloc(sizeof(struct child_t)); + cur = (struct child_t *)H5MM_calloc(sizeof(struct child_t)); HDassert(cur); cur->addr = addr; cur->level = bt->level; @@ -242,24 +242,26 @@ H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void HDassert(!H5F_addr_defined(bt->left)); if(cur->level > 0) { - for(i = 0; i < bt->nchildren; i++) { + unsigned u; + + for(u = 0; u < bt->nchildren; u++) { /* * Check that child nodes haven't already been seen. If they * have then the tree has a cycle. */ for(tmp = head; tmp; tmp = tmp->next) - HDassert(H5F_addr_ne(tmp->addr, bt->child[i])); + HDassert(H5F_addr_ne(tmp->addr, bt->child[u])); /* Add the child node to the end of the queue */ - tmp = H5MM_calloc(sizeof(struct child_t)); + tmp = (struct child_t *)H5MM_calloc(sizeof(struct child_t)); HDassert(tmp); - tmp->addr = bt->child[i]; + tmp->addr = bt->child[u]; tmp->level = bt->level - 1; tail->next = tmp; tail = tmp; /* Check that the keys are monotonically increasing */ - cmp = (type->cmp2)(H5B_NKEY(bt, shared, i), udata, H5B_NKEY(bt, shared, i + 1)); + cmp = (type->cmp2)(H5B_NKEY(bt, shared, u), udata, H5B_NKEY(bt, shared, u + 1)); HDassert(cmp < 0); } /* end for */ } /* end if */ @@ -4392,15 +4392,26 @@ done: herr_t H5C_set_prefix(H5C_t * cache_ptr, char * prefix) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5C_set_prefix) + herr_t ret_value = SUCCEED; /* Return value */ - HDassert((cache_ptr) && (cache_ptr->magic == H5C__H5C_T_MAGIC)); - HDassert(prefix); - HDassert(HDstrlen(prefix) < H5C__PREFIX_LEN); + FUNC_ENTER_NOAPI(H5C_set_prefix, FAIL) - HDstrcpy(&(cache_ptr->prefix[0]), prefix); + if ( ( cache_ptr == NULL ) || + ( cache_ptr->magic != H5C__H5C_T_MAGIC ) || + ( prefix == NULL ) || + ( HDstrlen(prefix) >= H5C__PREFIX_LEN ) ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad param(s) on entry.") + } + + HDstrncpy(&(cache_ptr->prefix[0]), prefix, (size_t)(H5C__PREFIX_LEN)); + + cache_ptr->prefix[H5C__PREFIX_LEN - 1] = '\0'; + +done: + + FUNC_LEAVE_NOAPI(ret_value) - FUNC_LEAVE_NOAPI(SUCCEED) } /* H5C_set_prefix() */ @@ -5018,6 +5029,137 @@ H5C_stats__reset(H5C_t UNUSED * cache_ptr) /*------------------------------------------------------------------------- + * Function: H5C_dump_cache + * + * Purpose: Print a summary of the contents of the metadata cache for + * debugging purposes. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 10/10/10 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_dump_cache(H5C_t * cache_ptr, + const char * cache_name) +{ + herr_t ret_value = SUCCEED; /* Return value */ + int i; + H5C_cache_entry_t * entry_ptr = NULL; + H5SL_t * slist_ptr = NULL; + H5SL_node_t * node_ptr = NULL; + + FUNC_ENTER_NOAPI(H5C_dump_cache, FAIL) + + HDassert(cache_ptr != NULL); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + HDassert(cache_name != NULL ); + + /* First, create a skip list */ + slist_ptr = H5SL_create(H5SL_TYPE_HADDR); + + if ( slist_ptr == NULL ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create skip list.") + } + + /* Next, scan the index, and insert all entries in the skip list. + * Do this, as we want to display cache entries in increasing address + * order. + */ + for ( i = 0; i < H5C__HASH_TABLE_LEN; i++ ) { + + entry_ptr = cache_ptr->index[i]; + + while ( entry_ptr != NULL ) { + + HDassert( entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ); + + if ( H5SL_insert(slist_ptr, entry_ptr, &(entry_ptr->addr)) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ + "Can't insert entry in skip list") + } + + entry_ptr = entry_ptr->ht_next; + } + } + + /* If we get this far, all entries in the cache are listed in the + * skip list -- scan the skip list generating the desired output. + */ + + HDfprintf(stdout, "\n\nDump of metadata cache \"%s\".\n", cache_name); + HDfprintf(stdout, + "Num: Addr: Len: Type: Prot: Pinned: Dirty:\n"); + + i = 0; + + node_ptr = H5SL_first(slist_ptr); + + if ( node_ptr != NULL ) { + + entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); + + } else { + + entry_ptr = NULL; + } + + while ( entry_ptr != NULL ) { + + HDassert( entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ); + + HDfprintf(stdout, + "%s%d 0x%08llx 0x%3llx %2d %d %d %d\n", + cache_ptr->prefix, i, + (long long)(entry_ptr->addr), + (long long)(entry_ptr->size), + (int)(entry_ptr->type->id), + (int)(entry_ptr->is_protected), + (int)(entry_ptr->is_pinned), + (int)(entry_ptr->is_dirty)); + + /* increment node_ptr before we delete its target */ + node_ptr = H5SL_next(node_ptr); + + /* remove the first item in the skip list */ + if ( H5SL_remove(slist_ptr, &(entry_ptr->addr)) != entry_ptr ) { + + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ + "Can't delete entry from skip list.") + } + + if ( node_ptr != NULL ) { + + entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); + + } else { + + entry_ptr = NULL; + } + + i++; + } + + HDfprintf(stdout, "\n\n"); + + /* Finally, discard the skip list */ + + HDassert( H5SL_count(slist_ptr) == 0 ); + + H5SL_close(slist_ptr); + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5C_dump_cache() */ + + +/*------------------------------------------------------------------------- * Function: H5C_unpin_entry_from_client() * * Purpose: Internal routine to unpin a cache entry from a client action. @@ -7792,7 +7934,7 @@ end_of_inner_loop: */ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ - "Pinned entry count not decreasing.") + "Pinned entry count not decreasing, cur_pel_len = %d, old_pel_len = %d", (int)cur_pel_len, (int)old_pel_len) } else if ( ( cur_pel_len == 0 ) && ( old_pel_len == 0 ) ) { @@ -8713,7 +8855,7 @@ H5C_make_space_in_cache(H5F_t * f, #endif /* H5C_COLLECT_CACHE_STATS */ HDassert( ( entries_examined > (2 * initial_list_len) ) || - ( (cache_ptr->pl_size + cache_ptr->min_clean_size) > + ( (cache_ptr->pl_size + cache_ptr->pel_size + cache_ptr->min_clean_size) > cache_ptr->max_cache_size ) || ( ( cache_ptr->clean_index_size + empty_space ) >= cache_ptr->min_clean_size ) ); @@ -9132,7 +9274,7 @@ H5C_mark_tagged_entries(H5C_t * cache_ptr, haddr_t tag) H5C_cache_entry_t *next_entry_ptr; /* entry pointer */ unsigned u; /* Local index variable */ - FUNC_ENTER_NOAPI_NOINIT(H5C_mark_tagged_entries) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5C_mark_tagged_entries) /* Assertions */ HDassert(0); /* This function is not yet used. We shouldn't be in here yet. */ diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 9f10409..0c7631a 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -1180,6 +1180,9 @@ H5_DLL herr_t H5C_stats(H5C_t * cache_ptr, H5_DLL void H5C_stats__reset(H5C_t * cache_ptr); +H5_DLL herr_t H5C_dump_cache(H5C_t * cache_ptr, + const char * cache_name); + H5_DLL herr_t H5C_unpin_entry(void *thing); H5_DLL herr_t H5C_destroy_flush_dependency(void *parent_thing, void *child_thing); @@ -256,6 +256,20 @@ H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset") done: + /* Release the dataset's object header, if it was created */ + if(dset) { + H5O_loc_t *oloc; /* Object location for dataset */ + + /* Get the new dataset's object location */ + if(NULL == (oloc = H5D_oloc(dset))) + HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get object location of dataset") + + /* Decrement refcount on dataset's object header in memory */ + if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") + } /* end if */ + + /* Cleanup on failure */ if(ret_value < 0) if(dset && H5D_close(dset) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index a2b3a37..06a25b4 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -822,7 +822,7 @@ done: */ static herr_t H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info, const H5S_t UNUSED *space, - haddr_t UNUSED dset_ohdr_addr) + haddr_t dset_ohdr_addr) { herr_t ret_value = SUCCEED; /* Return value */ @@ -836,6 +836,8 @@ H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info, const H5S_t UNUSED *space HDassert(idx_info->storage); HDassert(H5F_addr_defined(dset_ohdr_addr)); + idx_info->storage->u.btree.dset_ohdr_addr = dset_ohdr_addr; + /* Allocate the shared structure */ if(H5D_btree_shared_create(idx_info->f, idx_info->storage, idx_info->layout->ndims) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 910497b..e7a5bf1 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -108,7 +108,7 @@ typedef struct H5D_chunk_it_ud1_t { const H5D_chk_idx_info_t *idx_info; /* Chunked index info */ const H5D_io_info_t *io_info; /* I/O info for dataset operation */ const hsize_t *space_dim; /* New dataset dimensions */ - const hbool_t *shrunk_dim; /* Dimensions which have been shrunk */ + const hbool_t *shrunk_dim; /* Dimensions which have been shrunk */ H5S_t *chunk_space; /* Dataspace for a chunk */ uint32_t elmts_per_chunk;/* Elements in chunk */ hsize_t *hyper_start; /* Starting location of hyperslab */ @@ -649,7 +649,7 @@ H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info #ifdef H5_HAVE_PARALLEL && !(io_info->using_mpi_vfd) #endif /* H5_HAVE_PARALLEL */ - ) { + && H5S_SEL_ALL != H5S_GET_SELECT_TYPE(file_space)) { /* Initialize skip list for chunk selections */ fm->sel_chunks = NULL; fm->use_single = TRUE; @@ -2253,6 +2253,7 @@ H5D_chunk_lookup(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset, udata->common.layout = &(dset->shared->layout.u.chunk); udata->common.storage = &(dset->shared->layout.storage.u.chunk); udata->common.offset = chunk_offset; + udata->common.rdcc = &(dset->shared->cache.chunk); /* Reset information about the chunk we are looking for */ udata->nbytes = 0; @@ -2265,7 +2266,8 @@ H5D_chunk_lookup(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset, ent = dset->shared->cache.chunk.slot[udata->idx_hint]; if(ent) - for(u = 0, found = TRUE; u < dset->shared->layout.u.chunk.ndims; u++) + for(u = 0, found = TRUE; u < dset->shared->layout.u.chunk.ndims - 1; + u++) if(chunk_offset[u] != ent->offset[u]) { found = FALSE; break; @@ -2344,6 +2346,7 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t * udata.common.layout = &dset->shared->layout.u.chunk; udata.common.storage = &dset->shared->layout.storage.u.chunk; udata.common.offset = ent->offset; + udata.common.rdcc = &(dset->shared->cache.chunk); udata.filter_mask = 0; udata.nbytes = dset->shared->layout.u.chunk.size; udata.addr = ent->chunk_addr; @@ -3282,7 +3285,7 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite, chunk_offset[op_dim] = min_unalloc[op_dim]; carry = FALSE; - } /* end if */ + } /* end else */ while(!carry) { size_t chunk_size = orig_chunk_size; /* Size of chunk in bytes, possibly filtered */ @@ -3360,6 +3363,7 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite, udata.common.layout = &layout->u.chunk; udata.common.storage = &layout->storage.u.chunk; udata.common.offset = chunk_offset; + udata.common.rdcc = NULL; H5_ASSIGN_OVERFLOW(udata.nbytes, chunk_size, size_t, uint32_t); udata.filter_mask = filter_mask; udata.addr = HADDR_UNDEF; @@ -3412,9 +3416,9 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite, } /* end for */ } /* end while(!carry) */ - /* Adjust max_unalloc_dim_idx so we don't allocate the same chunk twice. - * Also check if this dimension started from 0 (and hence allocated all - * of the chunks. */ + /* Adjust max_unalloc so we don't allocate the same chunk twice. Also + * check if this dimension started from 0 (and hence allocated all of + * the chunks. */ if(min_unalloc[op_dim] == 0) break; else @@ -3764,6 +3768,7 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim) HDmemset(&udata, 0, sizeof udata); udata.common.layout = &layout->u.chunk; udata.common.storage = &layout->storage.u.chunk; + udata.common.rdcc = rdcc; udata.io_info = &chk_io_info; udata.idx_info = &idx_info; udata.space_dim = space_dim; @@ -4041,7 +4046,8 @@ H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[]) HDmemset(&udata, 0, sizeof(udata)); udata.common.layout = &dset->shared->layout.u.chunk; udata.common.storage = &dset->shared->layout.storage.u.chunk; - udata.chunk_addr = chunk_addr; + udata.common.rdcc = &(dset->shared->cache.chunk); + udata.chunk_addr = chunk_addr; /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; @@ -4365,6 +4371,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) udata_dst.common.layout = udata->idx_info_dst->layout; udata_dst.common.storage = udata->idx_info_dst->storage; udata_dst.common.offset = chunk_rec->offset; + udata_dst.common.rdcc = NULL; udata_dst.nbytes = chunk_rec->nbytes; udata_dst.filter_mask = chunk_rec->filter_mask; udata_dst.addr = HADDR_UNDEF; @@ -4608,6 +4615,7 @@ H5D_chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src, HDmemset(&udata, 0, sizeof udata); udata.common.layout = layout_src; udata.common.storage = storage_src; + udata.common.rdcc = NULL; udata.file_src = f_src; udata.idx_info_dst = &idx_info_dst; udata.buf = buf; diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index 9b4f338..9a6e08f 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -1301,7 +1301,7 @@ H5D_contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, void *reclaim_buf = NULL; /* Buffer for reclaiming data */ H5S_t *buf_space = NULL; /* Dataspace describing buffer */ hid_t buf_sid = -1; /* ID for buffer dataspace */ - hsize_t buf_dim; /* Dimension for buffer */ + hsize_t buf_dim[1] = {0}; /* Dimension for buffer */ hbool_t is_vlen = FALSE; /* Flag to indicate that VL type conversion should occur */ hbool_t fix_ref = FALSE; /* Flag to indicate that ref values should be fixed */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1382,10 +1382,10 @@ H5D_contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, buf_size = nelmts * max_dt_size; /* Create dataspace for number of elements in buffer */ - buf_dim = nelmts; + buf_dim[0] = nelmts; /* Create the space and set the initial extent */ - if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL))) + if(NULL == (buf_space = H5S_create_simple((unsigned)1, buf_dim, NULL))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") /* Atomize */ @@ -1441,10 +1441,10 @@ H5D_contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, mem_nbytes = nelmts * mem_dt_size; /* Adjust size of buffer's dataspace dimension */ - buf_dim = nelmts; + buf_dim[0] = nelmts; /* Adjust size of buffer's dataspace */ - if(H5S_set_extent_real(buf_space, &buf_dim) < 0) + if(H5S_set_extent_real(buf_space, buf_dim) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to change buffer dataspace size") } /* end if */ else diff --git a/src/H5Dint.c b/src/H5Dint.c index 4c076f7..947c0fe 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -789,7 +789,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) ohdr_size += layout->storage.u.compact.size; /* Create an object header for the dataset */ - if(H5O_create(file, dxpl_id, ohdr_size, dset->shared->dcpl_id, oloc/*out*/) < 0) + if(H5O_create(file, dxpl_id, ohdr_size, (size_t)1, dset->shared->dcpl_id, oloc/*out*/) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset object header") HDassert(file == dset->oloc.file); @@ -1063,6 +1063,8 @@ done: if(new_dset->shared->type && H5I_dec_ref(new_dset->shared->type_id) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release datatype") if(H5F_addr_defined(new_dset->oloc.addr)) { + if(H5O_dec_rc_by_loc(&(new_dset->oloc), dxpl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object") if(H5O_close(&(new_dset->oloc)) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release object header") if(file) { diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 96acc58..44b44d9 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -253,6 +253,9 @@ typedef struct H5D_chunk_common_ud_t { const H5O_layout_chunk_t *layout; /* Chunk layout description */ const H5O_storage_chunk_t *storage; /* Chunk storage description */ const hsize_t *offset; /* Logical offset of chunk */ + const struct H5D_rdcc_t *rdcc; /* Chunk cache. Only necessary if the index may + * be modified, and if any chunks in the dset + * may be cached */ } H5D_chunk_common_ud_t; /* B-tree callback info for various operations */ @@ -170,13 +170,20 @@ H5E_set_default_auto(H5E_t *stk) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5E_set_default_auto) -#ifdef H5_USE_16_API +#ifndef H5_NO_DEPRECATED_SYMBOLS +#ifdef H5_USE_16_API_DEFAULT stk->auto_op.vers = 1; - stk->auto_op.u.func1 = (H5E_auto1_t)H5Eprint1; #else /* H5_USE_16_API */ stk->auto_op.vers = 2; - stk->auto_op.u.func2 = (H5E_auto2_t)H5Eprint2; -#endif /* H5_USE_16_API */ +#endif /* H5_USE_16_API_DEFAULT */ + + stk->auto_op.func1 = stk->auto_op.func1_default = (H5E_auto1_t)H5Eprint1; + stk->auto_op.func2 = stk->auto_op.func2_default = (H5E_auto2_t)H5Eprint2; + stk->auto_op.is_default = TRUE; +#else /* H5_NO_DEPRECATED_SYMBOLS */ + stk->auto_op.func2 = (H5E_auto2_t)H5Eprint2; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + stk->auto_data = NULL; FUNC_LEAVE_NOAPI(SUCCEED) @@ -1555,6 +1562,11 @@ done: * Programmer: Robb Matzke * Saturday, February 28, 1998 * + * Modification:Raymond Lu + * 4 October 2010 + * If the printing function isn't the default H5Eprint1 or 2, + * and H5Eset_auto1 has been called to set the old style + * printing function, a call to H5Eget_auto2 should fail. *------------------------------------------------------------------------- */ herr_t @@ -1578,8 +1590,15 @@ H5Eget_auto2(hid_t estack_id, H5E_auto2_t *func, void **client_data) /* Get the automatic error reporting information */ if(H5E_get_auto(estack, &op, client_data) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info") + +#ifndef H5_NO_DEPRECATED_SYMBOLS + /* Fail if the printing function isn't the default(user-set) and set through H5Eset_auto1 */ + if(!op.is_default && op.vers == 1) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "wrong API function, H5Eset_auto1 has been called") +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + if(func) - *func = op.u.func2; + *func = op.func2; done: FUNC_LEAVE_API(ret_value) @@ -1606,6 +1625,9 @@ done: * Programmer: Robb Matzke * Friday, February 27, 1998 * + * Modification:Raymond Lu + * 4 October 2010 + * If the FUNC is H5Eprint2, put the IS_DEFAULT flag on. *------------------------------------------------------------------------- */ herr_t @@ -1627,9 +1649,23 @@ H5Eset_auto2(hid_t estack_id, H5E_auto2_t func, void *client_data) if(NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") +#ifndef H5_NO_DEPRECATED_SYMBOLS + /* Get the automatic error reporting information */ + if(H5E_get_auto(estack, &op, NULL) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info") + /* Set the automatic error reporting information */ + if(func != op.func2_default) + op.is_default = FALSE; + else + op.is_default = TRUE; + op.vers = 2; - op.u.func2 = func; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + + /* Set the automatic error reporting function */ + op.func2 = func; + if(H5E_set_auto(estack, &op, client_data) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set automatic error info") @@ -1672,7 +1708,11 @@ H5Eauto_is_v2(hid_t estack_id, unsigned *is_stack) /* Check if the error stack reporting function is the "newer" stack type */ if(is_stack) +#ifndef H5_NO_DEPRECATED_SYMBOLS *is_stack = estack->auto_op.vers > 1; +#else + *is_stack = 1; +#endif done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Edeprec.c b/src/H5Edeprec.c index 30f3ae9..0a028d9 100644 --- a/src/H5Edeprec.c +++ b/src/H5Edeprec.c @@ -370,6 +370,11 @@ done: * Programmer: Raymond Lu * Sep 16, 2003 * + * Modification:Raymond Lu + * 4 October 2010 + * If the printing function isn't the default H5Eprint1 or 2, + * and H5Eset_auto2 has been called to set the new style + * printing function, a call to H5Eget_auto1 should fail. *------------------------------------------------------------------------- */ herr_t @@ -389,8 +394,13 @@ H5Eget_auto1(H5E_auto1_t *func, void **client_data) /* Get the automatic error reporting information */ if(H5E_get_auto(estack, &auto_op, client_data) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info") + + /* Fail if the printing function isn't the default(user-set) and set through H5Eset_auto2 */ + if(!auto_op.is_default && auto_op.vers == 2) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "wrong API function, H5Eset_auto2 has been called") + if(func) - *func = auto_op.u.func1; + *func = auto_op.func1; done: FUNC_LEAVE_API(ret_value) @@ -418,6 +428,9 @@ done: * Programmer: Raymond Lu * Sep 16, 2003 * + * Modification:Raymond Lu + * 4 October 2010 + * If the FUNC is H5Eprint2, put the IS_DEFAULT flag on. *------------------------------------------------------------------------- */ herr_t @@ -434,9 +447,18 @@ H5Eset_auto1(H5E_auto1_t func, void *client_data) if(NULL == (estack = H5E_get_my_stack())) /*lint !e506 !e774 Make lint 'constant value Boolean' in non-threaded case */ HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") + /* Get the automatic error reporting information */ + if(H5E_get_auto(estack, &auto_op, NULL) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info") + /* Set the automatic error reporting information */ auto_op.vers = 1; - auto_op.u.func1 = func; + if(func != auto_op.func1_default) + auto_op.is_default = FALSE; + else + auto_op.is_default = TRUE; + auto_op.func1 = func; + if(H5E_set_auto(estack, &auto_op, client_data) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set automatic error info") diff --git a/src/H5Eint.c b/src/H5Eint.c index 584ba40..f650581 100644 --- a/src/H5Eint.c +++ b/src/H5Eint.c @@ -1011,18 +1011,20 @@ H5E_dump_api_stack(hbool_t is_api) H5E_t *estack = H5E_get_my_stack(); HDassert(estack); + +#ifdef H5_NO_DEPRECATED_SYMBOLS + if(estack->auto_op.func2) + (void)((estack->auto_op.func2)(H5E_DEFAULT, estack->auto_data)); +#else /* H5_NO_DEPRECATED_SYMBOLS */ if(estack->auto_op.vers == 1) { -#ifndef H5_NO_DEPRECATED_SYMBOLS - if(estack->auto_op.u.func1) - (void)((estack->auto_op.u.func1)(estack->auto_data)); -#else /* H5_NO_DEPRECATED_SYMBOLS */ - HDassert(0 && "version 1 error stack dump without deprecated symbols!"); -#endif /* H5_NO_DEPRECATED_SYMBOLS */ + if(estack->auto_op.func1) + (void)((estack->auto_op.func1)(estack->auto_data)); } /* end if */ else { - if(estack->auto_op.u.func2) - (void)((estack->auto_op.u.func2)(H5E_DEFAULT, estack->auto_data)); + if(estack->auto_op.func2) + (void)((estack->auto_op.func2)(H5E_DEFAULT, estack->auto_data)); } /* end else */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ } /* end if */ done: diff --git a/src/H5Epkg.h b/src/H5Epkg.h index a85ddc9..9a1163a 100644 --- a/src/H5Epkg.h +++ b/src/H5Epkg.h @@ -68,15 +68,20 @@ /****************************/ /* Some syntactic sugar to make the compiler happy with two different kinds of callbacks */ -typedef struct { - unsigned vers; /* Which version callback to use */ - union { #ifndef H5_NO_DEPRECATED_SYMBOLS - H5E_auto1_t func1; /* Old-style callback, NO error stack param. */ -#endif /* H5_NO_DEPRECATED_SYMBOLS */ - H5E_auto2_t func2; /* New-style callback, with error stack param. */ - }u; +typedef struct { + unsigned vers; /* Which version callback to use */ + hbool_t is_default; /* If the printing function is the library's own. */ + H5E_auto1_t func1; /* Old-style callback, NO error stack param. */ + H5E_auto2_t func2; /* New-style callback, with error stack param. */ + H5E_auto1_t func1_default; /* The saved library's default function - old style. */ + H5E_auto2_t func2_default; /* The saved library's default function - new style. */ +} H5E_auto_op_t; +#else /* H5_NO_DEPRECATED_SYMBOLS */ +typedef struct { + H5E_auto_t func2; /* Only the new style callback function is available. */ } H5E_auto_op_t; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Some syntactic sugar to make the compiler happy with two different kinds of callbacks */ typedef struct { @@ -1048,7 +1048,7 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) } /* end if */ /* Destroy other components of the file */ - if(H5F_accum_reset(f, dxpl_id) < 0) + if(H5F_accum_reset(f, dxpl_id, TRUE) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") if(H5FO_dest(f) < 0) diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index 70b33f7..29fd84f 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -120,7 +120,7 @@ typedef struct H5FD_direct_t { # define file_offset_t off64_t # define file_seek lseek64 # define file_truncate ftruncate64 -#elif defined (_WIN32) && !defined(__MWERKS__) +#elif defined (_WIN32) # /*MSVC*/ # define file_offset_t __int64 # define file_seek _lseeki64 diff --git a/src/H5FDlog.c b/src/H5FDlog.c index c21fc92..96df596 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -35,27 +35,18 @@ #include "H5Fprivate.h" /* File access */ #include "H5FDprivate.h" /* File drivers */ #include "H5FDlog.h" /* Logging file driver */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#ifdef MAX -#undef MAX -#define MAX(X,Y) ((X)>(Y)?(X):(Y)) -#endif /* MAX */ - /* The driver identification number, initialized at runtime */ static hid_t H5FD_LOG_g = 0; -/* File operations */ -#define OP_UNKNOWN 0 -#define OP_READ 1 -#define OP_WRITE 2 - /* Driver-specific file access properties */ typedef struct H5FD_log_fapl_t { char *logfile; /* Allocated log file name */ - unsigned flags; /* Flags for logging behavior */ + unsigned long long flags; /* Flags for logging behavior */ size_t buf_size; /* Size of buffers for track flavor and number of times each byte is accessed */ } H5FD_log_fapl_t; @@ -88,20 +79,19 @@ typedef struct H5FD_log_t { haddr_t eoa; /*end of allocated region */ haddr_t eof; /*end of file; current file size*/ haddr_t pos; /*current file I/O position */ - int op; /*last operation */ - unsigned char *nread; /* Number of reads from a file location */ - unsigned char *nwrite; /* Number of write to a file location */ - unsigned char *flavor; /* Flavor of information written to file location */ - size_t iosize; /* Size of I/O information buffers */ - FILE *logfp; /* Log file pointer */ - H5FD_log_fapl_t fa; /*driver-specific file access properties*/ + H5FD_file_op_t op; /*last operation */ + char filename[H5FD_MAX_FILENAME_LEN]; /* Copy of file name from open operation */ #ifndef _WIN32 /* * On most systems the combination of device and i-node number uniquely * identify a file. */ dev_t device; /*file device number */ +#ifdef H5_VMS + ino_t inode[3]; /*file i-node number */ +#else ino_t inode; /*file i-node number */ +#endif /*H5_VMS*/ #else /* * On _WIN32 the low-order word of a unique identifier associated with the @@ -115,6 +105,25 @@ typedef struct H5FD_log_t { DWORD fileindexlo; DWORD fileindexhi; #endif + + /* Information from properties set by 'h5repart' tool */ + hbool_t fam_to_sec2; /* Whether to eliminate the family driver info + * and convert this file to a single file */ + + /* Fields for tracking I/O operations */ + unsigned char *nread; /* Number of reads from a file location */ + unsigned char *nwrite; /* Number of write to a file location */ + unsigned char *flavor; /* Flavor of information written to file location */ + unsigned long long total_read_ops; /* Total number of read operations */ + unsigned long long total_write_ops; /* Total number of write operations */ + unsigned long long total_seek_ops; /* Total number of seek operations */ + unsigned long long total_truncate_ops; /* Total number of truncate operations */ + double total_read_time; /* Total time spent in read operations */ + double total_write_time; /* Total time spent in write operations */ + double total_seek_time; /* Total time spent in seek operations */ + size_t iosize; /* Size of I/O information buffers */ + FILE *logfp; /* Log file pointer */ + H5FD_log_fapl_t fa; /* Driver-specific file access properties*/ } H5FD_log_t; @@ -123,34 +132,14 @@ typedef struct H5FD_log_t { * some macros here so we don't have to have conditional compilations later * throughout the code. * - * file_offset_t: The datatype for file offsets, the second argument of - * the lseek() or lseek64() call. + * HDoff_t: The datatype for file offsets, the second argument of + * the lseek() or lseek64() call. * - * file_seek: The function which adjusts the current file position, - * either lseek() or lseek64(). */ -/* adding for windows NT file system support. */ - -#ifdef H5_HAVE_LSEEK64 -# define file_offset_t off64_t -# define file_seek lseek64 -#elif defined (_WIN32) -# ifdef __MWERKS__ -# define file_offset_t off_t -# define file_seek lseek -# else /*MSVC*/ -# define file_offset_t __int64 -# define file_seek _lseeki64 -# endif -#else -# define file_offset_t off_t -# define file_seek lseek -#endif - /* * These macros check for overflow of various quantities. These macros - * assume that file_offset_t is signed and haddr_t and size_t are unsigned. + * assume that HDoff_t is signed and haddr_t and size_t are unsigned. * * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' * is too large to be represented by the second argument @@ -163,14 +152,13 @@ typedef struct H5FD_log_t { * which can be addressed entirely by the second * argument of the file seek function. */ -#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1) +#define MAXADDR (((haddr_t)1<<(8*sizeof(HDoff_t)-1))-1) #define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ ((A) & ~(haddr_t)MAXADDR)) #define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) #define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ - sizeof(file_offset_t)<sizeof(size_t) || \ HADDR_UNDEF==(A)+(Z) || \ - (file_offset_t)((A)+(Z))<(file_offset_t)(A)) + (HDoff_t)((A)+(Z))<(HDoff_t)(A)) /* Prototypes */ static void *H5FD_log_fapl_get(H5FD_t *file); @@ -192,21 +180,6 @@ static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, hadd size_t size, const void *buf); static herr_t H5FD_log_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); -#ifdef OLD_WAY -/* - * The free list map which causes each request type to use no free lists - */ -#define H5FD_FLMAP_NOLIST { \ - H5FD_MEM_NOLIST, /*default*/ \ - H5FD_MEM_NOLIST, /*super*/ \ - H5FD_MEM_NOLIST, /*btree*/ \ - H5FD_MEM_NOLIST, /*draw*/ \ - H5FD_MEM_NOLIST, /*gheap*/ \ - H5FD_MEM_NOLIST, /*lheap*/ \ - H5FD_MEM_NOLIST /*ohdr*/ \ -} -#endif /* OLD_WAY */ - static const H5FD_class_t H5FD_log_g = { "log", /*name */ MAXADDR, /*maxaddr */ @@ -241,6 +214,9 @@ static const H5FD_class_t H5FD_log_g = { H5FD_FLMAP_SINGLE /*fl_map */ }; +/* Declare a free list to manage the H5FD_log_t struct */ +H5FL_DEFINE_STATIC(H5FD_log_t); + /*-------------------------------------------------------------------------- NAME @@ -271,32 +247,29 @@ H5FD_log_init_interface(void) * library. * * Return: Success: The driver ID for the log driver. - * * Failure: Negative. * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ hid_t H5FD_log_init(void) { - hid_t ret_value; /* Return value */ + hid_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5FD_log_init, FAIL) - if (H5I_VFL!=H5Iget_type(H5FD_LOG_g)) - H5FD_LOG_g = H5FD_register(&H5FD_log_g,sizeof(H5FD_class_t),FALSE); + if(H5I_VFL != H5I_get_type(H5FD_LOG_g)) + H5FD_LOG_g = H5FD_register(&H5FD_log_g, sizeof(H5FD_class_t), FALSE); /* Set return value */ - ret_value=H5FD_LOG_g; + ret_value = H5FD_LOG_g; done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_init() */ /*--------------------------------------------------------------------------- @@ -309,8 +282,6 @@ done: * Programmer: Quincey Koziol * Friday, Jan 30, 2004 * - * Modification: - * *--------------------------------------------------------------------------- */ void @@ -319,7 +290,7 @@ H5FD_log_term(void) FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_term) /* Reset VFL ID */ - H5FD_LOG_g=0; + H5FD_LOG_g = 0; FUNC_LEAVE_NOAPI_VOID } /* end H5FD_log_term() */ @@ -337,16 +308,10 @@ H5FD_log_term(void) * Programmer: Robb Matzke * Thursday, February 19, 1998 * - * Modifications: - * We copy the LOGFILE value into our own access properties. - * - * Raymond Lu, 2001-10-25 - * Changed the file access list to the new generic property list. - * *------------------------------------------------------------------------- */ herr_t -H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_size) +H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned long long flags, size_t buf_size) { H5FD_log_fapl_t fa; /* File access property list information */ H5P_genplist_t *plist; /* Property list pointer */ @@ -355,7 +320,7 @@ H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_s FUNC_ENTER_API(H5Pset_fapl_log, FAIL) H5TRACE4("e", "i*sIuz", fapl_id, logfile, flags, buf_size); - if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS))) + if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") fa.logfile = (char *)logfile; @@ -377,28 +342,24 @@ done: * * Return: Success: Ptr to new file access property list with all * members copied from the file struct. - * * Failure: NULL * * Programmer: Quincey Koziol * Thursday, April 20, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static void * H5FD_log_fapl_get(H5FD_t *_file) { - H5FD_log_t *file = (H5FD_log_t*)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; void *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_fapl_get, NULL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_fapl_get) /* Set return value */ - ret_value= H5FD_log_fapl_copy(&(file->fa)); + ret_value = H5FD_log_fapl_copy(&(file->fa)); -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_log_fapl_get() */ @@ -423,7 +384,7 @@ H5FD_log_fapl_copy(const void *_old_fa) H5FD_log_fapl_t *new_fa = NULL; /* New FAPL info */ void *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_fapl_copy, NULL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_fapl_copy) HDassert(old_fa); @@ -499,22 +460,29 @@ H5FD_log_fapl_free(void *_fa) *------------------------------------------------------------------------- */ static H5FD_t * -H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, - haddr_t maxaddr) +H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - int o_flags; - int fd = (-1); H5FD_log_t *file = NULL; - H5FD_log_fapl_t *fa; /* File access property list information */ + H5P_genplist_t *plist; /* Property list */ + H5FD_log_fapl_t *fa; /* File access property list information */ + int fd = (-1); /* File descriptor */ + int o_flags; /* Flags for open() call */ #ifdef _WIN32 HFILE filehandle; struct _BY_HANDLE_FILE_INFORMATION fileinfo; #endif - h5_stat_t sb; - H5P_genplist_t *plist; /* Property list */ - H5FD_t *ret_value; +#ifdef H5_HAVE_GETTIMEOFDAY + struct timeval timeval_start; + struct timeval open_timeval_diff; + struct timeval stat_timeval_diff; +#endif /* H5_HAVE_GETTIMEOFDAY */ + h5_stat_t sb; + H5FD_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_open) - FUNC_ENTER_NOAPI(H5FD_log_open, NULL) + /* Sanity check on file offsets */ + HDcompile_assert(sizeof(HDoff_t) >= sizeof(size_t)); /* Check arguments */ if(!name || !*name) @@ -533,22 +501,65 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, if(H5F_ACC_EXCL & flags) o_flags |= O_EXCL; - /* Open the file */ - if((fd = HDopen(name, o_flags, 0666)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") - if(HDfstat(fd, &sb) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") - - /* Create the new file struct */ - if(NULL == (file = (H5FD_log_t *)H5MM_calloc(sizeof(H5FD_log_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") - /* Get the driver specific information */ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") fa = (H5FD_log_fapl_t *)H5P_get_driver_info(plist); HDassert(fa); +#ifdef H5_HAVE_GETTIMEOFDAY + if(fa->flags & H5FD_LOG_TIME_OPEN) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + /* Open the file */ + if((fd = HDopen(name, o_flags, 0666)) < 0) { + int myerrno = errno; + + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', errno = %d, error message = '%s', flags = %x, o_flags = %x", name, myerrno, HDstrerror(myerrno), flags, (unsigned)o_flags); + } /* end if */ +#ifdef H5_HAVE_GETTIMEOFDAY + if(fa->flags & H5FD_LOG_TIME_OPEN) { + struct timeval timeval_stop; + + HDgettimeofday(&timeval_stop, NULL); + + /* Calculate the elapsed gettimeofday time */ + open_timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + open_timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(open_timeval_diff.tv_usec < 0) { + open_timeval_diff.tv_usec += 1000000; + open_timeval_diff.tv_sec--; + } /* end if */ + } /* end if */ +#endif /* H5_HAVE_GETTIMEOFDAY */ + +#ifdef H5_HAVE_GETTIMEOFDAY + if(fa->flags & H5FD_LOG_TIME_STAT) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + /* Get the file stats */ + if(HDfstat(fd, &sb) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") +#ifdef H5_HAVE_GETTIMEOFDAY + if(fa->flags & H5FD_LOG_TIME_STAT) { + struct timeval timeval_stop; + + HDgettimeofday(&timeval_stop, NULL); + + /* Calculate the elapsed gettimeofday time */ + stat_timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + stat_timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(stat_timeval_diff.tv_usec < 0) { + stat_timeval_diff.tv_usec += 1000000; + stat_timeval_diff.tv_sec--; + } /* end if */ + } /* end if */ +#endif /* H5_HAVE_GETTIMEOFDAY */ + + /* Create the new file struct */ + if(NULL == (file = H5FL_CALLOC(H5FD_log_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") + file->fd = fd; H5_ASSIGN_OVERFLOW(file->eof, sb.st_size, h5_stat_size_t, haddr_t); file->pos = HADDR_UNDEF; @@ -558,16 +569,28 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, (void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo); file->fileindexhi = fileinfo.nFileIndexHigh; file->fileindexlo = fileinfo.nFileIndexLow; -#else +#else /* _WIN32 */ file->device = sb.st_dev; +#ifdef H5_VMS + file->inode[0] = sb.st_ino[0]; + file->inode[1] = sb.st_ino[1]; + file->inode[2] = sb.st_ino[2]; +#else file->inode = sb.st_ino; -#endif +#endif /*H5_VMS*/ + +#endif /* _WIN32 */ + + /* Retain a copy of the name used to open the file, for possible error reporting */ + HDstrncpy(file->filename, name, sizeof(file->filename)); + file->filename[sizeof(file->filename) - 1] = '\0'; /* Get the flags for logging */ file->fa.flags = fa->flags; /* Check if we are doing any logging at all */ if(file->fa.flags != 0) { + /* Allocate buffers for tracking file accesses and data "flavor" */ file->iosize = fa->buf_size; if(file->fa.flags & H5FD_LOG_FILE_READ) { file->nread = (unsigned char *)H5MM_calloc(file->iosize); @@ -581,10 +604,32 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, file->flavor = (unsigned char *)H5MM_calloc(file->iosize); HDassert(file->flavor); } /* end if */ + + /* Set the log file pointer */ if(fa->logfile) file->logfp = HDfopen(fa->logfile, "w"); else file->logfp = stderr; + +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_OPEN) + HDfprintf(file->logfp, "Open took: (%f s)\n", (double)open_timeval_diff.tv_sec + ((double)open_timeval_diff.tv_usec / (double)1000000.0)); + if(file->fa.flags & H5FD_LOG_TIME_STAT) + HDfprintf(file->logfp, "Stat took: (%f s)\n", (double)stat_timeval_diff.tv_sec + ((double)stat_timeval_diff.tv_usec / (double)1000000.0)); +#endif /* H5_HAVE_GETTIMEOFDAY */ + + } /* end if */ + + /* Check for non-default FAPL */ + if(H5P_FILE_ACCESS_DEFAULT != fapl_id) { + /* This step is for h5repart tool only. If user wants to change file driver from + * family to sec2 while using h5repart, this private property should be set so that + * in the later step, the library can ignore the family driver information saved + * in the superblock. + */ + if(H5P_exist_plist(plist, H5F_ACS_FAMILY_TO_SEC2_NAME) > 0) + if(H5P_get(plist, H5F_ACS_FAMILY_TO_SEC2_NAME, &file->fam_to_sec2) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get property of changing family to sec2") } /* end if */ /* Set return value */ @@ -594,7 +639,8 @@ done: if(NULL == ret_value) { if(fd >= 0) HDclose(fd); - file = (H5FD_log_t *)H5MM_xfree(file); + if(file) + file = H5FL_FREE(H5FD_log_t, file); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -617,24 +663,27 @@ done: static herr_t H5FD_log_close(H5FD_t *_file) { - H5FD_log_t *file = (H5FD_log_t*)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; #ifdef H5_HAVE_GETTIMEOFDAY - struct timeval timeval_start,timeval_stop; - struct timeval timeval_diff; + struct timeval timeval_start, timeval_stop; #endif /* H5_HAVE_GETTIMEOFDAY */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_close) - FUNC_ENTER_NOAPI(H5FD_log_close, FAIL) + /* Sanity check */ + HDassert(file); #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags&H5FD_LOG_TIME_CLOSE) - HDgettimeofday(&timeval_start,NULL); + HDgettimeofday(&timeval_start, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ + /* Close the underlying file */ if(HDclose(file->fd) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + HSYS_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags&H5FD_LOG_TIME_CLOSE) - HDgettimeofday(&timeval_stop,NULL); + HDgettimeofday(&timeval_stop, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ /* Dump I/O information */ @@ -645,6 +694,8 @@ H5FD_log_close(H5FD_t *_file) #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags & H5FD_LOG_TIME_CLOSE) { + struct timeval timeval_diff; + /* Calculate the elapsed gettimeofday time */ timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; @@ -656,6 +707,24 @@ H5FD_log_close(H5FD_t *_file) } /* end if */ #endif /* H5_HAVE_GETTIMEOFDAY */ + /* Dump the total number of seek/read/write operations */ + if(file->fa.flags & H5FD_LOG_NUM_READ) + HDfprintf(file->logfp, "Total number of read operations: %llu\n", file->total_read_ops); + if(file->fa.flags & H5FD_LOG_NUM_WRITE) + HDfprintf(file->logfp, "Total number of write operations: %llu\n", file->total_write_ops); + if(file->fa.flags & H5FD_LOG_NUM_SEEK) + HDfprintf(file->logfp, "Total number of seek operations: %llu\n", file->total_seek_ops); + if(file->fa.flags & H5FD_LOG_NUM_TRUNCATE) + HDfprintf(file->logfp, "Total number of truncate operations: %llu\n", file->total_truncate_ops); + + /* Dump the total time in seek/read/write */ + if(file->fa.flags & H5FD_LOG_TIME_READ) + HDfprintf(file->logfp, "Total time in read operations: %f s\n", file->total_read_time); + if(file->fa.flags & H5FD_LOG_TIME_WRITE) + HDfprintf(file->logfp, "Total time in write operations: %f s\n", file->total_write_time); + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDfprintf(file->logfp, "Total time in seek operations: %f s\n", file->total_seek_time); + /* Dump the write I/O information */ if(file->fa.flags & H5FD_LOG_FILE_WRITE) { HDfprintf(file->logfp, "Dumping write I/O information:\n"); @@ -718,7 +787,8 @@ H5FD_log_close(H5FD_t *_file) fclose(file->logfp); } /* end if */ - H5MM_xfree(file); + /* Release the file info */ + file = H5FL_FREE(H5FD_log_t, file); done: FUNC_LEAVE_NOAPI(ret_value) @@ -732,53 +802,56 @@ done: * arbitrary (but consistent) ordering. * * Return: Success: A value like strcmp() - * * Failure: never fails (arguments were checked by the * caller). * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static int H5FD_log_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { - const H5FD_log_t *f1 = (const H5FD_log_t*)_f1; - const H5FD_log_t *f2 = (const H5FD_log_t*)_f2; - int ret_value=0; + const H5FD_log_t *f1 = (const H5FD_log_t *)_f1; + const H5FD_log_t *f2 = (const H5FD_log_t *)_f2; + int ret_value = 0; - FUNC_ENTER_NOAPI(H5FD_log_cmp, H5FD_VFD_DEFAULT) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_cmp) #ifdef _WIN32 - if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) - if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) + if(f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) + if(f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) - if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) - if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) + if(f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) + if(f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) #else #ifdef H5_DEV_T_IS_SCALAR - if (f1->device < f2->device) HGOTO_DONE(-1) - if (f1->device > f2->device) HGOTO_DONE(1) + if(f1->device < f2->device) HGOTO_DONE(-1) + if(f1->device > f2->device) HGOTO_DONE(1) #else /* H5_DEV_T_IS_SCALAR */ /* If dev_t isn't a scalar value on this system, just use memcmp to * determine if the values are the same or not. The actual return value * shouldn't really matter... */ - if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))<0) HGOTO_DONE(-1) - if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))>0) HGOTO_DONE(1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) < 0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) > 0) HGOTO_DONE(1) #endif /* H5_DEV_T_IS_SCALAR */ - if (f1->inode < f2->inode) HGOTO_DONE(-1) - if (f1->inode > f2->inode) HGOTO_DONE(1) +#ifndef H5_VMS + if(f1->inode < f2->inode) HGOTO_DONE(-1) + if(f1->inode > f2->inode) HGOTO_DONE(1) +#else + if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) < 0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) > 0) HGOTO_DONE(1) +#endif /*H5_VMS*/ + #endif done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_cmp() */ /*------------------------------------------------------------------------- @@ -788,20 +861,18 @@ done: * (listed in H5FDpublic.h) * * Return: Success: non-negative - * * Failure: negative * * Programmer: Quincey Koziol * Friday, August 25, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t -H5FD_log_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) +H5FD_log_query(const H5FD_t *_file, unsigned long *flags /* out */) { + const H5FD_log_t *file = (const H5FD_log_t *)_file; + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_query) /* Set the VFL feature flags that this driver supports */ @@ -812,6 +883,10 @@ H5FD_log_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */ + + /* Check for flags that are set by h5repart */ + if(file->fam_to_sec2) + *flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */ } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) @@ -824,56 +899,52 @@ H5FD_log_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) * Purpose: Allocate file memory. * * Return: Success: Address of new memory - * * Failure: HADDR_UNDEF * * Programmer: Quincey Koziol * Monday, April 17, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ static haddr_t H5FD_log_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, hsize_t size) { - H5FD_log_t *file = (H5FD_log_t*)_file; - haddr_t addr; + H5FD_log_t *file = (H5FD_log_t *)_file; + haddr_t addr; haddr_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_alloc, HADDR_UNDEF) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_alloc) /* Compute the address for the block to allocate */ addr = file->eoa; /* Check if we need to align this block */ - if(size>=file->pub.threshold) { + if(size >= file->pub.threshold) { /* Check for an already aligned block */ - if(addr%file->pub.alignment!=0) - addr=((addr/file->pub.alignment)+1)*file->pub.alignment; + if(addr % file->pub.alignment != 0) + addr = ((addr / file->pub.alignment) + 1) * file->pub.alignment; } /* end if */ - file->eoa = addr+size; + file->eoa = addr + size; /* Retain the (first) flavor of the information written to the file */ - if(file->fa.flags!=0) { - if(file->fa.flags&H5FD_LOG_FLAVOR) { - assert(addr<file->iosize); - H5_CHECK_OVERFLOW(size,hsize_t,size_t); - HDmemset(&file->flavor[addr],(int)type,(size_t)size); + if(file->fa.flags != 0) { + if(file->fa.flags & H5FD_LOG_FLAVOR) { + HDassert(addr < file->iosize); + H5_CHECK_OVERFLOW(size, hsize_t, size_t); + HDmemset(&file->flavor[addr], (int)type, (size_t)size); } /* end if */ - if(file->fa.flags&H5FD_LOG_ALLOC) - HDfprintf(file->logfp,"%10a-%10a (%10Hu bytes) (%s) Allocated\n",addr,addr+size-1,size,flavors[type]); + if(file->fa.flags & H5FD_LOG_ALLOC) + HDfprintf(file->logfp, "%10a-%10a (%10Hu bytes) (%s) Allocated\n", addr, (addr + size) - 1, size, flavors[type]); } /* end if */ /* Set return value */ - ret_value=addr; + ret_value = addr; -done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5FD_log_alloc() */ +} /* end H5FD_log_alloc() */ /*------------------------------------------------------------------------- @@ -884,33 +955,22 @@ done: * format address space. * * Return: Success: The end-of-address marker. - * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Monday, August 2, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static haddr_t H5FD_log_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) { - const H5FD_log_t *file = (const H5FD_log_t*)_file; - haddr_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_log_get_eoa, HADDR_UNDEF) + const H5FD_log_t *file = (const H5FD_log_t *)_file; - /* Set return value */ - ret_value=file->eoa; + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_get_eoa) -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(file->eoa) +} /* end H5FD_log_get_eoa() */ /*------------------------------------------------------------------------- @@ -921,32 +981,24 @@ done: * to tell the driver where the end of the HDF5 data is located. * * Return: Success: 0 - * * Failure: -1 * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static herr_t H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) { - H5FD_log_t *file = (H5FD_log_t*)_file; - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_log_t *file = (H5FD_log_t *)_file; - FUNC_ENTER_NOAPI(H5FD_log_set_eoa, FAIL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_set_eoa) file->eoa = addr; -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD_log_set_eoa() */ /*------------------------------------------------------------------------- @@ -959,30 +1011,22 @@ done: * Return: Success: End of file address, the first address past * the end of the "file", either the Unix file * or the HDF5 file. - * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static haddr_t H5FD_log_get_eof(const H5FD_t *_file) { - const H5FD_log_t *file = (const H5FD_log_t*)_file; - haddr_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_log_get_eof, HADDR_UNDEF) + const H5FD_log_t *file = (const H5FD_log_t *)_file; - /* Set return value */ - ret_value=MAX(file->eof, file->eoa); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_get_eof) -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(MAX(file->eof, file->eoa)) +} /* end H5FD_log_get_eof() */ /*------------------------------------------------------------------------- @@ -995,18 +1039,16 @@ done: * Programmer: Raymond Lu * Sept. 16, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ static herr_t -H5FD_log_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle) +H5FD_log_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void **file_handle) { H5FD_log_t *file = (H5FD_log_t *)_file; herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FD_log_get_handle, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_get_handle) if(!file_handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid") @@ -1015,7 +1057,7 @@ H5FD_log_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle) done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_get_handle() */ /*------------------------------------------------------------------------- @@ -1027,14 +1069,11 @@ done: * * Return: Success: Zero. Result is stored in caller-supplied * buffer BUF. - * * Failure: -1, Contents of buffer BUF are undefined. * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ @@ -1042,91 +1081,171 @@ static herr_t H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, void *buf/*out*/) { - H5FD_log_t *file = (H5FD_log_t*)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; ssize_t nbytes; - herr_t ret_value=SUCCEED; /* Return value */ + size_t orig_size = size; /* Save the original size for later */ + haddr_t orig_addr = addr; +#ifdef H5_HAVE_GETTIMEOFDAY + struct timeval timeval_start, timeval_stop; +#endif /* H5_HAVE_GETTIMEOFDAY */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_read, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_read) - assert(file && file->pub.cls); - assert(buf); + HDassert(file && file->pub.cls); + HDassert(buf); /* Check for overflow conditions */ - if (HADDR_UNDEF==addr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined") - if (REGION_OVERFLOW(addr, size)) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + if(!H5F_addr_defined(addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr) + if(REGION_OVERFLOW(addr, size)) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) if((addr + size) > file->eoa) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) /* Log the I/O information about the read */ - if(file->fa.flags!=0) { - size_t tmp_size=size; - haddr_t tmp_addr=addr; + if(file->fa.flags != 0) { + size_t tmp_size = size; + haddr_t tmp_addr = addr; /* Log information about the number of times these locations are read */ - if(file->fa.flags&H5FD_LOG_FILE_READ) { - assert((addr+size)<file->iosize); - while(tmp_size-->0) + if(file->fa.flags & H5FD_LOG_FILE_READ) { + HDassert((addr + size) < file->iosize); + while(tmp_size-- > 0) file->nread[tmp_addr++]++; } /* end if */ + } /* end if */ - /* Log information about the seek, if it's going to occur */ - if(file->fa.flags&H5FD_LOG_LOC_SEEK) { - if(addr!=file->pos || OP_READ!=file->op) - HDfprintf(file->logfp,"Seek: From %10a To %10a\n",file->pos,addr); - } /* end if */ + /* Seek to the correct location */ + if(addr != file->pos || OP_READ != file->op) { +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + if(HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDgettimeofday(&timeval_stop, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + + /* Log information about the seek */ + if(file->fa.flags & H5FD_LOG_NUM_SEEK) + file->total_seek_ops++; + if(file->fa.flags & H5FD_LOG_LOC_SEEK) { + HDfprintf(file->logfp, "Seek: From %10a To %10a", file->pos, addr); +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_SEEK) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0); + HDfprintf(file->logfp, " (%f s)\n", time_diff); - /* Log information about the read */ - if(file->fa.flags&H5FD_LOG_LOC_READ) { - HDfprintf(file->logfp,"%10a-%10a (%10Zu bytes) (%s) Read\n",addr,addr+size-1,size,flavors[type]); -/* XXX: Verify the flavor information, if we have it? */ + /* Add to total seek time */ + file->total_seek_time += time_diff; + } /* end if */ + else + HDfprintf(file->logfp, "\n"); +#else /* H5_HAVE_GETTIMEOFDAY */ + HDfprintf(file->logfp, "\n"); +#endif /* H5_HAVE_GETTIMEOFDAY */ } /* end if */ } /* end if */ - /* Seek to the correct location */ - if ((addr!=file->pos || OP_READ!=file->op) && - file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) { - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") - } - /* * Read data, being careful of interrupted system calls, partial results, * and the end of the file. */ - while (size>0) { +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_READ) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + while(size > 0) { do { nbytes = HDread(file->fd, buf, size); - } while (-1==nbytes && EINTR==errno); - if (-1==nbytes) { - /* error */ - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") - } - if (0==nbytes) { + } while(-1 == nbytes && EINTR == errno); + if(-1 == nbytes) { /* error */ + int myerrno = errno; + time_t mytime = HDtime(NULL); + HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); + + if(file->fa.flags & H5FD_LOG_LOC_READ) + HDfprintf(file->logfp, "Error! Reading: %10a-%10a (%10Zu bytes)\n", orig_addr, (orig_addr + orig_size) - 1, orig_size); + + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + } /* end if */ + if(0 == nbytes) { /* end of file but not end of format address space */ HDmemset(buf, 0, size); - size = 0; - } - assert(nbytes>=0); - assert((size_t)nbytes<=size); - H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t); + break; + } /* end if */ + HDassert(nbytes >= 0); + HDassert((size_t)nbytes <= size); + H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t); size -= (size_t)nbytes; - H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t); + H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t); addr += (haddr_t)nbytes; - buf = (char*)buf + nbytes; - } + buf = (char *)buf + nbytes; + } /* end while */ +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_READ) + HDgettimeofday(&timeval_stop, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + + /* Log information about the read */ + if(file->fa.flags & H5FD_LOG_NUM_READ) + file->total_read_ops++; + if(file->fa.flags & H5FD_LOG_LOC_READ) { + HDfprintf(file->logfp, "%10a-%10a (%10Zu bytes) (%s) Read", orig_addr, (orig_addr + orig_size) - 1, orig_size, flavors[type]); + + /* XXX: Verify the flavor information, if we have it? */ + +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_READ) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0); + HDfprintf(file->logfp, " (%f s)\n", time_diff); + + /* Add to total read time */ + file->total_read_time += time_diff; + } /* end if */ + else + HDfprintf(file->logfp, "\n"); +#else /* H5_HAVE_GETTIMEOFDAY */ + HDfprintf(file->logfp, "\n"); +#endif /* H5_HAVE_GETTIMEOFDAY */ + } /* end if */ /* Update current position */ file->pos = addr; file->op = OP_READ; done: + if(ret_value < 0) { + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_read() */ /*------------------------------------------------------------------------- @@ -1137,14 +1256,11 @@ done: * DXPL_ID. * * Return: Success: Zero - * * Failure: -1 * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ @@ -1152,80 +1268,86 @@ static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf) { - H5FD_log_t *file = (H5FD_log_t*)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; ssize_t nbytes; - size_t orig_size=size; /* Save the original size for later */ - haddr_t orig_addr=addr; + size_t orig_size = size; /* Save the original size for later */ + haddr_t orig_addr = addr; #ifdef H5_HAVE_GETTIMEOFDAY - struct timeval timeval_start,timeval_stop; - struct timeval timeval_diff; + struct timeval timeval_start, timeval_stop; #endif /* H5_HAVE_GETTIMEOFDAY */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_write, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_write) - assert(file && file->pub.cls); - assert(size>0); - assert(buf); + HDassert(file && file->pub.cls); + HDassert(size > 0); + HDassert(buf); /* Verify that we are writing out the type of data we allocated in this location */ if(file->flavor) { - assert(type==H5FD_MEM_DEFAULT || type==(H5FD_mem_t)file->flavor[addr] || (H5FD_mem_t)file->flavor[addr]==H5FD_MEM_DEFAULT); - assert(type==H5FD_MEM_DEFAULT || type==(H5FD_mem_t)file->flavor[(addr+size)-1] || (H5FD_mem_t)file->flavor[(addr+size)-1]==H5FD_MEM_DEFAULT); + HDassert(type == H5FD_MEM_DEFAULT || type == (H5FD_mem_t)file->flavor[addr] || (H5FD_mem_t)file->flavor[addr] == H5FD_MEM_DEFAULT); + HDassert(type == H5FD_MEM_DEFAULT || type == (H5FD_mem_t)file->flavor[(addr + size) - 1] || (H5FD_mem_t)file->flavor[(addr + size) - 1] == H5FD_MEM_DEFAULT); } /* end if */ /* Check for overflow conditions */ - if (HADDR_UNDEF==addr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined") - if (REGION_OVERFLOW(addr, size)) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") - if (addr+size>file->eoa) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + if(!H5F_addr_defined(addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr) + if(REGION_OVERFLOW(addr, size)) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size = %llu", (unsigned long long)addr, (unsigned long long)size) + if((addr + size) > file->eoa) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size = %llu, eoa = %llu", (unsigned long long)addr, (unsigned long long)size, (unsigned long long)file->eoa) /* Log the I/O information about the write */ - if(file->fa.flags&H5FD_LOG_FILE_WRITE) { - size_t tmp_size=size; - haddr_t tmp_addr=addr; + if(file->fa.flags & H5FD_LOG_FILE_WRITE) { + size_t tmp_size = size; + haddr_t tmp_addr = addr; - assert((addr+size)<file->iosize); - while(tmp_size-->0) + /* Log information about the number of times these locations are read */ + HDassert((addr + size) < file->iosize); + while(tmp_size-- > 0) file->nwrite[tmp_addr++]++; } /* end if */ /* Seek to the correct location */ - if (addr!=file->pos || OP_WRITE!=file->op) { + if(addr != file->pos || OP_WRITE != file->op) { #ifdef H5_HAVE_GETTIMEOFDAY - if(file->fa.flags&H5FD_LOG_TIME_SEEK) - HDgettimeofday(&timeval_start,NULL); + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDgettimeofday(&timeval_start, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ - if(file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) { - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") - } /* end if */ + if(HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") #ifdef H5_HAVE_GETTIMEOFDAY - if(file->fa.flags&H5FD_LOG_TIME_SEEK) - HDgettimeofday(&timeval_stop,NULL); + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDgettimeofday(&timeval_stop, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ /* Log information about the seek */ - if(file->fa.flags&H5FD_LOG_LOC_SEEK) { + if(file->fa.flags & H5FD_LOG_NUM_SEEK) + file->total_seek_ops++; + if(file->fa.flags & H5FD_LOG_LOC_SEEK) { + HDfprintf(file->logfp, "Seek: From %10a To %10a", file->pos, addr); #ifdef H5_HAVE_GETTIMEOFDAY - HDfprintf(file->logfp,"Seek: From %10a To %10a",file->pos,addr); - if(file->fa.flags&H5FD_LOG_TIME_SEEK) { - /* Calculate the elapsed gettimeofday time */ - timeval_diff.tv_usec=timeval_stop.tv_usec-timeval_start.tv_usec; - timeval_diff.tv_sec=timeval_stop.tv_sec-timeval_start.tv_sec; - if(timeval_diff.tv_usec<0) { - timeval_diff.tv_usec+=1000000; - timeval_diff.tv_sec--; - } /* end if */ - HDfprintf(file->logfp," (%f s)\n",(double)timeval_diff.tv_sec+((double)timeval_diff.tv_usec/(double)1000000.0)); + if(file->fa.flags & H5FD_LOG_TIME_SEEK) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0); + HDfprintf(file->logfp, " (%f s)\n", time_diff); + + /* Add to total seek time */ + file->total_seek_time += time_diff; } /* end if */ else - HDfprintf(file->logfp,"\n"); + HDfprintf(file->logfp, "\n"); #else /* H5_HAVE_GETTIMEOFDAY */ - HDfprintf(file->logfp,"Seek: From %10a To %10a\n",file->pos,addr); + HDfprintf(file->logfp, "\n"); #endif /* H5_HAVE_GETTIMEOFDAY */ } /* end if */ } /* end if */ @@ -1236,70 +1358,87 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t add */ #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags&H5FD_LOG_TIME_WRITE) - HDgettimeofday(&timeval_start,NULL); + HDgettimeofday(&timeval_start, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ - while (size>0) { + while(size > 0) { do { nbytes = HDwrite(file->fd, buf, size); - } while (-1==nbytes && EINTR==errno); - if (-1==nbytes) { - /* error */ - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - if(file->fa.flags&H5FD_LOG_LOC_WRITE) - HDfprintf(file->logfp,"Error! Writing: %10a-%10a (%10Zu bytes)\n",orig_addr,orig_addr+orig_size-1,orig_size); - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") - } - assert(nbytes>0); - assert((size_t)nbytes<=size); - H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t); + } while(-1 == nbytes && EINTR == errno); + if(-1 == nbytes) { /* error */ + int myerrno = errno; + time_t mytime = HDtime(NULL); + HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); + + if(file->fa.flags & H5FD_LOG_LOC_WRITE) + HDfprintf(file->logfp, "Error! Writing: %10a-%10a (%10Zu bytes)\n", orig_addr, (orig_addr + orig_size) - 1, orig_size); + + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + } /* end if */ + HDassert(nbytes > 0); + HDassert((size_t)nbytes <= size); + H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t); size -= (size_t)nbytes; - H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t); + H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t); addr += (haddr_t)nbytes; - buf = (const char*)buf + nbytes; - } + buf = (const char *)buf + nbytes; + } /* end while */ #ifdef H5_HAVE_GETTIMEOFDAY - if(file->fa.flags&H5FD_LOG_TIME_WRITE) - HDgettimeofday(&timeval_stop,NULL); + if(file->fa.flags & H5FD_LOG_TIME_WRITE) + HDgettimeofday(&timeval_stop, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ /* Log information about the write */ - if(file->fa.flags&H5FD_LOG_LOC_WRITE) { - HDfprintf(file->logfp,"%10a-%10a (%10Zu bytes) (%s) Written",orig_addr,orig_addr+orig_size-1,orig_size,flavors[type]); + if(file->fa.flags & H5FD_LOG_NUM_WRITE) + file->total_write_ops++; + if(file->fa.flags & H5FD_LOG_LOC_WRITE) { + HDfprintf(file->logfp, "%10a-%10a (%10Zu bytes) (%s) Written", orig_addr, (orig_addr + orig_size) - 1, orig_size, flavors[type]); /* Check if this is the first write into a "default" section, grabbed by the metadata agregation algorithm */ - if(file->fa.flags&H5FD_LOG_FLAVOR) { - if((H5FD_mem_t)file->flavor[orig_addr]==H5FD_MEM_DEFAULT) - HDmemset(&file->flavor[orig_addr],(int)type,orig_size); + if(file->fa.flags & H5FD_LOG_FLAVOR) { + if((H5FD_mem_t)file->flavor[orig_addr] == H5FD_MEM_DEFAULT) + HDmemset(&file->flavor[orig_addr], (int)type, orig_size); } /* end if */ #ifdef H5_HAVE_GETTIMEOFDAY - if(file->fa.flags&H5FD_LOG_TIME_WRITE) { - /* Calculate the elapsed gettimeofday time */ - timeval_diff.tv_usec=timeval_stop.tv_usec-timeval_start.tv_usec; - timeval_diff.tv_sec=timeval_stop.tv_sec-timeval_start.tv_sec; - if(timeval_diff.tv_usec<0) { - timeval_diff.tv_usec+=1000000; - timeval_diff.tv_sec--; - } /* end if */ - HDfprintf(file->logfp," (%f s)\n",(double)timeval_diff.tv_sec+((double)timeval_diff.tv_usec/(double)1000000.0)); + if(file->fa.flags & H5FD_LOG_TIME_WRITE) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0); + HDfprintf(file->logfp, " (%f s)\n", time_diff); + + /* Add to total write time */ + file->total_write_time += time_diff; } /* end if */ else - HDfprintf(file->logfp,"\n"); + HDfprintf(file->logfp, "\n"); #else /* H5_HAVE_GETTIMEOFDAY */ - HDfprintf(file->logfp,"\n"); + HDfprintf(file->logfp, "\n"); #endif /* H5_HAVE_GETTIMEOFDAY */ } /* end if */ /* Update current position and eof */ file->pos = addr; file->op = OP_WRITE; - if (file->pos>file->eof) + if(file->pos > file->eof) file->eof = file->pos; done: + if(ret_value < 0) { + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_write() */ /*------------------------------------------------------------------------- @@ -1318,22 +1457,53 @@ done: */ /* ARGSUSED */ static herr_t -H5FD_log_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing) +H5FD_log_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) { - H5FD_log_t *file = (H5FD_log_t*)_file; - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_log_t *file = (H5FD_log_t *)_file; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_truncate) + + HDassert(file); + + /* Extend the file to make sure it's large enough */ + if(!H5F_addr_eq(file->eoa, file->eof)) { +#ifdef _WIN32 + HFILE filehandle; /* Windows file handle */ + LARGE_INTEGER li; /* 64-bit integer for SetFilePointer() call */ + + /* Map the posix file handle to a Windows file handle */ + filehandle = _get_osfhandle(file->fd); + + /* Translate 64-bit integers into form Windows wants */ + /* [This algorithm is from the Windows documentation for SetFilePointer()] */ + li.QuadPart = (LONGLONG)file->eoa; + (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN); + if(SetEndOfFile((HANDLE)filehandle) == 0) + HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") +#else /* _WIN32 */ +#ifdef H5_VMS + /* Reset seek offset to the beginning of the file, so that the file isn't + * re-extended later. This may happen on Open VMS. */ + if(-1 == HDlseek(file->fd, (HDoff_t)0, SEEK_SET)) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") +#endif - FUNC_ENTER_NOAPI(H5FD_log_truncate, FAIL) + if(-1 == HDftruncate(file->fd, (HDoff_t)file->eoa)) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") +#endif /* _WIN32 */ - if(file->eoa>file->eof) { - if(-1 == file_seek(file->fd, (file_offset_t)(file->eoa - 1), SEEK_SET)) - HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") - if(HDwrite(file->fd, "", (size_t)1) != 1) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + /* Log information about the truncate */ + if(file->fa.flags & H5FD_LOG_NUM_TRUNCATE) + file->total_truncate_ops++; + + /* Update the eof value */ file->eof = file->eoa; - file->pos = file->eoa; - file->op = OP_WRITE; - } + + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5FDlog.h b/src/H5FDlog.h index e829016..bd1bbe2 100644 --- a/src/H5FDlog.h +++ b/src/H5FDlog.h @@ -28,30 +28,32 @@ /* Flags for H5Pset_fapl_log() */ /* Flags for tracking where reads/writes/seeks occur */ -#define H5FD_LOG_LOC_READ 0x0001 -#define H5FD_LOG_LOC_WRITE 0x0002 -#define H5FD_LOG_LOC_SEEK 0x0004 +#define H5FD_LOG_LOC_READ 0x00000001 +#define H5FD_LOG_LOC_WRITE 0x00000002 +#define H5FD_LOG_LOC_SEEK 0x00000004 #define H5FD_LOG_LOC_IO (H5FD_LOG_LOC_READ|H5FD_LOG_LOC_WRITE|H5FD_LOG_LOC_SEEK) /* Flags for tracking number of times each byte is read/written */ -#define H5FD_LOG_FILE_READ 0x0008 -#define H5FD_LOG_FILE_WRITE 0x0010 +#define H5FD_LOG_FILE_READ 0x00000008 +#define H5FD_LOG_FILE_WRITE 0x00000010 #define H5FD_LOG_FILE_IO (H5FD_LOG_FILE_READ|H5FD_LOG_FILE_WRITE) /* Flag for tracking "flavor" (type) of information stored at each byte */ -#define H5FD_LOG_FLAVOR 0x0020 +#define H5FD_LOG_FLAVOR 0x00000020 /* Flags for tracking total number of reads/writes/seeks */ -#define H5FD_LOG_NUM_READ 0x0040 -#define H5FD_LOG_NUM_WRITE 0x0080 -#define H5FD_LOG_NUM_SEEK 0x0100 -#define H5FD_LOG_NUM_IO (H5FD_LOG_NUM_READ|H5FD_LOG_NUM_WRITE|H5FD_LOG_NUM_SEEK) +#define H5FD_LOG_NUM_READ 0x00000040 +#define H5FD_LOG_NUM_WRITE 0x00000080 +#define H5FD_LOG_NUM_SEEK 0x00000100 +#define H5FD_LOG_NUM_TRUNCATE 0x00000200 +#define H5FD_LOG_NUM_IO (H5FD_LOG_NUM_READ|H5FD_LOG_NUM_WRITE|H5FD_LOG_NUM_SEEK|H5FD_LOG_NUM_TRUNCATE) /* Flags for tracking time spent in open/read/write/seek/close */ -#define H5FD_LOG_TIME_OPEN 0x0200 /* Not implemented yet */ -#define H5FD_LOG_TIME_READ 0x0400 /* Not implemented yet */ -#define H5FD_LOG_TIME_WRITE 0x0800 /* Partially implemented (need to track total time) */ -#define H5FD_LOG_TIME_SEEK 0x1000 /* Partially implemented (need to track total time & track time for seeks during reading) */ -#define H5FD_LOG_TIME_CLOSE 0x2000 /* Fully implemented */ -#define H5FD_LOG_TIME_IO (H5FD_LOG_TIME_OPEN|H5FD_LOG_TIME_READ|H5FD_LOG_TIME_WRITE|H5FD_LOG_TIME_SEEK|H5FD_LOG_TIME_CLOSE) +#define H5FD_LOG_TIME_OPEN 0x00000400 +#define H5FD_LOG_TIME_STAT 0x00000800 +#define H5FD_LOG_TIME_READ 0x00001000 +#define H5FD_LOG_TIME_WRITE 0x00002000 +#define H5FD_LOG_TIME_SEEK 0x00004000 +#define H5FD_LOG_TIME_CLOSE 0x00008000 +#define H5FD_LOG_TIME_IO (H5FD_LOG_TIME_OPEN|H5FD_LOG_TIME_STAT|H5FD_LOG_TIME_READ|H5FD_LOG_TIME_WRITE|H5FD_LOG_TIME_SEEK|H5FD_LOG_TIME_CLOSE) /* Flag for tracking allocation of space in file */ -#define H5FD_LOG_ALLOC 0x4000 +#define H5FD_LOG_ALLOC 0x00010000 #define H5FD_LOG_ALL (H5FD_LOG_ALLOC|H5FD_LOG_TIME_IO|H5FD_LOG_NUM_IO|H5FD_LOG_FLAVOR|H5FD_LOG_FILE_IO|H5FD_LOG_LOC_IO) #ifdef __cplusplus @@ -60,10 +62,11 @@ extern "C" { H5_DLL hid_t H5FD_log_init(void); H5_DLL void H5FD_log_term(void); -H5_DLL herr_t H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_size); +H5_DLL herr_t H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned long long flags, size_t buf_size); #ifdef __cplusplus } #endif #endif + diff --git a/src/H5FDmpiposix.c b/src/H5FDmpiposix.c index 5bea8fe..7ca38cc 100644 --- a/src/H5FDmpiposix.c +++ b/src/H5FDmpiposix.c @@ -138,7 +138,7 @@ typedef struct H5FD_mpiposix_t { # define file_offset_t off64_t # define file_seek lseek64 # define file_truncate ftruncate64 -#elif defined (_WIN32) && !defined(__MWERKS__) +#elif defined (_WIN32) # /*MSVC*/ # define file_offset_t __int64 # define file_seek _lseeki64 diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index cb40e5c..fe770d2 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -31,13 +31,40 @@ */ #include "H5FDmpi.h" /* MPI-based file drivers */ -/* Macros */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/* Length of filename buffer */ +#define H5FD_MAX_FILENAME_LEN 1024 + + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/* File operations */ +typedef enum { + OP_UNKNOWN = 0, /* Unknown last file operation */ + OP_READ = 1, /* Last file I/O operation was a read */ + OP_WRITE = 2 /* Last file I/O operation was a write */ +} H5FD_file_op_t; + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/******************************/ +/* Library Private Prototypes */ +/******************************/ /* Forward declarations for prototype arguments */ struct H5P_genplist_t; struct H5F_t; -/* Prototypes */ H5_DLL int H5FD_term_interface(void); H5_DLL H5FD_class_t *H5FD_get_class(hid_t id); H5_DLL hsize_t H5FD_sb_size(H5FD_t *file); diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index d9fa4d9..1153df7 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -42,15 +42,6 @@ /* The driver identification number, initialized at runtime */ static hid_t H5FD_SEC2_g = 0; -/* File operations */ -typedef enum { - OP_UNKNOWN = 0, /* Unknown last file operation */ - OP_READ = 1, /* Last file I/O operation was a read */ - OP_WRITE = 2 /* Last file I/O operation was a write */ -} H5FD_sec2_file_op_t; - -#define H5FD_SEC2_MAX_FILENAME_LEN 1024 - /* * The description of a file belonging to this driver. The `eoa' and `eof' * determine the amount of hdf5 address space in use and the high-water mark @@ -69,8 +60,8 @@ typedef struct H5FD_sec2_t { haddr_t eoa; /*end of allocated region */ haddr_t eof; /*end of file; current file size*/ haddr_t pos; /*current file I/O position */ - H5FD_sec2_file_op_t op; /*last operation */ - char filename[H5FD_SEC2_MAX_FILENAME_LEN]; /* Copy of file name from open operation */ + H5FD_file_op_t op; /*last operation */ + char filename[H5FD_MAX_FILENAME_LEN]; /* Copy of file name from open operation */ #ifndef _WIN32 /* * On most systems the combination of device and i-node number uniquely @@ -165,10 +156,10 @@ static const H5FD_class_t H5FD_sec2_g = { 0, /*dxpl_size */ NULL, /*dxpl_copy */ NULL, /*dxpl_free */ - H5FD_sec2_open, /*open */ - H5FD_sec2_close, /*close */ - H5FD_sec2_cmp, /*cmp */ - H5FD_sec2_query, /*query */ + H5FD_sec2_open, /*open */ + H5FD_sec2_close, /*close */ + H5FD_sec2_cmp, /*cmp */ + H5FD_sec2_query, /*query */ NULL, /*get_type_map */ NULL, /*alloc */ NULL, /*free */ @@ -228,7 +219,7 @@ H5FD_sec2_init_interface(void) hid_t H5FD_sec2_init(void) { - hid_t ret_value; /* Return value */ + hid_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5FD_sec2_init, FAIL) @@ -290,14 +281,14 @@ H5Pset_fapl_sec2(hid_t fapl_id) FUNC_ENTER_API(H5Pset_fapl_sec2, FAIL) H5TRACE1("e", "i", fapl_id); - if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS))) + if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") - ret_value= H5P_set_driver(plist, H5FD_SEC2, NULL); + ret_value = H5P_set_driver(plist, H5FD_SEC2, NULL); done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Pset_fapl_sec2() */ /*------------------------------------------------------------------------- @@ -308,22 +299,19 @@ done: * Return: Success: A pointer to a new file data structure. The * public fields will be initialized by the * caller, which is always H5FD_open(). - * * Failure: NULL * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static H5FD_t * H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { H5FD_sec2_t *file = NULL; /* sec2 VFD info */ - int fd = (-1); /* File descriptor */ - int o_flags; /* Flags for open() call */ + int fd = (-1); /* File descriptor */ + int o_flags; /* Flags for open() call */ #ifdef _WIN32 HFILE filehandle; struct _BY_HANDLE_FILE_INFORMATION fileinfo; @@ -331,10 +319,10 @@ H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) h5_stat_t sb; H5FD_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_open, NULL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_open) /* Sanity check on file offsets */ - HDassert(sizeof(HDoff_t) >= sizeof(size_t)); + HDcompile_assert(sizeof(HDoff_t) >= sizeof(size_t)); /* Check arguments */ if(!name || !*name) @@ -430,7 +418,6 @@ done: * Purpose: Closes a Unix file. * * Return: Success: 0 - * * Failure: -1, file not closed. * * Programmer: Robb Matzke @@ -441,10 +428,10 @@ done: static herr_t H5FD_sec2_close(H5FD_t *_file) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_close, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_close) /* Sanity check */ HDassert(file); @@ -468,59 +455,56 @@ done: * arbitrary (but consistent) ordering. * * Return: Success: A value like strcmp() - * * Failure: never fails (arguments were checked by the * caller). * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static int H5FD_sec2_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { - const H5FD_sec2_t *f1 = (const H5FD_sec2_t*)_f1; - const H5FD_sec2_t *f2 = (const H5FD_sec2_t*)_f2; - int ret_value=0; + const H5FD_sec2_t *f1 = (const H5FD_sec2_t *)_f1; + const H5FD_sec2_t *f2 = (const H5FD_sec2_t *)_f2; + int ret_value = 0; - FUNC_ENTER_NOAPI(H5FD_sec2_cmp, H5FD_VFD_DEFAULT) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_cmp) #ifdef _WIN32 - if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) - if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) + if(f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) + if(f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) - if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) - if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) + if(f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) + if(f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) #else #ifdef H5_DEV_T_IS_SCALAR - if (f1->device < f2->device) HGOTO_DONE(-1) - if (f1->device > f2->device) HGOTO_DONE(1) + if(f1->device < f2->device) HGOTO_DONE(-1) + if(f1->device > f2->device) HGOTO_DONE(1) #else /* H5_DEV_T_IS_SCALAR */ /* If dev_t isn't a scalar value on this system, just use memcmp to * determine if the values are the same or not. The actual return value * shouldn't really matter... */ - if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))<0) HGOTO_DONE(-1) - if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))>0) HGOTO_DONE(1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) < 0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) > 0) HGOTO_DONE(1) #endif /* H5_DEV_T_IS_SCALAR */ #ifndef H5_VMS - if (f1->inode < f2->inode) HGOTO_DONE(-1) - if (f1->inode > f2->inode) HGOTO_DONE(1) + if(f1->inode < f2->inode) HGOTO_DONE(-1) + if(f1->inode > f2->inode) HGOTO_DONE(1) #else - if(HDmemcmp(&(f1->inode),&(f2->inode),3*sizeof(ino_t))<0) HGOTO_DONE(-1) - if(HDmemcmp(&(f1->inode),&(f2->inode),3*sizeof(ino_t))>0) HGOTO_DONE(1) + if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) < 0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) > 0) HGOTO_DONE(1) #endif /*H5_VMS*/ #endif done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_sec2_cmp() */ /*------------------------------------------------------------------------- @@ -540,7 +524,7 @@ done: static herr_t H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */) { - const H5FD_sec2_t *file = (const H5FD_sec2_t*)_file; /* sec2 VFD info */ + const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; /* sec2 VFD info */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_query) @@ -570,32 +554,21 @@ H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */) * format address space. * * Return: Success: The end-of-address marker. - * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Monday, August 2, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static haddr_t H5FD_sec2_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) { - const H5FD_sec2_t *file = (const H5FD_sec2_t*)_file; - haddr_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_sec2_get_eoa, HADDR_UNDEF) + const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; - /* Set return value */ - ret_value = file->eoa; + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_get_eoa) -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(file->eoa) } /* end H5FD_sec2_get_eoa() */ @@ -607,31 +580,23 @@ done: * to tell the driver where the end of the HDF5 data is located. * * Return: Success: 0 - * * Failure: -1 * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static herr_t H5FD_sec2_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; - FUNC_ENTER_NOAPI(H5FD_sec2_set_eoa, FAIL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_set_eoa) file->eoa = addr; -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FD_sec2_set_eoa() */ @@ -645,30 +610,22 @@ done: * Return: Success: End of file address, the first address past * the end of the "file", either the Unix file * or the HDF5 file. - * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static haddr_t H5FD_sec2_get_eof(const H5FD_t *_file) { - const H5FD_sec2_t *file = (const H5FD_sec2_t*)_file; - haddr_t ret_value; /* Return value */ + const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; - FUNC_ENTER_NOAPI(H5FD_sec2_get_eof, HADDR_UNDEF) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_get_eof) - /* Set return value */ - ret_value=MAX(file->eof, file->eoa); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(MAX(file->eof, file->eoa)) +} /* end H5FD_sec2_get_eof() */ /*------------------------------------------------------------------------- @@ -690,10 +647,11 @@ H5FD_sec2_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void **file_handle) H5FD_sec2_t *file = (H5FD_sec2_t *)_file; herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FD_sec2_get_handle, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_get_handle) if(!file_handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid") + *file_handle = &(file->fd); done: @@ -722,11 +680,11 @@ static herr_t H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, void *buf/*out*/) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; ssize_t nbytes; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_read, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_read) HDassert(file && file->pub.cls); HDassert(buf); @@ -740,9 +698,10 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) /* Seek to the correct location */ - if((addr != file->pos || OP_READ != file->op) && - HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) - HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + if(addr != file->pos || OP_READ != file->op) { + if(HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + } /* end if */ /* * Read data, being careful of interrupted system calls, partial results, @@ -808,11 +767,11 @@ static herr_t H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; ssize_t nbytes; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_write, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_write) HDassert(file && file->pub.cls); HDassert(buf); @@ -826,9 +785,10 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size = %llu, eoa = %llu", (unsigned long long)addr, (unsigned long long)size, (unsigned long long)file->eoa) /* Seek to the correct location */ - if((addr != file->pos || OP_WRITE != file->op) && - HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) - HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + if(addr != file->pos || OP_WRITE != file->op) { + if(HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + } /* end if */ /* * Write the data, being careful of interrupted system calls and partial @@ -878,7 +838,6 @@ done: * than the end-of-address. * * Return: Success: Non-negative - * * Failure: Negative * * Programmer: Robb Matzke @@ -890,10 +849,10 @@ done: static herr_t H5FD_sec2_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_truncate, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_truncate) HDassert(file); diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 20fa31f..9bc4161 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -130,14 +130,8 @@ typedef struct H5FD_stdio_t { /* Use file_xxx to indicate these are local macros, avoiding confusing * with the global HD_xxx macros. - * Need fseeko, off_t, ftell and ftruncate are all of the same 32 or 64 - * versions. * Assume fseeko, which is POSIX standard, is always supported; * but prefer to use fseeko64 if supported. - * [Note: the ifndef H5_HAVE_FSEEKO condition to determine BIG FILE not - * supported was old code. This condition is not supposed to be true in Unix - * like systems but may happen in non-Unix systems like Windows. They are left - * in for now and will be cleaned later. -AKC-] */ #ifndef file_fseek #ifdef H5_HAVE_FSEEKO64 @@ -175,11 +169,6 @@ typedef struct H5FD_stdio_t { #define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ HADDR_UNDEF==(A)+(Z) || (file_offset_t)((A)+(Z))<(file_offset_t)(A)) -#ifndef H5_HAVE_FSEEKO -/* Define big file as 2GB */ -#define BIG_FILE 0x80000000UL -#endif - /* Prototypes */ static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); @@ -587,9 +576,6 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp { H5FD_stdio_t *file = (H5FD_stdio_t*)_file; haddr_t addr; -#ifndef H5_HAVE_FSEEKO - static const char *func = "H5FD_stdio_alloc"; /* Function Name for error reporting */ -#endif haddr_t ret_value; /* Return value */ /* Shut compiler up */ @@ -609,12 +595,6 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp addr = ((addr / file->pub.alignment) + 1) * file->pub.alignment; } /* end if */ -#ifndef H5_HAVE_FSEEKO - /* If fseeko isn't available, big files (>2GB) won't be supported. */ - if((addr + size) > BIG_FILE) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "can't write file bigger than 2GB because fseeko isn't available", HADDR_UNDEF) -#endif - file->eoa = addr + size; /* Set return value */ diff --git a/src/H5FScache.c b/src/H5FScache.c index 17f8f6a..d1c8a2a 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -555,7 +555,7 @@ H5FS_cache_hdr_size(const H5F_t UNUSED *f, const H5FS_t *fspace, size_t *size_pt *------------------------------------------------------------------------- */ static H5FS_sinfo_t * -H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata) +H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata) { H5FS_sinfo_t *sinfo = NULL; /* Free space section info */ H5FS_sinfo_cache_ud_t *udata = (H5FS_sinfo_cache_ud_t *)_udata; /* user data for callback */ diff --git a/src/H5Faccum.c b/src/H5Faccum.c index 2fc53ea..c89ff33 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -111,11 +111,11 @@ H5FL_BLK_DEFINE_STATIC(meta_accum); * *------------------------------------------------------------------------- */ -htri_t +herr_t H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/) { - htri_t ret_value = FALSE; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5F_accum_read, FAIL) @@ -124,90 +124,135 @@ H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, HDassert(buf); /* Check if this information is in the metadata accumulator */ - if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW - && size < H5F_ACCUM_MAX_SIZE) { - /* Sanity check */ - HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); - - /* Current read adjoins or overlaps with metadata accumulator */ - if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size) - || ((addr + size) == f->shared->accum.loc) - || (f->shared->accum.loc + f->shared->accum.size) == addr) { - size_t amount_before; /* Amount to read before current accumulator */ - haddr_t new_addr; /* New address of the accumulator buffer */ - size_t new_size; /* New size of the accumulator buffer */ - - /* Compute new values for accumulator */ - new_addr = MIN(addr, f->shared->accum.loc); - new_size = (size_t)(MAX((addr + size), (f->shared->accum.loc + f->shared->accum.size)) - - new_addr); - - /* Check if we need more buffer space */ - if(new_size > f->shared->accum.alloc_size) { - size_t new_alloc_size; /* New size of accumulator */ - - /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ - new_alloc_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(new_size - 1))); - - /* Reallocate the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_alloc_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") - - /* Note the new buffer size */ - f->shared->accum.alloc_size = new_alloc_size; + if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW) { + if(size < H5F_ACCUM_MAX_SIZE) { + /* Sanity check */ + HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); + + /* Current read adjoins or overlaps with metadata accumulator */ + if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size) + || ((addr + size) == f->shared->accum.loc) + || (f->shared->accum.loc + f->shared->accum.size) == addr) { + size_t amount_before; /* Amount to read before current accumulator */ + haddr_t new_addr; /* New address of the accumulator buffer */ + size_t new_size; /* New size of the accumulator buffer */ + + /* Compute new values for accumulator */ + new_addr = MIN(addr, f->shared->accum.loc); + new_size = (size_t)(MAX((addr + size), (f->shared->accum.loc + f->shared->accum.size)) + - new_addr); + + /* Check if we need more buffer space */ + if(new_size > f->shared->accum.alloc_size) { + size_t new_alloc_size; /* New size of accumulator */ + + /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ + new_alloc_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(new_size - 1))); + + /* Reallocate the metadata accumulator buffer */ + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_alloc_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") + + /* Note the new buffer size */ + f->shared->accum.alloc_size = new_alloc_size; #ifdef H5_CLEAR_MEMORY -HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.alloc_size - f->shared->accum.size)); + HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.alloc_size - f->shared->accum.size)); #endif /* H5_CLEAR_MEMORY */ - } /* end if */ + } /* end if */ - /* Read the part before the metadata accumulator */ - if(addr < f->shared->accum.loc) { - /* Set the amount to read */ - H5_ASSIGN_OVERFLOW(amount_before, (f->shared->accum.loc - addr), hsize_t, size_t); + /* Read the part before the metadata accumulator */ + if(addr < f->shared->accum.loc) { + /* Set the amount to read */ + H5_ASSIGN_OVERFLOW(amount_before, (f->shared->accum.loc - addr), hsize_t, size_t); - /* Make room for the metadata to read in */ - HDmemmove(f->shared->accum.buf + amount_before, f->shared->accum.buf, f->shared->accum.size); + /* Make room for the metadata to read in */ + HDmemmove(f->shared->accum.buf + amount_before, f->shared->accum.buf, f->shared->accum.size); - /* Adjust dirty region tracking info, if present */ - if(f->shared->accum.dirty) - f->shared->accum.dirty_off += amount_before; + /* Adjust dirty region tracking info, if present */ + if(f->shared->accum.dirty) + f->shared->accum.dirty_off += amount_before; - /* Dispatch to driver */ - if(H5FD_read(f->shared->lf, dxpl_id, type, addr, amount_before, f->shared->accum.buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - } /* end if */ - else - amount_before = 0; + /* Dispatch to driver */ + if(H5FD_read(f->shared->lf, dxpl_id, type, addr, amount_before, f->shared->accum.buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") + } /* end if */ + else + amount_before = 0; - /* Read the part after the metadata accumulator */ - if((addr + size) > (f->shared->accum.loc + f->shared->accum.size)) { - size_t amount_after; /* Amount to read at a time */ + /* Read the part after the metadata accumulator */ + if((addr + size) > (f->shared->accum.loc + f->shared->accum.size)) { + size_t amount_after; /* Amount to read at a time */ - /* Set the amount to read */ - H5_ASSIGN_OVERFLOW(amount_after, ((addr + size) - (f->shared->accum.loc + f->shared->accum.size)), hsize_t, size_t); + /* Set the amount to read */ + H5_ASSIGN_OVERFLOW(amount_after, ((addr + size) - (f->shared->accum.loc + f->shared->accum.size)), hsize_t, size_t); - /* Dispatch to driver */ - if(H5FD_read(f->shared->lf, dxpl_id, type, (f->shared->accum.loc + f->shared->accum.size), amount_after, (f->shared->accum.buf + f->shared->accum.size + amount_before)) < 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - } /* end if */ + /* Dispatch to driver */ + if(H5FD_read(f->shared->lf, dxpl_id, type, (f->shared->accum.loc + f->shared->accum.size), amount_after, (f->shared->accum.buf + f->shared->accum.size + amount_before)) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") + } /* end if */ - /* Copy the data out of the buffer */ - HDmemcpy(buf, f->shared->accum.buf + (addr - new_addr), size); + /* Copy the data out of the buffer */ + HDmemcpy(buf, f->shared->accum.buf + (addr - new_addr), size); - /* Adjust the accumulator address & size */ - f->shared->accum.loc = new_addr; - f->shared->accum.size = new_size; + /* Adjust the accumulator address & size */ + f->shared->accum.loc = new_addr; + f->shared->accum.size = new_size; + } /* end if */ + /* Current read doesn't overlap with metadata accumulator, read it from file */ + else { + /* Dispatch to driver */ + if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") + } /* end else */ } /* end if */ - /* Current read doesn't overlap with metadata accumulator, read it from file */ else { - /* Dispatch to driver */ + /* Read the data */ if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - } /* end else */ - /* Indicate success */ - HGOTO_DONE(TRUE); + /* Check for overlap w/dirty accumulator */ + /* (Note that this could be improved by updating the non-dirty + * information in the accumulator with [some of] the information + * just read in. -QAK) + */ + if(f->shared->accum.dirty && + H5F_addr_overlap(addr, size, f->shared->accum.loc + f->shared->accum.dirty_off, f->shared->accum.dirty_len)) { + haddr_t dirty_loc = f->shared->accum.loc + f->shared->accum.dirty_off; /* File offset of dirty information */ + size_t buf_off; /* Offset of dirty region in buffer */ + size_t dirty_off; /* Offset within dirty region */ + size_t overlap_size; /* Size of overlap with dirty region */ + + /* Check for read starting before beginning dirty region */ + if(H5F_addr_le(addr, dirty_loc)) { + /* Compute offset of dirty region within buffer */ + buf_off = (size_t)(dirty_loc - addr); + + /* Compute offset within dirty region */ + dirty_off = 0; + + /* Check for read ending within dirty region */ + if(H5F_addr_lt(addr + size, dirty_loc + f->shared->accum.dirty_len)) + overlap_size = (size_t)((addr + size) - buf_off); + else /* Access covers whole dirty region */ + overlap_size = f->shared->accum.dirty_len; + } /* end if */ + else { /* Read starts after beginning of dirty region */ + /* Compute dirty offset within buffer and overlap size */ + buf_off = 0; + dirty_off = (size_t)(addr - dirty_loc); + overlap_size = (size_t)((dirty_loc + f->shared->accum.dirty_len) - addr); + } /* end else */ + + /* Copy the dirty region to buffer */ + HDmemcpy((unsigned char *)buf + buf_off, (unsigned char *)f->shared->accum.buf + f->shared->accum.dirty_off + dirty_off, overlap_size); + } /* end if */ + } /* end else */ } /* end if */ + else { + /* Read the data */ + if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -312,12 +357,6 @@ H5F_accum_adjust(H5F_meta_accum_t *accum, H5FD_t *lf, hid_t dxpl_id, accum->dirty = FALSE; } /* end if */ - /* Move remnant of accumulator down */ - HDmemmove(accum->buf, (accum->buf + shrink_size), remnant_size); - - /* Adjust accumulator's location */ - accum->loc += shrink_size; - /* Adjust dirty region tracking info */ accum->dirty_off -= shrink_size; } /* end else */ @@ -325,6 +364,15 @@ H5F_accum_adjust(H5F_meta_accum_t *accum, H5FD_t *lf, hid_t dxpl_id, /* Trim the accumulator's use of its buffer */ accum->size = remnant_size; + + /* When appending, need to adjust location of accumulator */ + if(H5F_ACCUM_APPEND == adjust) { + /* Move remnant of accumulator down */ + HDmemmove(accum->buf, (accum->buf + shrink_size), remnant_size); + + /* Adjust accumulator's location */ + accum->loc += shrink_size; + } /* end if */ } /* end if */ /* Check for accumulator needing to be reallocated */ @@ -352,8 +400,8 @@ done: /*------------------------------------------------------------------------- * Function: H5F_accum_write * - * Purpose: Attempts to read some data from the metadata accumulator for - * a file into a buffer. + * Purpose: Attempts to write some data to the metadata accumulator for + * a file from a buffer. * * Return: Non-negative on success/Negative on failure * @@ -363,11 +411,11 @@ done: * *------------------------------------------------------------------------- */ -htri_t +herr_t H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, size_t size, const void *buf) { - htri_t ret_value = FALSE; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5F_accum_write, FAIL) @@ -377,248 +425,284 @@ H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, HDassert(buf); /* Check for accumulating metadata */ - if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW - && size < H5F_ACCUM_MAX_SIZE) { - /* Sanity check */ - HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); - - /* Check if there is already metadata in the accumulator */ - if(f->shared->accum.size > 0) { - /* Check if the new metadata adjoins the beginning of the current accumulator */ - if((addr + size) == f->shared->accum.loc) { - /* Check if we need to adjust accumulator size */ - if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_PREPEND, size) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") - - /* Move the existing metadata to the proper location */ - HDmemmove(f->shared->accum.buf + size, f->shared->accum.buf, f->shared->accum.size); - - /* Copy the new metadata at the front */ - HDmemcpy(f->shared->accum.buf, buf, size); - - /* Set the new size & location of the metadata accumulator */ - f->shared->accum.loc = addr; - f->shared->accum.size += size; - - /* Adjust the dirty region and mark accumulator dirty */ - if(f->shared->accum.dirty) - f->shared->accum.dirty_len = size + f->shared->accum.dirty_off - + f->shared->accum.dirty_len; - else { - f->shared->accum.dirty_len = size; - f->shared->accum.dirty = TRUE; - } /* end else */ - f->shared->accum.dirty_off = 0; - } /* end if */ - /* Check if the new metadata adjoins the end of the current accumulator */ - else if(addr == (f->shared->accum.loc + f->shared->accum.size)) { - /* Check if we need to adjust accumulator size */ - if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_APPEND, size) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") + if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW) { + if(size < H5F_ACCUM_MAX_SIZE) { + /* Sanity check */ + HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); + + /* Check if there is already metadata in the accumulator */ + if(f->shared->accum.size > 0) { + /* Check if the new metadata adjoins the beginning of the current accumulator */ + if((addr + size) == f->shared->accum.loc) { + /* Check if we need to adjust accumulator size */ + if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_PREPEND, size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") - /* Copy the new metadata to the end */ - HDmemcpy(f->shared->accum.buf + f->shared->accum.size, buf, size); + /* Move the existing metadata to the proper location */ + HDmemmove(f->shared->accum.buf + size, f->shared->accum.buf, f->shared->accum.size); - /* Adjust the dirty region and mark accumulator dirty */ - if(f->shared->accum.dirty) - f->shared->accum.dirty_len = size + (f->shared->accum.size - - f->shared->accum.dirty_off); - else { - f->shared->accum.dirty_off = f->shared->accum.size; - f->shared->accum.dirty_len = size; - f->shared->accum.dirty = TRUE; - } /* end else */ + /* Copy the new metadata at the front */ + HDmemcpy(f->shared->accum.buf, buf, size); - /* Set the new size of the metadata accumulator */ - f->shared->accum.size += size; - } /* end if */ - /* Check if the piece of metadata being written overlaps the metadata accumulator */ - else if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) { - size_t add_size; /* New size of the accumulator buffer */ + /* Set the new size & location of the metadata accumulator */ + f->shared->accum.loc = addr; + f->shared->accum.size += size; - /* Check if the new metadata is entirely within the current accumulator */ - if(addr >= f->shared->accum.loc && (addr + size) <= (f->shared->accum.loc + f->shared->accum.size)) { - size_t dirty_off = (size_t)(addr - f->shared->accum.loc); + /* Adjust the dirty region and mark accumulator dirty */ + if(f->shared->accum.dirty) + f->shared->accum.dirty_len = size + f->shared->accum.dirty_off + + f->shared->accum.dirty_len; + else { + f->shared->accum.dirty_len = size; + f->shared->accum.dirty = TRUE; + } /* end else */ + f->shared->accum.dirty_off = 0; + } /* end if */ + /* Check if the new metadata adjoins the end of the current accumulator */ + else if(addr == (f->shared->accum.loc + f->shared->accum.size)) { + /* Check if we need to adjust accumulator size */ + if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_APPEND, size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") - /* Copy the new metadata to the proper location within the accumulator */ - HDmemcpy(f->shared->accum.buf + dirty_off, buf, size); + /* Copy the new metadata to the end */ + HDmemcpy(f->shared->accum.buf + f->shared->accum.size, buf, size); /* Adjust the dirty region and mark accumulator dirty */ - if(f->shared->accum.dirty) { - /* Check for new metadata starting before current dirty region */ - if(dirty_off <= f->shared->accum.dirty_off) { - if((dirty_off + size) <= (f->shared->accum.dirty_off + f->shared->accum.dirty_len)) - f->shared->accum.dirty_len = (f->shared->accum.dirty_off + f->shared->accum.dirty_len) - dirty_off; - else - f->shared->accum.dirty_len = size; - f->shared->accum.dirty_off = dirty_off; - } /* end if */ - else { - if((dirty_off + size) <= (f->shared->accum.dirty_off + f->shared->accum.dirty_len)) - ; /* f->shared->accum.dirty_len doesn't change */ - else - f->shared->accum.dirty_len = (dirty_off + size) - f->shared->accum.dirty_off; - } /* end else */ - } /* end if */ + if(f->shared->accum.dirty) + f->shared->accum.dirty_len = size + (f->shared->accum.size - + f->shared->accum.dirty_off); else { - f->shared->accum.dirty_off = dirty_off; + f->shared->accum.dirty_off = f->shared->accum.size; f->shared->accum.dirty_len = size; f->shared->accum.dirty = TRUE; } /* end else */ + + /* Set the new size of the metadata accumulator */ + f->shared->accum.size += size; } /* end if */ - /* Check if the new metadata overlaps the beginning of the current accumulator */ - else if(addr < f->shared->accum.loc && (addr + size) <= (f->shared->accum.loc + f->shared->accum.size)) { - size_t old_offset; /* Offset of old data within the accumulator buffer */ + /* Check if the piece of metadata being written overlaps the metadata accumulator */ + else if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) { + size_t add_size; /* New size of the accumulator buffer */ + + /* Check if the new metadata is entirely within the current accumulator */ + if(addr >= f->shared->accum.loc && (addr + size) <= (f->shared->accum.loc + f->shared->accum.size)) { + size_t dirty_off = (size_t)(addr - f->shared->accum.loc); + + /* Copy the new metadata to the proper location within the accumulator */ + HDmemcpy(f->shared->accum.buf + dirty_off, buf, size); + + /* Adjust the dirty region and mark accumulator dirty */ + if(f->shared->accum.dirty) { + /* Check for new metadata starting before current dirty region */ + if(dirty_off <= f->shared->accum.dirty_off) { + if((dirty_off + size) <= (f->shared->accum.dirty_off + f->shared->accum.dirty_len)) + f->shared->accum.dirty_len = (f->shared->accum.dirty_off + f->shared->accum.dirty_len) - dirty_off; + else + f->shared->accum.dirty_len = size; + f->shared->accum.dirty_off = dirty_off; + } /* end if */ + else { + if((dirty_off + size) <= (f->shared->accum.dirty_off + f->shared->accum.dirty_len)) + ; /* f->shared->accum.dirty_len doesn't change */ + else + f->shared->accum.dirty_len = (dirty_off + size) - f->shared->accum.dirty_off; + } /* end else */ + } /* end if */ + else { + f->shared->accum.dirty_off = dirty_off; + f->shared->accum.dirty_len = size; + f->shared->accum.dirty = TRUE; + } /* end else */ + } /* end if */ + /* Check if the new metadata overlaps the beginning of the current accumulator */ + else if(addr < f->shared->accum.loc && (addr + size) <= (f->shared->accum.loc + f->shared->accum.size)) { + size_t old_offset; /* Offset of old data within the accumulator buffer */ - /* Calculate the amount we will need to add to the accumulator size, based on the amount of overlap */ - H5_ASSIGN_OVERFLOW(add_size, (f->shared->accum.loc - addr), hsize_t, size_t); + /* Calculate the amount we will need to add to the accumulator size, based on the amount of overlap */ + H5_ASSIGN_OVERFLOW(add_size, (f->shared->accum.loc - addr), hsize_t, size_t); - /* Check if we need to adjust accumulator size */ - if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_PREPEND, add_size) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") + /* Check if we need to adjust accumulator size */ + if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_PREPEND, add_size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") - /* Calculate the proper offset of the existing metadata */ - H5_ASSIGN_OVERFLOW(old_offset, (addr + size) - f->shared->accum.loc, hsize_t, size_t); + /* Calculate the proper offset of the existing metadata */ + H5_ASSIGN_OVERFLOW(old_offset, (addr + size) - f->shared->accum.loc, hsize_t, size_t); - /* Move the existing metadata to the proper location */ - HDmemmove(f->shared->accum.buf + size, f->shared->accum.buf + old_offset, (f->shared->accum.size - old_offset)); + /* Move the existing metadata to the proper location */ + HDmemmove(f->shared->accum.buf + size, f->shared->accum.buf + old_offset, (f->shared->accum.size - old_offset)); - /* Copy the new metadata at the front */ - HDmemcpy(f->shared->accum.buf, buf, size); + /* Copy the new metadata at the front */ + HDmemcpy(f->shared->accum.buf, buf, size); - /* Set the new size & location of the metadata accumulator */ - f->shared->accum.loc = addr; - f->shared->accum.size += add_size; + /* Set the new size & location of the metadata accumulator */ + f->shared->accum.loc = addr; + f->shared->accum.size += add_size; - /* Adjust the dirty region and mark accumulator dirty */ - if(f->shared->accum.dirty) { - size_t curr_dirty_end = add_size + f->shared->accum.dirty_off + f->shared->accum.dirty_len; + /* Adjust the dirty region and mark accumulator dirty */ + if(f->shared->accum.dirty) { + size_t curr_dirty_end = add_size + f->shared->accum.dirty_off + f->shared->accum.dirty_len; - f->shared->accum.dirty_off = 0; - if(size <= curr_dirty_end) - f->shared->accum.dirty_len = curr_dirty_end; - else + f->shared->accum.dirty_off = 0; + if(size <= curr_dirty_end) + f->shared->accum.dirty_len = curr_dirty_end; + else + f->shared->accum.dirty_len = size; + } /* end if */ + else { + f->shared->accum.dirty_off = 0; f->shared->accum.dirty_len = size; + f->shared->accum.dirty = TRUE; + } /* end else */ } /* end if */ - else { - f->shared->accum.dirty_off = 0; - f->shared->accum.dirty_len = size; - f->shared->accum.dirty = TRUE; - } /* end else */ - } /* end if */ - /* Check if the new metadata overlaps the end of the current accumulator */ - else if(addr >= f->shared->accum.loc && (addr + size) > (f->shared->accum.loc + f->shared->accum.size)) { - size_t dirty_off = (size_t)(addr - f->shared->accum.loc); + /* Check if the new metadata overlaps the end of the current accumulator */ + else if(addr >= f->shared->accum.loc && (addr + size) > (f->shared->accum.loc + f->shared->accum.size)) { + size_t dirty_off; /* Offset of dirty region */ - /* Calculate the amount we will need to add to the accumulator size, based on the amount of overlap */ - H5_ASSIGN_OVERFLOW(add_size, (addr + size) - (f->shared->accum.loc + f->shared->accum.size), hsize_t, size_t); + /* Calculate the amount we will need to add to the accumulator size, based on the amount of overlap */ + H5_ASSIGN_OVERFLOW(add_size, (addr + size) - (f->shared->accum.loc + f->shared->accum.size), hsize_t, size_t); - /* Check if we need to adjust accumulator size */ - if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_APPEND, add_size) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") + /* Check if we need to adjust accumulator size */ + if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_APPEND, add_size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") - /* Copy the new metadata to the end */ - HDmemcpy(f->shared->accum.buf + dirty_off, buf, size); + /* Compute offset of dirty region (after adjusting accumulator) */ + dirty_off = (size_t)(addr - f->shared->accum.loc); - /* Set the new size of the metadata accumulator */ - f->shared->accum.size += add_size; + /* Copy the new metadata to the end */ + HDmemcpy(f->shared->accum.buf + dirty_off, buf, size); - /* Adjust the dirty region and mark accumulator dirty */ - if(f->shared->accum.dirty) { - /* Check for new metadata starting before current dirty region */ - if(dirty_off <= f->shared->accum.dirty_off) { - f->shared->accum.dirty_off = dirty_off; - f->shared->accum.dirty_len = size; + /* Set the new size of the metadata accumulator */ + f->shared->accum.size += add_size; + + /* Adjust the dirty region and mark accumulator dirty */ + if(f->shared->accum.dirty) { + /* Check for new metadata starting before current dirty region */ + if(dirty_off <= f->shared->accum.dirty_off) { + f->shared->accum.dirty_off = dirty_off; + f->shared->accum.dirty_len = size; + } /* end if */ + else { + f->shared->accum.dirty_len = (dirty_off + size) - f->shared->accum.dirty_off; + } /* end else */ } /* end if */ else { - f->shared->accum.dirty_len = (dirty_off + size) - f->shared->accum.dirty_off; + f->shared->accum.dirty_off = dirty_off; + f->shared->accum.dirty_len = size; + f->shared->accum.dirty = TRUE; } /* end else */ } /* end if */ + /* New metadata overlaps both ends of the current accumulator */ else { - f->shared->accum.dirty_off = dirty_off; + /* Check if we need more buffer space */ + if(size > f->shared->accum.alloc_size) { + size_t new_alloc_size; /* New size of accumulator */ + + /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ + new_alloc_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); + + /* Reallocate the metadata accumulator buffer */ + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_alloc_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") + + /* Note the new buffer size */ + f->shared->accum.alloc_size = new_alloc_size; +#ifdef H5_CLEAR_MEMORY +HDmemset(f->shared->accum.buf + size, 0, (f->shared->accum.alloc_size - size)); +#endif /* H5_CLEAR_MEMORY */ + } /* end if */ + + /* Copy the new metadata to the buffer */ + HDmemcpy(f->shared->accum.buf, buf, size); + + /* Set the new size & location of the metadata accumulator */ + f->shared->accum.loc = addr; + f->shared->accum.size = size; + + /* Adjust the dirty region and mark accumulator dirty */ + f->shared->accum.dirty_off = 0; f->shared->accum.dirty_len = size; f->shared->accum.dirty = TRUE; } /* end else */ } /* end if */ - /* New metadata overlaps both ends of the current accumulator */ + /* New piece of metadata doesn't adjoin or overlap the existing accumulator */ else { - /* Check if we need more buffer space */ + /* Write out the existing metadata accumulator, with dispatch to driver */ + if(f->shared->accum.dirty) { + if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, f->shared->accum.loc + f->shared->accum.dirty_off, f->shared->accum.dirty_len, f->shared->accum.buf + f->shared->accum.dirty_off) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + + /* Reset accumulator dirty flag */ + f->shared->accum.dirty = FALSE; + } /* end if */ + + /* Cache the new piece of metadata */ + /* Check if we need to resize the buffer */ if(size > f->shared->accum.alloc_size) { - size_t new_alloc_size; /* New size of accumulator */ + size_t new_size; /* New size of accumulator */ /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ - new_alloc_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); + new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); - /* Reallocate the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_alloc_size))) + /* Grow the metadata accumulator buffer */ + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ - f->shared->accum.alloc_size = new_alloc_size; + f->shared->accum.alloc_size = new_size; #ifdef H5_CLEAR_MEMORY -HDmemset(f->shared->accum.buf + size, 0, (f->shared->accum.alloc_size - size)); +{ +size_t clear_size = MAX(f->shared->accum.size, size); +HDmemset(f->shared->accum.buf + clear_size, 0, (f->shared->accum.alloc_size - clear_size)); +} #endif /* H5_CLEAR_MEMORY */ } /* end if */ + else { + /* Check if we should shrink the accumulator buffer */ + if(size < (f->shared->accum.alloc_size / H5F_ACCUM_THROTTLE) && + f->shared->accum.alloc_size > H5F_ACCUM_THRESHOLD) { + size_t tmp_size = (f->shared->accum.alloc_size / H5F_ACCUM_THROTTLE); /* New size of accumulator buffer */ - /* Copy the new metadata to the buffer */ - HDmemcpy(f->shared->accum.buf, buf, size); + /* Shrink the accumulator buffer */ + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, tmp_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") - /* Set the new size & location of the metadata accumulator */ + /* Note the new buffer size */ + f->shared->accum.alloc_size = tmp_size; + } /* end if */ + } /* end else */ + + /* Update the metadata accumulator information */ f->shared->accum.loc = addr; f->shared->accum.size = size; + /* Store the piece of metadata in the accumulator */ + HDmemcpy(f->shared->accum.buf, buf, size); + /* Adjust the dirty region and mark accumulator dirty */ f->shared->accum.dirty_off = 0; f->shared->accum.dirty_len = size; f->shared->accum.dirty = TRUE; } /* end else */ } /* end if */ - /* New piece of metadata doesn't adjoin or overlap the existing accumulator */ + /* No metadata in the accumulator, grab this piece and keep it */ else { - /* Write out the existing metadata accumulator, with dispatch to driver */ - if(f->shared->accum.dirty) { - if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, f->shared->accum.loc + f->shared->accum.dirty_off, f->shared->accum.dirty_len, f->shared->accum.buf + f->shared->accum.dirty_off) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") - - /* Reset accumulator dirty flag */ - f->shared->accum.dirty = FALSE; - } /* end if */ - - /* Cache the new piece of metadata */ - /* Check if we need to resize the buffer */ + /* Check if we need to reallocate the buffer */ if(size > f->shared->accum.alloc_size) { size_t new_size; /* New size of accumulator */ /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); - /* Grow the metadata accumulator buffer */ + /* Reallocate the metadata accumulator buffer */ if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ f->shared->accum.alloc_size = new_size; #ifdef H5_CLEAR_MEMORY -{ -size_t clear_size = MAX(f->shared->accum.size, size); -HDmemset(f->shared->accum.buf + clear_size, 0, (f->shared->accum.alloc_size - clear_size)); -} +HDmemset(f->shared->accum.buf + size, 0, (f->shared->accum.alloc_size - size)); #endif /* H5_CLEAR_MEMORY */ } /* end if */ - else { - /* Check if we should shrink the accumulator buffer */ - if(size < (f->shared->accum.alloc_size / H5F_ACCUM_THROTTLE) && - f->shared->accum.alloc_size > H5F_ACCUM_THRESHOLD) { - size_t tmp_size = (f->shared->accum.alloc_size / H5F_ACCUM_THROTTLE); /* New size of accumulator buffer */ - - /* Shrink the accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, tmp_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") - - /* Note the new buffer size */ - f->shared->accum.alloc_size = tmp_size; - } /* end if */ - } /* end else */ /* Update the metadata accumulator information */ f->shared->accum.loc = addr; @@ -633,42 +717,96 @@ HDmemset(f->shared->accum.buf + clear_size, 0, (f->shared->accum.alloc_size - cl f->shared->accum.dirty = TRUE; } /* end else */ } /* end if */ - /* No metadata in the accumulator, grab this piece and keep it */ else { - /* Check if we need to reallocate the buffer */ - if(size > f->shared->accum.alloc_size) { - size_t new_size; /* New size of accumulator */ + /* Write the data */ + if(H5FD_write(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + + /* Check for overlap w/accumulator */ + /* (Note that this could be improved by updating the accumulator + * with [some of] the information just read in. -QAK) + */ + if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) { + /* Check for write starting before beginning of accumulator */ + if(H5F_addr_le(addr, f->shared->accum.loc)) { + /* Check for write ending within accumulator */ + if(H5F_addr_le(addr + size, f->shared->accum.loc + f->shared->accum.size)) { + size_t overlap_size; /* Size of overlapping region */ + + /* Compute overlap size */ + overlap_size = (size_t)((addr + size) - f->shared->accum.loc); + + /* Check for dirty region */ + if(f->shared->accum.dirty) { + haddr_t dirty_start = f->shared->accum.loc + f->shared->accum.dirty_off; /* File address of start of dirty region */ + haddr_t dirty_end = dirty_start + f->shared->accum.dirty_len; /* File address of end of dirty region */ + + /* Check if entire dirty region is overwritten */ + if(H5F_addr_le(dirty_end, addr + size)) { + f->shared->accum.dirty = FALSE; + f->shared->accum.dirty_len = 0; + } /* end if */ + else { + /* Check for dirty region falling after write */ + if(H5F_addr_le(addr + size, dirty_start)) + f->shared->accum.dirty_off = overlap_size; + else { /* Dirty region overlaps w/written region */ + f->shared->accum.dirty_off = 0; + f->shared->accum.dirty_len -= (size_t)((addr + size) - dirty_start); + } /* end else */ + } /* end if */ + } /* end if */ - /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ - new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); + /* Trim bottom of accumulator off */ + f->shared->accum.loc += overlap_size; + f->shared->accum.size -= overlap_size; + HDmemmove(f->shared->accum.buf, f->shared->accum.buf + overlap_size, f->shared->accum.size); + } /* end if */ + else { /* Access covers whole accumulator */ + /* Reset accumulator, but don't flush */ + if(H5F_accum_reset(f, dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESET, FAIL, "can't reset accumulator") + } /* end else */ + } /* end if */ + else { /* Write starts after beginning of accumulator */ + size_t overlap_size; /* Size of overlapping region */ - /* Reallocate the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") + /* Sanity check */ + HDassert(H5F_addr_gt(addr + size, f->shared->accum.loc + f->shared->accum.size)); - /* Note the new buffer size */ - f->shared->accum.alloc_size = new_size; -#ifdef H5_CLEAR_MEMORY -HDmemset(f->shared->accum.buf + size, 0, (f->shared->accum.alloc_size - size)); -#endif /* H5_CLEAR_MEMORY */ - } /* end if */ + /* Compute overlap size */ + overlap_size = (size_t)((f->shared->accum.loc + f->shared->accum.size) - addr); - /* Update the metadata accumulator information */ - f->shared->accum.loc = addr; - f->shared->accum.size = size; + /* Check for dirty region */ + if(f->shared->accum.dirty) { + haddr_t dirty_start = f->shared->accum.loc + f->shared->accum.dirty_off; /* File address of start of dirty region */ + haddr_t dirty_end = dirty_start + f->shared->accum.dirty_len; /* File address of end of dirty region */ - /* Store the piece of metadata in the accumulator */ - HDmemcpy(f->shared->accum.buf, buf, size); + /* Check if entire dirty region is overwritten */ + if(H5F_addr_ge(dirty_start, addr)) { + f->shared->accum.dirty = FALSE; + f->shared->accum.dirty_len = 0; + } /* end if */ + else { + /* Check for dirty region falling before write */ + if(H5F_addr_le(dirty_end, addr)) + ; /* noop */ + else /* Dirty region overlaps w/written region */ + f->shared->accum.dirty_len = (size_t)(addr - dirty_start); + } /* end if */ + } /* end if */ - /* Adjust the dirty region and mark accumulator dirty */ - f->shared->accum.dirty_off = 0; - f->shared->accum.dirty_len = size; - f->shared->accum.dirty = TRUE; + /* Trim top of accumulator off */ + f->shared->accum.size -= overlap_size; + } /* end else */ + } /* end if */ } /* end else */ - - /* Indicate success */ - HGOTO_DONE(TRUE); } /* end if */ + else { + /* Write the data */ + if(H5FD_write(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -775,22 +913,20 @@ H5F_accum_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t UNUSED type, haddr_t addr, HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") } /* end if */ /* Block to free overlaps with some/all of dirty region */ - else { + /* Check for unfreed dirty region to write */ + else if(H5F_addr_lt(tail_addr, dirty_end)) { size_t write_size; + size_t dirty_delta; write_size = (size_t)(dirty_end - tail_addr); + dirty_delta = f->shared->accum.dirty_len - write_size; - /* Check for unfreed dirty region to write */ - if(write_size > 0) { - size_t dirty_delta; - - dirty_delta = f->shared->accum.dirty_len - write_size; + HDassert(write_size > 0); - /* Write out the unfreed dirty region of the accumulator */ - if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, dirty_start + dirty_delta, write_size, f->shared->accum.buf + f->shared->accum.dirty_off + dirty_delta) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") - } /* end if */ - } /* end else */ + /* Write out the unfreed dirty region of the accumulator */ + if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, dirty_start + dirty_delta, write_size, f->shared->accum.buf + f->shared->accum.dirty_off + dirty_delta) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + } /* end if */ /* Reset dirty flag */ f->shared->accum.dirty = FALSE; @@ -800,19 +936,16 @@ H5F_accum_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t UNUSED type, haddr_t addr, /* Check if block to free ends before end of dirty region */ if(H5F_addr_lt(tail_addr, dirty_end)) { size_t write_size; + size_t dirty_delta; write_size = (size_t)(dirty_end - tail_addr); + dirty_delta = f->shared->accum.dirty_len - write_size; - /* Check for unfreed dirty region to write */ - if(write_size > 0) { - size_t dirty_delta; + HDassert(write_size > 0); - dirty_delta = f->shared->accum.dirty_len - write_size; - - /* Write out the unfreed end of the dirty region of the accumulator */ - if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, dirty_start + dirty_delta, write_size, f->shared->accum.buf + f->shared->accum.dirty_off + dirty_delta) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") - } /* end if */ + /* Write out the unfreed end of the dirty region of the accumulator */ + if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, dirty_start + dirty_delta, write_size, f->shared->accum.buf + f->shared->accum.dirty_off + dirty_delta) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") } /* end if */ /* Check for block to free beginning at same location as dirty region */ @@ -822,7 +955,7 @@ H5F_accum_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t UNUSED type, haddr_t addr, } /* end if */ /* Block to free eliminates end of dirty region */ else { - f->shared->accum.dirty_len = (addr - dirty_start); + f->shared->accum.dirty_len = (size_t)(addr - dirty_start); } /* end else */ } /* end else */ @@ -852,7 +985,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_accum_flush(H5F_t *f, hid_t dxpl_id) +H5F_accum_flush(const H5F_t *f, hid_t dxpl_id) { herr_t ret_value = SUCCEED; /* Return value */ @@ -890,7 +1023,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_accum_reset(H5F_t *f, hid_t dxpl_id) +H5F_accum_reset(const H5F_t *f, hid_t dxpl_id, hbool_t flush) { herr_t ret_value = SUCCEED; /* Return value */ @@ -899,9 +1032,10 @@ H5F_accum_reset(H5F_t *f, hid_t dxpl_id) HDassert(f); HDassert(f->shared); - /* Flush any dirty data in accumulator */ - if(H5F_accum_flush(f, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "can't flush metadata accumulator") + /* Flush any dirty data in accumulator, if requested */ + if(flush) + if(H5F_accum_flush(f, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "can't flush metadata accumulator") /* Check if we need to reset the metadata accumulator information */ if(f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) { diff --git a/src/H5Fio.c b/src/H5Fio.c index 407f950..c8c75b2 100644 --- a/src/H5Fio.c +++ b/src/H5Fio.c @@ -95,7 +95,6 @@ herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t dxpl_id, void *buf/*out*/) { - htri_t accumulated; /* Whether the data was accepted by the metadata accumulator */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5F_block_read, FAIL) @@ -103,19 +102,15 @@ H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, HDassert(f); HDassert(f->shared); HDassert(buf); + HDassert(H5F_addr_defined(addr)); /* Check for attempting I/O on 'temporary' file address */ if(H5F_addr_le(f->shared->tmp_addr, (addr + size))) HGOTO_ERROR(H5E_IO, H5E_BADRANGE, FAIL, "attempting I/O in temporary file space") - /* Check if this I/O can be satisfied by the metadata accumulator */ - if((accumulated = H5F_accum_read(f, dxpl_id, type, addr, size, buf)) < 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from metadata accumulator failed") - else if(accumulated == FALSE) { - /* Read the data */ - if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - } /* end else */ + /* Pass through metadata accumulator layer */ + if(H5F_accum_read(f, dxpl_id, type, addr, size, buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read through metadata accumulator failed") done: FUNC_LEAVE_NOAPI(ret_value) @@ -141,7 +136,6 @@ herr_t H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t dxpl_id, const void *buf) { - htri_t accumulated; /* Whether the data was accepted by the metadata accumulator */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5F_block_write, FAIL) @@ -153,19 +147,15 @@ HDfprintf(stderr, "%s: write to addr = %a, size = %Zu\n", FUNC, addr, size); HDassert(f->shared); HDassert(f->intent & H5F_ACC_RDWR); HDassert(buf); + HDassert(H5F_addr_defined(addr)); /* Check for attempting I/O on 'temporary' file address */ if(H5F_addr_le(f->shared->tmp_addr, (addr + size))) HGOTO_ERROR(H5E_IO, H5E_BADRANGE, FAIL, "attempting I/O in temporary file space") - /* Check for accumulating metadata */ - if((accumulated = H5F_accum_write(f, dxpl_id, type, addr, size, buf)) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to metadata accumulator failed") - else if(accumulated == FALSE) { - /* Write the data */ - if(H5FD_write(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") - } /* end else */ + /* Pass through metadata accumulator layer */ + if(H5F_accum_write(f, dxpl_id, type, addr, size, buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write through metadata accumulator failed") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index d264d04..c98bda4 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -310,17 +310,18 @@ H5_DLL herr_t H5F_super_free(H5F_super_t *sblock); H5_DLL herr_t H5F_super_ext_open(H5F_t *f, haddr_t ext_addr, H5O_loc_t *ext_ptr); H5_DLL herr_t H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create); H5_DLL herr_t H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id); -H5_DLL herr_t H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr); +H5_DLL herr_t H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr, hid_t dxpl_id, + hbool_t was_created); /* Metadata accumulator routines */ -H5_DLL htri_t H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, +H5_DLL herr_t H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, size_t size, void *buf); -H5_DLL htri_t H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, +H5_DLL herr_t H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, size_t size, const void *buf); H5_DLL herr_t H5F_accum_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, hsize_t size); -H5_DLL herr_t H5F_accum_flush(H5F_t *f, hid_t dxpl_id); -H5_DLL herr_t H5F_accum_reset(H5F_t *f, hid_t dxpl_id); +H5_DLL herr_t H5F_accum_flush(const H5F_t *f, hid_t dxpl_id); +H5_DLL herr_t H5F_accum_reset(const H5F_t *f, hid_t dxpl_id, hbool_t flush); /* Shared file list related routines */ H5_DLL herr_t H5F_sfile_add(H5F_file_t *shared); diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index a259dde..2510487 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -204,7 +204,7 @@ H5F_super_ext_create(H5F_t *f, hid_t dxpl_id, H5O_loc_t *ext_ptr) * extension. */ H5O_loc_reset(ext_ptr); - if(H5O_create(f, dxpl_id, 0, H5P_GROUP_CREATE_DEFAULT, ext_ptr) < 0) + if(H5O_create(f, dxpl_id, 0, (size_t)1, H5P_GROUP_CREATE_DEFAULT, ext_ptr) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "unable to create superblock extension") /* Record the address of the superblock extension */ @@ -267,7 +267,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr) +H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr, hid_t dxpl_id, + hbool_t was_created) { herr_t ret_value = SUCCEED; /* Return value */ @@ -277,6 +278,17 @@ H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr) HDassert(f); HDassert(ext_ptr); + /* Check if extension was created */ + if(was_created) { + /* Increment link count on superblock extension's object header */ + if(H5O_link(ext_ptr, 1, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_LINKCOUNT, FAIL, "unable to increment hard link count") + + /* Decrement refcount on superblock extension's object header in memory */ + if(H5O_dec_rc_by_loc(ext_ptr, dxpl_id) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to decrement refcount on superblock extension") + } /* end if */ + /* Twiddle the number of open objects to avoid closing the file. */ f->nopen_objs++; if(H5O_close(ext_ptr) < 0) @@ -384,7 +396,9 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) hsize_t superblock_size; /* Size of superblock, in bytes */ size_t driver_size; /* Size of driver info block (bytes) */ unsigned super_vers = HDF5_SUPERBLOCK_VERSION_DEF; /* Superblock version for file */ + H5O_loc_t ext_loc; /* Superblock extension object location */ hbool_t need_ext; /* Whether the superblock extension is needed */ + hbool_t ext_created = FALSE; /* Whether the extension has been created */ herr_t ret_value = SUCCEED; /* Return Value */ FUNC_ENTER_NOAPI_TAG(H5F_super_init, dxpl_id, H5AC__SUPERBLOCK_TAG, FAIL) @@ -545,8 +559,6 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) /* Create the superblock extension for "extra" superblock data, if necessary. */ if(need_ext) { - H5O_loc_t ext_loc; /* Superblock extension object location */ - /* The superblock extension isn't actually a group, but the * default group creation list should work fine. * If we don't supply a size for the object header, HDF5 will @@ -557,6 +569,7 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) */ if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to create superblock extension") + ext_created = TRUE; /* Create the Shared Object Header Message table and register it with * the metadata cache, if this file supports shared messages. @@ -615,13 +628,13 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) if(H5O_msg_create(&ext_loc, H5O_FSINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &fsinfo, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update free-space info header message") } /* end if */ - - /* Close superblock extension */ - if(H5F_super_ext_close(f, &ext_loc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") } /* end if */ done: + /* Close superblock extension, if it was created */ + if(ext_created && H5F_super_ext_close(f, &ext_loc, dxpl_id, ext_created) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") + /* Cleanup on failure */ if(ret_value < 0) { /* Check if the superblock has been allocated yet */ @@ -786,7 +799,8 @@ done: herr_t H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create) { - hbool_t sblock_dirty = FALSE; /* Whether superblock was dirtied */ + hbool_t ext_created = FALSE; /* Whether superblock extension was created */ + hbool_t ext_opened = FALSE; /* Whether superblock extension was opened */ H5O_loc_t ext_loc; /* "Object location" for superblock extension */ htri_t status; /* Indicate whether the message exists or not */ herr_t ret_value = SUCCEED; /* Return value */ @@ -807,9 +821,10 @@ H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_ HDassert(may_create); if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to create file's superblock extension") - sblock_dirty = TRUE; + ext_created = TRUE; } /* end else */ HDassert(H5F_addr_defined(ext_loc.addr)); + ext_opened = TRUE; /* Check if message with ID does not exist in the object header */ if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0) @@ -833,15 +848,14 @@ H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to write the message in object header") } /* end else */ - /* Close the superblock extension object header */ - if(H5F_super_ext_close(f, &ext_loc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") - done: - /* Mark superblock dirty in cache, if necessary */ - if(sblock_dirty) - if(H5AC_mark_entry_dirty(f->shared->sblock) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty") + /* Close the superblock extension, if it was opened */ + if(ext_opened && H5F_super_ext_close(f, &ext_loc, dxpl_id, ext_created) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") + + /* Mark superblock dirty in cache, if superblock extension was created */ + if(ext_created && H5AC_mark_entry_dirty(f->shared->sblock) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty") FUNC_LEAVE_NOAPI(ret_value) } /* H5F_super_ext_write_msg() */ @@ -861,9 +875,10 @@ done: herr_t H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id) { - htri_t status; /* Indicate whether the message exists or not */ H5O_loc_t ext_loc; /* "Object location" for superblock extension */ + hbool_t ext_opened = FALSE; /* Whether the superblock extension was opened */ int null_count = 0; /* # of null messages */ + htri_t status; /* Indicate whether the message exists or not */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5F_super_ext_remove_msg, FAIL) @@ -874,6 +889,7 @@ H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id) /* Open superblock extension object header */ if(H5F_super_ext_open(f, f->shared->sblock->ext_addr, &ext_loc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "error in starting file's superblock extension") + ext_opened = TRUE; /* Check if message with ID exists in the object header */ if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0) @@ -902,10 +918,11 @@ H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id) } /* end if */ } /* end if */ - /* Close superblock extension object header */ - if(H5F_super_ext_close(f, &ext_loc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") done: + /* Close superblock extension object header, if opened */ + if(ext_opened && H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") + FUNC_LEAVE_NOAPI(ret_value) } /* H5F_super_ext_remove_msg() */ diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index f9a29e8..56f9219 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -595,7 +595,7 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata) } /* end if */ /* Close superblock extension */ - if(H5F_super_ext_close(f, &ext_loc) < 0) + if(H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, NULL, "unable to close file's superblock extension") } /* end if */ @@ -794,7 +794,7 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "unable to update driver info header message") /* Close the superblock extension object header */ - if(H5F_super_ext_close(f, &ext_loc) < 0) + if(H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close file's superblock extension") } /* end if */ } /* end if */ @@ -353,6 +353,20 @@ H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") done: + /* Release the group's object header, if it was created */ + if(grp) { + H5O_loc_t *oloc; /* Object location for group */ + + /* Get the new group's object location */ + if(NULL == (oloc = H5G_oloc(grp))) + HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object location of group") + + /* Decrement refcount on group's object header in memory */ + if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") + } /* end if */ + + /* Cleanup on failure */ if(ret_value < 0) if(grp && H5G_close(grp) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") @@ -901,6 +915,8 @@ done: if(ret_value == NULL) { /* Check if we need to release the file-oriented symbol table info */ if(oloc_init) { + if(H5O_dec_rc_by_loc(&(grp->oloc), dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object") if(H5O_close(&(grp->oloc)) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "unable to release object header") if(H5O_delete(file, dxpl_id, grp->oloc.addr) < 0) diff --git a/src/H5Gobj.c b/src/H5Gobj.c index ce11990..b0add06 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -160,8 +160,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, H5G_obj_create_t *gcrt_info, HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info") /* Call the "real" group creation routine now */ - if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcrt_info, oloc) - < 0) + if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcrt_info, oloc) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create group") done: @@ -264,7 +263,7 @@ H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, * since nothing refers to it yet. The link count will be * incremented if the object is added to the group directed graph. */ - if(H5O_create(f, dxpl_id, hdr_size, gcpl_id, oloc/*out*/) < 0) + if(H5O_create(f, dxpl_id, hdr_size, (size_t)1, gcpl_id, oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header") /* Check for format of group to create */ diff --git a/src/H5Groot.c b/src/H5Groot.c index a79a5dd..ff4a8c4 100644 --- a/src/H5Groot.c +++ b/src/H5Groot.c @@ -15,7 +15,7 @@ /*------------------------------------------------------------------------- * - * Created: H5Gobj.c + * Created: H5Groot.c * Apr 8 2009 * Neil Fortner <nfortne2@hdfgroup.org> * @@ -148,6 +148,10 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) if(1 != H5O_link(root_loc.oloc, 1, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)") + /* Decrement refcount on root group's object header in memory */ + if(H5O_dec_rc_by_loc(root_loc.oloc, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on root group's object header") + /* Mark superblock dirty, so root group info is flushed */ sblock_dirty = TRUE; diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 4016068..bb8e590 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -792,15 +792,17 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, gcrt_info.gcpl_id = H5P_GROUP_CREATE_DEFAULT; gcrt_info.cache_type = H5G_NOTHING_CACHED; HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache)); - if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo, - pline, &gcrt_info, obj_loc.oloc/*out*/) < 0) + if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo, pline, &gcrt_info, obj_loc.oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") /* Insert new group into current group's symbol table */ - if(H5G_loc_insert(&grp_loc, H5G_comp_g, &obj_loc, - H5O_TYPE_GROUP, &gcrt_info, dxpl_id) < 0) + if(H5G_loc_insert(&grp_loc, H5G_comp_g, &obj_loc, H5O_TYPE_GROUP, &gcrt_info, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert intermediate group") + /* Decrement refcount on intermediate group's object header in memory */ + if(H5O_dec_rc_by_loc(obj_loc.oloc, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") + /* Close new group */ if(H5O_close(obj_loc.oloc) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close") diff --git a/src/H5HGdbg.c b/src/H5HGdbg.c index 38b7047..f301701 100644 --- a/src/H5HGdbg.c +++ b/src/H5HGdbg.c @@ -106,6 +106,9 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, if (h->obj[u].begin) { sprintf (buf, "Object %u", u); fprintf (stream, "%*s%s\n", indent, "", buf); + fprintf (stream, "%*s%-*s %lu\n", indent+3, "", MIN(fwidth-3, 0), + "Obffset in block:", + (unsigned long)(h->obj[u].begin - h->chunk)); fprintf (stream, "%*s%-*s %d\n", indent+3, "", MIN(fwidth-3, 0), "Reference count:", h->obj[u].nrefs); @@ -1664,8 +1664,9 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED H5G_t *grp = NULL; /* H5G_t for this group, opened to pass to user callback */ hid_t grp_id = FAIL; /* Id for this group (passed to user callback */ H5G_loc_t temp_loc; /* For UD callback */ - hbool_t temp_loc_init = FALSE; - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t temp_loc_init = FALSE; /* Temporary location for UD callback (temp_loc) has been initialized */ + hbool_t obj_created = FALSE; /* Whether an object was created (through a hard link) */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5L_link_cb) @@ -1690,6 +1691,9 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED /* Set object path to use for setting object name (below) */ udata->path = new_loc.path; + + /* Indicate that an object was created */ + obj_created = TRUE; } /* end if */ else { /* Check that both objects are in same file */ @@ -1763,6 +1767,20 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED } /* end if */ done: + /* Check if an object was created */ + if(obj_created) { + H5O_loc_t oloc; /* Object location for created object */ + + /* Set up object location */ + HDmemset(&oloc, 0, sizeof(oloc)); + oloc.file = grp_loc->oloc->file; + oloc.addr = udata->lnk->u.hard.addr; + + /* Decrement refcount on superblock extension's object header in memory */ + if(H5O_dec_rc_by_loc(&oloc, udata->dxpl_id) < 0) + HDONE_ERROR(H5E_LINK, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") + } /* end if */ + /* Close the location given to the user callback if it was created */ if(grp_id >= 0) { if(H5I_dec_app_ref(grp_id) < 0) @@ -2396,8 +2414,8 @@ H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, H5G_own_loc_t *own_loc/*out*/) { H5L_trav_mv2_t *udata = (H5L_trav_mv2_t *)_udata; /* User data passed in */ - H5G_t *grp=NULL; /* H5G_t for this group, opened to pass to user callback */ - hid_t grp_id = FAIL; /* Id for this group (passed to user callback */ + H5G_t *grp = NULL; /* H5G_t for this group, opened to pass to user callback */ + hid_t grp_id = FAIL; /* ID for this group (passed to user callback */ H5G_loc_t temp_loc; /* For UD callback */ hbool_t temp_loc_init = FALSE; herr_t ret_value = SUCCEED; /* Return value */ @@ -2482,6 +2500,10 @@ done: * location for the object */ *own_loc = H5G_OWN_NONE; + /* Reset the "name" field in udata->lnk because it is owned by traverse() + * and must not be manipulated after traverse closes */ + udata->lnk->name = NULL; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5L_move_dest_cb() */ @@ -2521,7 +2543,7 @@ H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "the name of a link must be supplied to move or copy") /* Set up user data for move_dest_cb */ - if((udata_out.lnk = (H5O_link_t *)H5O_msg_copy(H5O_LINK_ID, lnk, NULL)) == NULL) + if(NULL == (udata_out.lnk = (H5O_link_t *)H5O_msg_copy(H5O_LINK_ID, lnk, NULL))) HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link to be moved") /* In this special case, the link's name is going to be replaced at its @@ -2582,16 +2604,11 @@ done: H5MM_xfree(orig_name); /* If udata_out.lnk was copied, free any memory allocated - * In this special case, the H5L_move_dest_cb callback frees the name - * if it succeeds + * In this special case, the H5L_move_dest_cb callback resets the name + * so H5O_msg_free shouldn't try to free it */ - if(link_copied) { - if(udata_out.lnk->type == H5L_TYPE_SOFT) - udata_out.lnk->u.soft.name = (char *)H5MM_xfree(udata_out.lnk->u.soft.name); - else if(udata_out.lnk->type >= H5L_TYPE_UD_MIN && udata_out.lnk->u.ud.size > 0) - udata_out.lnk->u.ud.udata = H5MM_xfree(udata_out.lnk->u.ud.udata); - H5MM_xfree(udata_out.lnk); - } /* end if */ + if(link_copied) + H5O_msg_free(H5O_LINK_ID, udata_out.lnk); /* Indicate that this callback didn't take ownership of the group * * location for the object */ diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 9cab8cf..eb2ffe5 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -188,6 +188,9 @@ done: * Otherwise, the file access property retrieved from H5Pget_elink_fapl() * is used to H5F_open() the target file. * + * Vailin Choi; Nov 2010 + * Free memory pointed to by tmp_env_prefix for HDF5_EXT_PREFIX case. + * *------------------------------------------------------------------------- */ static hid_t @@ -343,9 +346,9 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, char *env_prefix; if(NULL != (env_prefix = HDgetenv("HDF5_EXT_PREFIX"))) { - char *tmp_env_prefix; + char *tmp_env_prefix, *saved_env; - if(NULL == (tmp_env_prefix = H5MM_strdup(env_prefix))) + if(NULL == (saved_env = tmp_env_prefix = H5MM_strdup(env_prefix))) HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed") while((tmp_env_prefix) && (*tmp_env_prefix)) { @@ -353,8 +356,10 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, out_prefix_name = H5L_getenv_prefix_name(&tmp_env_prefix/*in,out*/); if(out_prefix_name && (*out_prefix_name)) { - if(H5L_build_name(out_prefix_name, temp_file_name, &full_name/*out*/) < 0) + if(H5L_build_name(out_prefix_name, temp_file_name, &full_name/*out*/) < 0) { + saved_env = (char *)H5MM_xfree(saved_env); HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") + } ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id); full_name = (char *)H5MM_xfree(full_name); @@ -363,6 +368,7 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, H5E_clear_stack(NULL); } /* end if */ } /* end while */ + saved_env = (char *)H5MM_xfree(saved_env); } /* end if */ } /* end if */ @@ -1106,14 +1106,15 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, - H5O_loc_t *loc/*out*/) +H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, size_t initial_rc, + hid_t ocpl_id, H5O_loc_t *loc/*out*/) { H5P_genplist_t *oc_plist; /* Object creation property list */ H5O_t *oh = NULL; /* Object header created */ haddr_t oh_addr; /* Address of initial object header */ size_t oh_size; /* Size of initial object header */ uint8_t oh_flags; /* Object header's initial status flags */ + unsigned insert_flags = H5AC__NO_FLAGS_SET; /* Flags for inserting object header into cache */ hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */ herr_t ret_value = SUCCEED; /* return value */ @@ -1243,11 +1244,18 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, oh->mesg[0].raw_size = size_hint - (size_t)H5O_SIZEOF_MSGHDR_OH(oh); oh->mesg[0].chunkno = 0; + /* Check for non-zero initial refcount on the object header */ + if(initial_rc > 0) { + /* Set the initial refcount & pin the header when its inserted */ + oh->rc = initial_rc; + insert_flags |= H5AC__PIN_ENTRY_FLAG; + } /* end if */ + /* Set metadata tag in dxpl_id */ H5_BEGIN_TAG(dxpl_id, oh_addr, FAIL); /* Cache object header */ - if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR, oh_addr, oh, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR, oh_addr, oh, insert_flags) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header") oh = NULL; @@ -1654,7 +1662,10 @@ H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, H5AC_protect_t prot) /* check args */ HDassert(loc); HDassert(loc->file); - HDassert(H5F_addr_defined(loc->addr)); + + /* Check for valid address */ + if(!H5F_addr_defined(loc->addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "address undefined") /* Check for write access on the file */ file_intent = H5F_INTENT(loc->file); @@ -3422,6 +3433,49 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_dec_rc_by_loc + * + * Purpose: Decrement the refcount of an object header, using its + * object location information. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 08 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_dec_rc_by_loc(const H5O_loc_t *loc, hid_t dxpl_id) +{ + H5O_t *oh = NULL; /* Object header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_dec_rc_by_loc, FAIL) + + /* check args */ + HDassert(loc); + + /* Get header */ + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header") + + /* Decrement the reference count on the object header */ + /* (which will unpin it, if appropriate) */ + if(H5O_dec_rc(oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement reference count on object header") + +done: + /* Release the object header from the cache */ + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dec_rc_by_loc() */ + + +/*------------------------------------------------------------------------- * Function: H5O_free * * Purpose: Destroys an object header. diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 9e909a6..e64262b 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -560,6 +560,21 @@ done: * koziol@ncsa.uiuc.edu * Mar 20 2003 * + * Changes: In the parallel case, there is the possibility that the + * the object header may be flushed by different processes + * over the life of the computation. Thus we must ensure + * that the chunk images are up to date before we mark the + * messages clean -- as otherwise we may overwrite valid + * data with a blank section of a chunk image. + * + * To deal with this, I have added code to call + * H5O_chunk_serialize() for all chunks before we + * mark all messages as clean if we are not destroying the + * object. Do this in the parallel case only, as the problem + * can only occur in this context. + * + * JRM -- 10/12/10 + * *------------------------------------------------------------------------- */ static herr_t @@ -573,6 +588,30 @@ H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy) /* check args */ HDassert(oh); +#ifdef H5_HAVE_PARALLEL + if ( ( oh->cache_info.is_dirty ) && ( ! destroy ) ) { + + size_t i; + + /* scan through all chunks associated with the object header, + * and cause them to update their images for all entries currently + * marked dirty. Must do this in the parallel case, as it is possible + * that this processor may clear this object header several times + * before flushing it -- thus causing undefined sections of the image + * to be written to disk overwriting valid data. + */ + + for ( i = 0; i < oh->nchunks; i++ ) { + + if ( H5O_chunk_serialize(f, oh, i) < 0 ) { + + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, + "unable to serialize object header chunk") + } + } + } +#endif /* H5_HAVE_PARALLEL */ + /* Mark messages as clean */ for(u = 0; u < oh->nmesgs; u++) oh->mesg[u].dirty = FALSE; @@ -830,6 +869,30 @@ done: * koziol@hdfgroup.org * July 12, 2008 * + * Changes: In the parallel case, there is the possibility that the + * the object header chunk may be flushed by different + * processes over the life of the computation. Thus we must + * ensure that the chunk image is up to date before we mark its + * messages clean -- as otherwise we may overwrite valid + * data with a blank section of a chunk image. + * + * To deal with this, I have added code to call + * H5O_chunk_serialize() for this chunk before we + * mark all messages as clean if we are not destroying the + * chunk. + * + * Do this in the parallel case only, as the problem + * can only occur in this context. + * + * Note that at present at least, it seems that this fix + * is not necessary, as we don't seem to be able to + * generate a dirty chunk without creating a dirty object + * header. However, the object header code will be changing + * a lot in the near future, so I'll leave this fix in + * for now, unless Quincey requests otherwise. + * + * JRM -- 10/12/10 + * *------------------------------------------------------------------------- */ static herr_t @@ -843,6 +906,17 @@ H5O_cache_chk_clear(H5F_t *f, H5O_chunk_proxy_t *chk_proxy, hbool_t destroy) /* check args */ HDassert(chk_proxy); +#ifdef H5_HAVE_PARALLEL + if ( ( chk_proxy->oh->cache_info.is_dirty ) && ( ! destroy ) ) { + + if ( H5O_chunk_serialize(f, chk_proxy->oh, chk_proxy->chunkno) < 0 ) { + + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, + "unable to serialize object header chunk") + } + } +#endif /* H5_HAVE_PARALLEL */ + /* Mark messages in chunk as clean */ for(u = 0; u < chk_proxy->oh->nmesgs; u++) if(chk_proxy->oh->mesg[u].chunkno == chk_proxy->chunkno) diff --git a/src/H5Opkg.h b/src/H5Opkg.h index a14d471..54e7233 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -610,6 +610,7 @@ H5_DLL herr_t H5O_num_attrs_test(hid_t oid, hsize_t *nattrs); H5_DLL herr_t H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count); H5_DLL herr_t H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val); H5_DLL herr_t H5O_expunge_chunks_test(const H5O_loc_t *oloc, hid_t dxpl_id); +H5_DLL herr_t H5O_get_rc(const H5O_loc_t *oloc, hid_t dxpl_id, unsigned *rc); #endif /* H5O_TESTING */ /* Object header debugging routines */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 63264d8..56901f3 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -369,6 +369,7 @@ typedef struct H5O_storage_contig_t { } H5O_storage_contig_t; typedef struct H5O_storage_chunk_btree_t { + haddr_t dset_ohdr_addr; /* File address dataset's object header */ H5RC_t *shared; /* Ref-counted shared info for B-tree nodes */ } H5O_storage_chunk_btree_t; @@ -623,13 +624,14 @@ struct H5P_genplist_t; /* Object header routines */ H5_DLL herr_t H5O_init(void); H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, - hid_t ocpl_id, H5O_loc_t *loc/*out*/); + size_t initial_rc, hid_t ocpl_id, H5O_loc_t *loc/*out*/); H5_DLL herr_t H5O_open(H5O_loc_t *loc); H5_DLL herr_t H5O_close(H5O_loc_t *loc); H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id); H5_DLL H5O_t *H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, H5AC_protect_t prot); H5_DLL H5O_t *H5O_pin(const H5O_loc_t *loc, hid_t dxpl_id); H5_DLL herr_t H5O_unpin(H5O_t *oh); +H5_DLL herr_t H5O_dec_rc_by_loc(const H5O_loc_t *loc, hid_t dxpl_id); H5_DLL herr_t H5O_unprotect(const H5O_loc_t *loc, hid_t dxpl_id, H5O_t *oh, unsigned oh_flags); H5_DLL herr_t H5O_touch(const H5O_loc_t *loc, hbool_t force, hid_t dxpl_id); diff --git a/src/H5Otest.c b/src/H5Otest.c index 557ac9e..883bfcd 100644 --- a/src/H5Otest.c +++ b/src/H5Otest.c @@ -536,3 +536,52 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5O_expunge_chunks_test() */ + +/*-------------------------------------------------------------------------- + NAME + H5O_get_rc + PURPOSE + Retrieve the refcount for the object header + USAGE + herr_t H5O_expunge_chunks_test(loc, dxpl_id, rc) + const H5O_loc_t *loc; IN: Object location for object header to query + hid_t dxpl_id; IN: DXPL to use for operation + unsigned *rc; OUT: Pointer to refcount for object header + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Protects object header, retrieves the object header's refcount, and + unprotects object header. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5O_get_rc(const H5O_loc_t *loc, hid_t dxpl_id, unsigned *rc) +{ + H5O_t *oh = NULL; /* Object header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_get_rc, FAIL) + + /* Sanity check */ + HDassert(loc); + HDassert(rc); + + /* Get the object header */ + if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header") + + /* Save the refcount for the object header */ + *rc = oh->nlink; + +done: + /* Release the object header */ + if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_expunge_chunks_test() */ + diff --git a/src/H5Smpio.c b/src/H5Smpio.c index e9d0541..d6131b9 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -35,6 +35,7 @@ #include "H5Oprivate.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ #include "H5Spkg.h" /* Dataspaces */ +#include "H5Vprivate.h" /* Vector and array functions */ #ifdef H5_HAVE_PARALLEL @@ -83,7 +84,7 @@ H5S_mpio_all_type(const H5S_t *space, size_t elmt_size, HDassert(space); /* Just treat the entire extent as a block of bytes */ - if((snelmts = H5S_GET_EXTENT_NPOINTS(space)) < 0) + if((snelmts = (hssize_t)H5S_GET_EXTENT_NPOINTS(space)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection") H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, hsize_t); @@ -160,14 +161,15 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, hsize_t count; } d[H5S_MAX_RANK]; - int i; - int offset[H5S_MAX_RANK]; - int max_xtent[H5S_MAX_RANK]; + hsize_t offset[H5S_MAX_RANK]; + hsize_t max_xtent[H5S_MAX_RANK]; H5S_hyper_dim_t *diminfo; /* [rank] */ - int rank; + unsigned rank; int block_length[3]; MPI_Datatype inner_type, outer_type, old_types[3]; MPI_Aint extent_len, displacement[3]; + unsigned u; /* Local index variable */ + int i; /* Local index variable */ int mpi_code; /* MPI return code */ herr_t ret_value = SUCCEED; @@ -192,66 +194,68 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, if(sel_iter.u.hyp.iter_rank != 0 && sel_iter.u.hyp.iter_rank < space->extent.rank) { /* Flattened selection */ rank = sel_iter.u.hyp.iter_rank; - HDassert(rank >= 0 && rank <= H5S_MAX_RANK); /* within array bounds */ + HDassert(rank <= H5S_MAX_RANK); /* within array bounds */ #ifdef H5S_DEBUG if(H5DEBUG(S)) HDfprintf(H5DEBUG(S), "%s: Flattened selection\n",FUNC); #endif - for(i = 0; i < rank; ++i) { - d[i].start = diminfo[i].start + sel_iter.u.hyp.sel_off[i]; - d[i].strid = diminfo[i].stride; - d[i].block = diminfo[i].block; - d[i].count = diminfo[i].count; - d[i].xtent = sel_iter.u.hyp.size[i]; + for(u = 0; u < rank; ++u) { + H5_CHECK_OVERFLOW(diminfo[u].start, hsize_t, hssize_t) + d[u].start = (hssize_t)diminfo[u].start + sel_iter.u.hyp.sel_off[u]; + d[u].strid = diminfo[u].stride; + d[u].block = diminfo[u].block; + d[u].count = diminfo[u].count; + d[u].xtent = sel_iter.u.hyp.size[u]; #ifdef H5S_DEBUG if(H5DEBUG(S)){ HDfprintf(H5DEBUG(S), "%s: start=%Hd stride=%Hu count=%Hu block=%Hu xtent=%Hu", - FUNC, d[i].start, d[i].strid, d[i].count, d[i].block, d[i].xtent ); - if (i==0) - HDfprintf(H5DEBUG(S), " rank=%d\n", rank ); + FUNC, d[u].start, d[u].strid, d[u].count, d[u].block, d[u].xtent ); + if (u==0) + HDfprintf(H5DEBUG(S), " rank=%u\n", rank ); else HDfprintf(H5DEBUG(S), "\n" ); } #endif - if(0 == d[i].block) + if(0 == d[u].block) goto empty; - if(0 == d[i].count) + if(0 == d[u].count) goto empty; - if(0 == d[i].xtent) + if(0 == d[u].xtent) goto empty; } /* end for */ } /* end if */ else { /* Non-flattened selection */ rank = space->extent.rank; - HDassert(rank >= 0 && rank <= H5S_MAX_RANK); /* within array bounds */ + HDassert(rank <= H5S_MAX_RANK); /* within array bounds */ if(0 == rank) goto empty; #ifdef H5S_DEBUG if(H5DEBUG(S)) HDfprintf(H5DEBUG(S),"%s: Non-flattened selection\n",FUNC); #endif - for(i = 0; i < rank; ++i) { - d[i].start = diminfo[i].start + space->select.offset[i]; - d[i].strid = diminfo[i].stride; - d[i].block = diminfo[i].block; - d[i].count = diminfo[i].count; - d[i].xtent = space->extent.size[i]; + for(u = 0; u < rank; ++u) { + H5_CHECK_OVERFLOW(diminfo[u].start, hsize_t, hssize_t) + d[u].start = (hssize_t)diminfo[u].start + space->select.offset[u]; + d[u].strid = diminfo[u].stride; + d[u].block = diminfo[u].block; + d[u].count = diminfo[u].count; + d[u].xtent = space->extent.size[u]; #ifdef H5S_DEBUG if(H5DEBUG(S)){ HDfprintf(H5DEBUG(S), "%s: start=%Hd stride=%Hu count=%Hu block=%Hu xtent=%Hu", - FUNC, d[i].start, d[i].strid, d[i].count, d[i].block, d[i].xtent ); - if (i==0) - HDfprintf(H5DEBUG(S), " rank=%d\n", rank ); + FUNC, d[u].start, d[u].strid, d[u].count, d[u].block, d[u].xtent ); + if (u==0) + HDfprintf(H5DEBUG(S), " rank=%u\n", rank ); else HDfprintf(H5DEBUG(S), "\n" ); } #endif - if(0 == d[i].block) + if(0 == d[u].block) goto empty; - if(0 == d[i].count) + if(0 == d[u].count) goto empty; - if(0 == d[i].xtent) + if(0 == d[u].xtent) goto empty; } /* end for */ } /* end else */ @@ -264,17 +268,17 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, max_xtent[rank - 1] = d[rank - 1].xtent; #ifdef H5S_DEBUG if(H5DEBUG(S)) { - i=rank-1; - HDfprintf(H5DEBUG(S), " offset[%2d]=%d; max_xtent[%2d]=%d\n", + i = ((int)rank) - 1; + HDfprintf(H5DEBUG(S), " offset[%2d]=%Hu; max_xtent[%2d]=%Hu\n", i, offset[i], i, max_xtent[i]); } #endif - for(i = rank - 2; i >= 0; --i) { + for(i = ((int)rank) - 2; i >= 0; --i) { offset[i] = offset[i + 1] * d[i + 1].xtent; max_xtent[i] = max_xtent[i + 1] * d[i].xtent; #ifdef H5S_DEBUG if(H5DEBUG(S)) - HDfprintf(H5DEBUG(S), " offset[%2d]=%d; max_xtent[%2d]=%d\n", + HDfprintf(H5DEBUG(S), " offset[%2d]=%Hu; max_xtent[%2d]=%Hu\n", i, offset[i], i, max_xtent[i]); #endif } /* end for */ @@ -290,7 +294,7 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, #ifdef H5S_DEBUG if(H5DEBUG(S)) { HDfprintf(H5DEBUG(S), "%s: Making contig type %Zu MPI_BYTEs\n", FUNC, elmt_size); - for (i=rank-1; i>=0; --i) + for(i = ((int)rank) - 1; i >= 0; --i) HDfprintf(H5DEBUG(S), "d[%d].xtent=%Hu \n", i, d[i].xtent); } #endif @@ -301,7 +305,7 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, * Construct the type by walking the hyperslab dims * from the inside out: *******************************************************/ - for(i = rank - 1; i >= 0; --i) { + for(i = ((int)rank) - 1; i >= 0; --i) { #ifdef H5S_DEBUG if(H5DEBUG(S)) HDfprintf(H5DEBUG(S), "%s: Dimension i=%d \n" @@ -538,7 +542,8 @@ H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, /* Store displacement & block length */ disp[outercount] = (MPI_Aint)elmt_size * tspan->low; - blocklen[outercount] = tspan->nelem; + H5_CHECK_OVERFLOW(tspan->nelem, hsize_t, int) + blocklen[outercount] = (int)tspan->nelem; tspan = tspan->next; outercount++; @@ -710,12 +715,15 @@ H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, } /* end else */ break; + case H5S_SEL_ERROR: + case H5S_SEL_N: default: HDassert("unknown selection type" && 0); break; } /* end switch */ break; + case H5S_NO_CLASS: default: HDassert("unknown data space type" && 0); break; diff --git a/src/H5Tbit.c b/src/H5Tbit.c index 2c289b0..a52d538 100644 --- a/src/H5Tbit.c +++ b/src/H5Tbit.c @@ -279,6 +279,7 @@ H5T_bit_get_d(uint8_t *buf, size_t offset, size_t size) case H5T_ORDER_ERROR: case H5T_ORDER_VAX: case H5T_ORDER_NONE: + case H5T_ORDER_MIXED: default: /* Unknown endianness. Bail out. */ HGOTO_DONE(UFAIL) @@ -326,6 +327,7 @@ H5T_bit_set_d(uint8_t *buf, size_t offset, size_t size, uint64_t val) case H5T_ORDER_ERROR: case H5T_ORDER_VAX: case H5T_ORDER_NONE: + case H5T_ORDER_MIXED: default: HDabort(); } /* end switch */ @@ -534,7 +536,7 @@ H5T_bit_inc(uint8_t *buf, size_t start, size_t size) else mask = ((unsigned)1 << (8 - start)) - 1; acc = ((unsigned)buf[idx] >> start) & mask; - acc += 1; + acc++; carry = acc & ((unsigned)1 << MIN(size, 8 - start)); buf[idx] &= (uint8_t)(~(mask << start)); buf[idx] |= (uint8_t)((acc & mask) << start); @@ -546,7 +548,7 @@ H5T_bit_inc(uint8_t *buf, size_t start, size_t size) /* The middle */ while(carry && size >= 8) { acc = buf[idx]; - acc += 1; + acc++; carry = acc & 0x100; buf[idx] = acc & 0xff; idx++; @@ -557,7 +559,7 @@ H5T_bit_inc(uint8_t *buf, size_t start, size_t size) if(carry && size > 0) { mask = ((unsigned)1 << size) - 1; acc = buf[idx] & mask; - acc += 1; + acc++; carry = acc & ((unsigned)1 << size); buf[idx] &= (uint8_t)(~mask); buf[idx] |= (uint8_t)(acc & mask); @@ -606,7 +608,7 @@ H5T_bit_dec(uint8_t *buf, size_t start, size_t size) */ if(!(buf[idx] >> pos)) borrow = 1; - buf[idx] -= 1 << pos; + buf[idx] = (uint8_t)(buf[idx] - (1 << pos)); idx++; size -= (8 - pos); @@ -614,7 +616,7 @@ H5T_bit_dec(uint8_t *buf, size_t start, size_t size) while(borrow && size >= 8) { if(buf[idx]) borrow = 0; - buf[idx] -= 1; + buf[idx]--; idx++; size -= 8; @@ -624,9 +626,9 @@ H5T_bit_dec(uint8_t *buf, size_t start, size_t size) if(borrow && size > 0) { /* Similar to the first byte case, where sequence ends in the same byte as starts */ tmp = buf[idx]; - buf[idx] -= 1; + buf[idx]--; if((buf[idx] >> size) != tmp >> size) - buf[idx] += 1 << size; + buf[idx] = (uint8_t)(buf[idx] + (1 << size)); } /* end if */ } /* end if */ else { /* bit sequence ends in the same byte as starts */ @@ -635,9 +637,9 @@ H5T_bit_dec(uint8_t *buf, size_t start, size_t size) * not equal). We need to put this bit back by increment 1000000. */ tmp = buf[idx]; - buf[idx] -= 1 << pos; + buf[idx] = (uint8_t)(buf[idx] - (1 << pos)); if((buf[idx] >> (pos + size)) != tmp >> (pos + size)) { - buf[idx] += 1 << (pos + size); + buf[idx] = (uint8_t)(buf[idx] + (1 << (pos + size))); borrow = 1; } /* end if */ } /* end else */ @@ -664,7 +666,7 @@ H5T_bit_neg(uint8_t *buf, size_t start, size_t size) { size_t idx = start / 8; size_t pos = start % 8; - uint8_t tmp; + uint8_t tmp[1]; /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_bit_neg); @@ -673,12 +675,11 @@ H5T_bit_neg(uint8_t *buf, size_t start, size_t size) HDassert(size); /* The first partial byte */ - tmp = buf[idx]; - tmp = (uint8_t)~tmp; + tmp[0] = (uint8_t)~buf[idx]; /* Simply copy the negated bit field back to the original byte */ if((size + start - 1) / 8 > idx) { /*bit sequence doesn't end in the same byte as starts*/ - H5T_bit_copy(&(buf[idx]), pos, &tmp, pos, (8-pos)); + H5T_bit_copy(&(buf[idx]), pos, tmp, pos, (8-pos)); idx++; size -= (8 - pos); @@ -692,13 +693,12 @@ H5T_bit_neg(uint8_t *buf, size_t start, size_t size) /* The last partial byte */ if(size > 0) { /* Similar to the first byte case, where sequence ends in the same byte as starts */ - tmp = buf[idx]; - tmp = (uint8_t)~tmp; - H5T_bit_copy(&(buf[idx]), (size_t)0, &tmp, (size_t)0, size); + tmp[0] = (uint8_t)~buf[idx]; + H5T_bit_copy(&(buf[idx]), (size_t)0, tmp, (size_t)0, size); } /* end if */ } /* end if */ else /* bit sequence ends in the same byte as starts */ - H5T_bit_copy(&(buf[idx]), pos, &tmp, pos, size); + H5T_bit_copy(&(buf[idx]), pos, tmp, pos, size); FUNC_LEAVE_NOAPI_VOID } /* end H5T_bit_neg() */ diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index b924b61..e109f95 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -302,6 +302,19 @@ H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id) if(H5T_commit(loc.oloc->file, type, tcpl_id, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") + /* Release the datatype's object header */ + { + H5O_loc_t *oloc; /* Object location for datatype */ + + /* Get the new committed datatype's object location */ + if(NULL == (oloc = H5T_oloc(type))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get object location of committed datatype") + + /* Decrement refcount on committed datatype's object header in memory */ + if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") + } /* end if */ + done: FUNC_LEAVE_API(ret_value) } /* end H5Tcommit_anon() */ @@ -379,7 +392,7 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id) * Create the object header and open it for write access. Insert the data * type message and then give the object header a name. */ - if(H5O_create(file, dxpl_id, dtype_size, tcpl_id, &temp_oloc) < 0) + if(H5O_create(file, dxpl_id, dtype_size, (size_t)1, tcpl_id, &temp_oloc) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create datatype object header") if(H5O_msg_create(&temp_oloc, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, type, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message") @@ -415,6 +428,8 @@ done: H5G_name_free(&temp_path); } /* end if */ if((type->shared->state == H5T_STATE_TRANSIENT || type->shared->state == H5T_STATE_RDONLY) && (type->sh_loc.type == H5O_SHARE_TYPE_COMMITTED)) { + if(H5O_dec_rc_by_loc(&(type->oloc), dxpl_id) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") if(H5O_close(&(type->oloc)) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release object header") if(H5O_delete(file, dxpl_id, type->sh_loc.u.loc.oh_addr) < 0) diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 9d98e50..927a9dc 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -662,17 +662,16 @@ CI_INC_DST(d_mv) \ \ /* Get the plist structure */ \ - if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) \ - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); \ + if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) \ + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") \ \ /* Get conversion exception callback property */ \ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) \ - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); \ + if(H5P_get(plist, H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) \ + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") \ \ /* Get source and destination datatypes */ \ - if (NULL==(st=(H5T_t*)H5I_object(src_id)) || NULL==(dt=(H5T_t*)H5I_object(dst_id))) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \ - "unable to dereference datatype object ID") \ + if(NULL == (st = (H5T_t *)H5I_object(src_id)) || NULL == (dt = (H5T_t *)H5I_object(dst_id))) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to dereference datatype object ID") \ \ /* Get source & destination precisions into a variable */ \ tclass = st->shared->type; \ @@ -1041,9 +1040,8 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, switch(cdata->command) { case H5T_CONV_INIT: /* Capability query */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset) @@ -1055,7 +1053,7 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, !((H5T_ORDER_BE == src->shared->u.atomic.order && H5T_ORDER_LE == dst->shared->u.atomic.order) || (H5T_ORDER_LE == src->shared->u.atomic.order && H5T_ORDER_BE == dst->shared->u.atomic.order))) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported") - if (src->shared->size != 1 && src->shared->size != 2 && src->shared->size != 4 && + if(src->shared->size != 1 && src->shared->size != 2 && src->shared->size != 4 && src->shared->size != 8 && src->shared->size != 16) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported") switch(src->shared->type) { @@ -1085,14 +1083,14 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, case H5T_CONV_CONV: /* The conversion */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Check for "no op" reference conversion */ if(src->shared->type == H5T_REFERENCE) { /* Sanity check */ - HDassert(dst->shared->type == H5T_REFERENCE); + if(dst->shared->type != H5T_REFERENCE) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype") /* Check if we are on a little-endian machine (the order that * the addresses in the file must be) and just get out now, there @@ -1452,7 +1450,7 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Capability query */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset || !((H5T_ORDER_BE == src->shared->u.atomic.order && @@ -1487,9 +1485,8 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* The conversion */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + if(NULL == (src = (H5T_t *)H5I_object(src_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") buf_stride = buf_stride ? buf_stride : src->shared->size; md = src->shared->size / 2; @@ -1535,7 +1532,7 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void UNUSED *background, hid_t dxpl_id) { uint8_t *buf = (uint8_t*)_buf; - H5T_t *src = NULL, *dst = NULL; /*source and dest data types */ + H5T_t *src = NULL, *dst = NULL; /*source and dest datatypes */ int direction; /*direction of traversal */ size_t elmtno; /*element number */ size_t olap; /*num overlapping elements */ @@ -1558,7 +1555,7 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Capability query */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") @@ -1572,10 +1569,9 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; case H5T_CONV_CONV: - /* Get the data types */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + /* Get the datatypes */ + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* * Do we process the values from beginning to end or vice versa? Also, @@ -1777,24 +1773,26 @@ H5T_conv_struct_free(H5T_conv_struct_t *priv) hid_t *src_memb_id = priv->src_memb_id, *dst_memb_id = priv->dst_memb_id; unsigned i; - int status; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_conv_struct_free) - for (i=0; i<priv->src_nmembs; i++) - if (src2dst[i] >= 0) { + for(i = 0; i < priv->src_nmembs; i++) + if(src2dst[i] >= 0) { + int status; + status = H5I_dec_ref(src_memb_id[i]); HDassert(status >= 0); status = H5I_dec_ref(dst_memb_id[src2dst[i]]); HDassert(status >= 0); - } + } /* end if */ H5MM_xfree(src2dst); H5MM_xfree(src_memb_id); H5MM_xfree(dst_memb_id); H5MM_xfree(priv->memb_path); - FUNC_LEAVE_NOAPI((H5T_conv_struct_t *)H5MM_xfree(priv)); -} + + FUNC_LEAVE_NOAPI((H5T_conv_struct_t *)H5MM_xfree(priv)) +} /* end H5T_conv_struct_free() */ /*------------------------------------------------------------------------- @@ -1852,9 +1850,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) int *src2dst = NULL; unsigned src_nmembs, dst_nmembs; unsigned i, j; - H5T_t *type = NULL; - hid_t tid; - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5T_conv_struct_init) @@ -1900,9 +1896,12 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) } /* end if */ } /* end for */ if(src2dst[i] >= 0) { + hid_t tid; + H5T_t *type; + type = H5T_copy(src->shared->u.compnd.memb[i].type, H5T_COPY_ALL); tid = H5I_register(H5I_DATATYPE, type, FALSE); - HDassert(tid>=0); + HDassert(tid >= 0); priv->src_memb_id[i] = tid; type = H5T_copy(dst->shared->u.compnd.memb[src2dst[i]].type, H5T_COPY_ALL); @@ -1933,7 +1932,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) H5T_path_t *tpath = H5T_path_find(src->shared->u.compnd.memb[i].type, dst->shared->u.compnd.memb[src2dst[i]].type, NULL, NULL, dxpl_id, FALSE); if(NULL == (priv->memb_path[i] = tpath)) { - cdata->priv = priv = H5T_conv_struct_free(priv); + cdata->priv = H5T_conv_struct_free(priv); HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member datatype") } /* end if */ } /* end if */ @@ -1959,8 +1958,8 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) * the end of src. */ if(priv->subset_info.subset == H5T_SUBSET_SRC) - priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs-1].offset - + src->shared->u.compnd.memb[src_nmembs-1].size; + priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs - 1].offset + + src->shared->u.compnd.memb[src_nmembs - 1].size; } else if(dst_nmembs < src_nmembs) { priv->subset_info.subset = H5T_SUBSET_DST; for(i = 0; i < dst_nmembs; i++) { @@ -2075,23 +2074,23 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, { uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ uint8_t *bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ - uint8_t *xbuf=buf, *xbkg=bkg; /*temp pointers into buf and bkg*/ + uint8_t *xbuf = buf, *xbkg = bkg; /*temp pointers into buf and bkg*/ H5T_t *src = NULL; /*source datatype */ H5T_t *dst = NULL; /*destination datatype */ int *src2dst = NULL; /*maps src member to dst member */ H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/ H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */ size_t offset; /*byte offset wrt struct */ - size_t src_delta; /*source stride */ + size_t src_delta; /*source stride */ size_t elmtno; - unsigned u; /*counters */ - int i; /*counters */ + unsigned u; /*counters */ + int i; /*counters */ H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5T_conv_struct, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: /* * First, determine if this conversion function applies to the @@ -2099,35 +2098,35 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * otherwise initialize the `priv' field of `cdata' with information * that remains (almost) constant for this conversion path. */ - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert (H5T_COMPOUND==src->shared->type); - assert (H5T_COMPOUND==dst->shared->type); + if (NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_COMPOUND != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") + if(H5T_COMPOUND != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") - if (H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); + if(H5T_conv_struct_init(src, dst, cdata, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") break; case H5T_CONV_FREE: /* * Free the private conversion data. */ - cdata->priv = priv = H5T_conv_struct_free(priv); + cdata->priv = H5T_conv_struct_free(priv); break; case H5T_CONV_CONV: /* * Conversion. */ - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert (priv); - assert (bkg && cdata->need_bkg); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + HDassert(priv); + HDassert(bkg && cdata->need_bkg); - if (cdata->recalc && H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); + if(cdata->recalc && H5T_conv_struct_init(src, dst, cdata, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") /* * Insure that members are sorted. @@ -2139,7 +2138,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* * Direction of conversion and striding through background. */ - if (buf_stride) { + if(buf_stride) { src_delta = buf_stride; if(!bkg_stride) bkg_stride = dst->shared->size; @@ -2156,7 +2155,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* end else */ /* Conversion loop... */ - for (elmtno=0; elmtno<nelmts; elmtno++) { + for(elmtno = 0; elmtno < nelmts; elmtno++) { /* * For each source member which will be present in the * destination, convert the member to the destination type unless @@ -2165,8 +2164,9 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * data point as small as possible with all the free space on the * right side. */ - for (u=0, offset=0; u<src->shared->u.compnd.nmembs; u++) { - if (src2dst[u]<0) continue; /*subsetting*/ + for(u = 0, offset = 0; u < src->shared->u.compnd.nmembs; u++) { + if(src2dst[u] < 0) + continue; /*subsetting*/ src_memb = src->shared->u.compnd.memb + u; dst_memb = dst->shared->u.compnd.memb + src2dst[u]; @@ -2176,15 +2176,16 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, (size_t)1, (size_t)0, (size_t)0, /*no striding (packed array)*/ xbuf + src_memb->offset, xbkg + dst_memb->offset, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member") HDmemmove(xbuf + offset, xbuf + src_memb->offset, dst_memb->size); offset += dst_memb->size; - } else { + } /* end if */ + else { HDmemmove (xbuf+offset, xbuf+src_memb->offset, src_memb->size); offset += src_memb->size; - } - } + } /* end else */ + } /* end for */ /* * For each source member which will be present in the @@ -2193,8 +2194,9 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * yet). Then copy the member to the destination offset in the * background buffer. */ - for (i=src->shared->u.compnd.nmembs-1; i>=0; --i) { - if (src2dst[i]<0) continue; /*subsetting*/ + for(i = src->shared->u.compnd.nmembs - 1; i >= 0; --i) { + if(src2dst[i] < 0) + continue; /*subsetting*/ src_memb = src->shared->u.compnd.memb + i; dst_memb = dst->shared->u.compnd.memb + src2dst[i]; @@ -2205,43 +2207,44 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, (size_t)1, (size_t)0, (size_t)0, /*no striding (packed array)*/ xbuf + offset, xbkg + dst_memb->offset, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member"); - } else + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member") + } /* end if */ + else offset -= dst_memb->size; HDmemmove(xbkg + dst_memb->offset, xbuf + offset, dst_memb->size); - } - assert (0==offset); + } /* end for */ + HDassert(0 == offset); /* * Update pointers */ xbuf += src_delta; xbkg += bkg_stride; - } + } /* end for */ /* If the bkg_stride was set to -(dst->shared->size), make it positive now */ - if(buf_stride==0 && dst->shared->size>src->shared->size) - bkg_stride=dst->shared->size; + if(buf_stride == 0 && dst->shared->size > src->shared->size) + bkg_stride = dst->shared->size; /* * Copy the background buffer back into the in-place conversion * buffer. */ - for (xbuf=buf, xbkg=bkg, elmtno=0; elmtno<nelmts; elmtno++) { + for(xbuf = buf, xbkg = bkg, elmtno = 0; elmtno < nelmts; elmtno++) { HDmemmove(xbuf, xbkg, dst->shared->size); xbuf += buf_stride ? buf_stride : dst->shared->size; xbkg += bkg_stride; - } + } /* end for */ break; default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_struct() */ /*------------------------------------------------------------------------- @@ -2337,7 +2340,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, FUNC_ENTER_NOAPI(H5T_conv_struct_opt, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: /* * First, determine if this conversion function applies to the @@ -2347,8 +2350,10 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - HDassert(H5T_COMPOUND == src->shared->type); - HDassert(H5T_COMPOUND == dst->shared->type); + if(H5T_COMPOUND != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") + if(H5T_COMPOUND != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") /* Initialize data which is relatively constant */ if(H5T_conv_struct_init(src, dst, cdata, dxpl_id) < 0) @@ -2383,7 +2388,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, if(dst_memb->size > src_memb->size) { offset -= src_memb->size; if(dst_memb->size > src->shared->size-offset) { - cdata->priv = priv = H5T_conv_struct_free(priv); + cdata->priv = H5T_conv_struct_free(priv); HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "convertion is unsupported by this function") } /* end if */ } /* end if */ @@ -2395,8 +2400,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, /* * Free the private conversion data. */ - priv = (H5T_conv_struct_t *)(cdata->priv); - cdata->priv = priv = H5T_conv_struct_free(priv); + cdata->priv = H5T_conv_struct_free((H5T_conv_struct_t *)(cdata->priv)); break; case H5T_CONV_CONV: @@ -2410,8 +2414,8 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, if(cdata->recalc && H5T_conv_struct_init(src, dst, cdata, dxpl_id)<0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") priv = (H5T_conv_struct_t *)(cdata->priv); - src2dst = priv->src2dst; HDassert(priv); + src2dst = priv->src2dst; HDassert(bkg && cdata->need_bkg); /* @@ -2558,20 +2562,20 @@ done: static herr_t H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) { - H5T_enum_struct_t *priv=NULL; /*private conversion data */ + H5T_enum_struct_t *priv = NULL; /*private conversion data */ int n; /*src value cast as native int */ int domain[2] = {0, 0}; /*min and max source values */ - int *map=NULL; /*map from src value to dst idx */ + int *map = NULL; /*map from src value to dst idx */ unsigned length; /*nelmts in map array */ unsigned i, j; /*counters */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5T_conv_enum_init) cdata->need_bkg = H5T_BKG_NO; - if (NULL==(priv=(H5T_enum_struct_t *)(cdata->priv=H5MM_calloc(sizeof(*priv))))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - if (0==src->shared->u.enumer.nmembs) + if(NULL == (priv = (H5T_enum_struct_t *)(cdata->priv = H5MM_calloc(sizeof(*priv))))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + if(0 == src->shared->u.enumer.nmembs) HGOTO_DONE(SUCCEED); /* @@ -2581,18 +2585,18 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) */ H5T_sort_name(src, NULL); H5T_sort_name(dst, NULL); - if (NULL==(priv->src2dst=(int *)H5MM_malloc(src->shared->u.enumer.nmembs*sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");; - for (i=0, j=0; - i<src->shared->u.enumer.nmembs && j<dst->shared->u.enumer.nmembs; + if(NULL == (priv->src2dst = (int *)H5MM_malloc(src->shared->u.enumer.nmembs * sizeof(int)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + for(i = 0, j = 0; + i < src->shared->u.enumer.nmembs && j < dst->shared->u.enumer.nmembs; i++, j++) { - while (j<dst->shared->u.enumer.nmembs && + while(j < dst->shared->u.enumer.nmembs && HDstrcmp(src->shared->u.enumer.name[i], dst->shared->u.enumer.name[j])) j++; - if (j>=dst->shared->u.enumer.nmembs) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source type is not a subset of destination type"); + if(j >= dst->shared->u.enumer.nmembs) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source type is not a subset of destination type") priv->src2dst[i] = j; - } + } /* end for */ /* * The conversion function will use an O(log N) lookup method for each @@ -2634,7 +2638,7 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) priv->base = domain[0]; priv->length = length; if (NULL==(map=(int *)H5MM_malloc(length*sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") for (i=0; i<length; i++) map[i] = -1; /*entry unused*/ for (i=0; i<src->shared->u.enumer.nmembs; i++) { @@ -2701,20 +2705,20 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void UNUSED *bkg, hid_t UNUSED dxpl_id) { uint8_t *buf = (uint8_t*)_buf; /*cast for pointer arithmetic */ - H5T_t *src=NULL, *dst=NULL; /*src and dst datatypes */ - uint8_t *s=NULL, *d=NULL; /*src and dst BUF pointers */ + H5T_t *src = NULL, *dst = NULL; /*src and dst datatypes */ + uint8_t *s = NULL, *d = NULL; /*src and dst BUF pointers */ int src_delta, dst_delta; /*conversion strides */ int n; /*src value cast as native int */ - size_t i; /*counters */ H5T_enum_struct_t *priv = (H5T_enum_struct_t*)(cdata->priv); H5P_genplist_t *plist; /*property list pointer */ H5T_conv_cb_t cb_struct; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ - herr_t ret_value=SUCCEED; /* Return value */ + size_t i; /*counters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5T_conv_enum, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: /* * Determine if this conversion function applies to the conversion @@ -2722,13 +2726,15 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * the `priv' field of `cdata' with information about the underlying * integer conversion. */ - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert (H5T_ENUM==src->shared->type); - assert (H5T_ENUM==dst->shared->type); - if (H5T_conv_enum_init(src, dst, cdata)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_ENUM != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") + if(H5T_ENUM != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") + + if(H5T_conv_enum_init(src, dst, cdata) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data") break; case H5T_CONV_FREE: @@ -2747,26 +2753,28 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; case H5T_CONV_CONV: - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert (H5T_ENUM==src->shared->type); - assert (H5T_ENUM==dst->shared->type); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_ENUM != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") + if(H5T_ENUM != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") /* priv->src2dst map was computed for certain sort keys. Make sure those same * sort keys are used here during conversion. See H5T_conv_enum_init(). But * we actually don't care about the source type's order when doing the O(1) * conversion algorithm, which is turned on by non-zero priv->length */ H5T_sort_name(dst, NULL); - if (!priv->length) H5T_sort_value(src, NULL); + if(!priv->length) + H5T_sort_value(src, NULL); /* * Direction of conversion. */ - if (buf_stride) { + if(buf_stride) { src_delta = dst_delta = (int)buf_stride; s = d = buf; - } else if (dst->shared->size <= src->shared->size) { + } else if(dst->shared->size <= src->shared->size) { src_delta = (int)src->shared->size; /*overflow shouldn't be possible*/ dst_delta = (int)dst->shared->size; /*overflow shouldn't be possible*/ s = d = buf; @@ -2778,25 +2786,24 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + if(H5P_get(plist, H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") - for (i=0; i<nelmts; i++, s+=src_delta, d+=dst_delta) { - if (priv->length) { + for(i = 0; i < nelmts; i++, s += src_delta, d += dst_delta) { + if(priv->length) { /* Use O(1) lookup */ - if (1==src->shared->size) { + if(1 == src->shared->size) n = *((signed char*)s); - } else if (sizeof(short)==src->shared->size) { + else if(sizeof(short) == src->shared->size) n = *((short*)s); - } else { + else n = *((int*)s); - } n -= priv->base; - if (n<0 || n>=priv->length || priv->src2dst[n]<0) { + if(n < 0 || n >= priv->length || priv->src2dst[n] < 0) { /*overflow*/ except_ret = H5T_CONV_UNHANDLED; if(cb_struct.func) { /*If user's exception handler is present, use it*/ @@ -2818,19 +2825,19 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, int lt = 0; int rt = src->shared->u.enumer.nmembs; int md, cmp; - while (lt<rt) { - md = (lt+rt)/2; - cmp = HDmemcmp(s, src->shared->u.enumer.value+md*src->shared->size, + + while(lt < rt) { + md = (lt + rt) / 2; + cmp = HDmemcmp(s, src->shared->u.enumer.value + md * src->shared->size, src->shared->size); - if (cmp<0) { + if(cmp < 0) rt = md; - } else if (cmp>0) { - lt = md+1; - } else { + else if(cmp > 0) + lt = md + 1; + else break; - } - } - if (lt>=rt) { + } /* end while */ + if(lt >= rt) { except_ret = H5T_CONV_UNHANDLED; if(cb_struct.func) { /*If user's exception handler is present, use it*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, @@ -2841,23 +2848,24 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, HDmemset(d, 0xff, dst->shared->size); } else if(except_ret == H5T_CONV_ABORT) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") - } else { + } /* end if */ + else { HDmemcpy(d, dst->shared->u.enumer.value+priv->src2dst[md]*dst->shared->size, dst->shared->size); - } + } /* end else */ } } break; default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_enum() */ /*------------------------------------------------------------------------- @@ -2930,7 +2938,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_ENTER_NOAPI(H5T_conv_vlen, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: /* * First, determine if this conversion function applies to the @@ -2940,9 +2948,11 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * conversion path. */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - HDassert(H5T_VLEN == src->shared->type); - HDassert(H5T_VLEN == dst->shared->type); + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_VLEN != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") + if(H5T_VLEN != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") /* Variable-length types don't need a background buffer */ cdata->need_bkg = H5T_BKG_NO; @@ -3331,8 +3341,8 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: /* Release the background buffer, if we have one */ @@ -3340,7 +3350,7 @@ done: bkg_buf = H5FL_BLK_FREE(array_seq, bkg_buf); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_conv_array() */ +} /* end H5T_conv_array() */ /*------------------------------------------------------------------------- @@ -3396,19 +3406,16 @@ H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_ENTER_NOAPI(H5T_conv_i_i, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src=(H5T_t *)H5I_object(src_id)) || - NULL==(dst=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_ORDER_LE!=src->shared->u.atomic.order && - H5T_ORDER_BE!=src->shared->u.atomic.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (H5T_ORDER_LE!=dst->shared->u.atomic.order && - H5T_ORDER_BE!=dst->shared->u.atomic.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst->shared->size>sizeof dbuf) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(H5T_ORDER_LE != dst->shared->u.atomic.order && H5T_ORDER_BE != dst->shared->u.atomic.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(dst->shared->size > sizeof dbuf) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large") cdata->need_bkg = H5T_BKG_NO; break; @@ -3417,9 +3424,8 @@ H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src=(H5T_t *)H5I_object(src_id)) || - NULL==(dst=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* * Do we process the values from beginning to end or vice versa? Also, @@ -3441,18 +3447,18 @@ H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, double olap_d = HDceil((double)(src->shared->size)/ (double)(dst->shared->size-src->shared->size)); olap = (size_t)olap_d; - sp = (uint8_t*)buf + (nelmts-1) * src->shared->size; - dp = (uint8_t*)buf + (nelmts-1) * dst->shared->size; + sp = (uint8_t*)buf + (nelmts - 1) * src->shared->size; + dp = (uint8_t*)buf + (nelmts - 1) * dst->shared->size; direction = -1; } /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + if(H5P_get(plist,H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") /* Allocate space for order-reversed source buffer */ src_rev = (uint8_t*)H5MM_calloc(src->shared->size); @@ -3741,14 +3747,14 @@ H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: if(src_rev) H5MM_free(src_rev); FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_i_i() */ /*------------------------------------------------------------------------- @@ -3783,7 +3789,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, +H5T_conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg, hid_t dxpl_id) { @@ -3799,44 +3805,43 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t olap; /*num overlapping elements */ ssize_t bitno = 0; /*bit number */ uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t *src_rev=NULL; /*order-reversed source buffer */ + uint8_t *src_rev = NULL; /*order-reversed source buffer */ uint8_t dbuf[64]; /*temp destination buffer */ uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ /* Conversion-related variables */ hssize_t expo; /*exponent */ hssize_t expo_max; /*maximum possible dst exponent */ - size_t msize=0; /*useful size of mantissa in src*/ + size_t msize = 0; /*useful size of mantissa in src*/ size_t mpos; /*offset to useful mant is src */ hssize_t sign; /*source sign bit value */ size_t mrsh; /*amount to right shift mantissa*/ - hbool_t carry=0; /*carry after rounding mantissa */ + hbool_t carry = 0; /*carry after rounding mantissa */ size_t i; /*miscellaneous counters */ size_t implied; /*destination implied bits */ - hbool_t denormalized=FALSE; /*is either source or destination denormalized?*/ + hbool_t denormalized = FALSE; /*is either source or destination denormalized?*/ H5P_genplist_t *plist; /*property list pointer */ - H5T_conv_cb_t cb_struct={NULL, NULL}; /*conversion callback structure */ + H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ hbool_t reverse; /*if reverse the order of destination */ - herr_t ret_value=SUCCEED; /*return value */ + herr_t ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI(H5T_conv_f_f, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src_p=(H5T_t *)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE!=src.order && H5T_ORDER_BE!=src.order && H5T_ORDER_VAX!=src.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (H5T_ORDER_LE!=dst.order && H5T_ORDER_BE!=dst.order && H5T_ORDER_VAX!=dst.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size>sizeof(dbuf)) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8*sizeof(expo)-1<src.u.f.esize || 8*sizeof(expo)-1<dst.u.f.esize) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + if(H5T_ORDER_LE != src.order && H5T_ORDER_BE != src.order && H5T_ORDER_VAX != src.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(H5T_ORDER_LE != dst.order && H5T_ORDER_BE != dst.order && H5T_ORDER_VAX != dst.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large") + if(8 * sizeof(expo) - 1 < src.u.f.esize || 8 * sizeof(expo) - 1 < dst.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large") cdata->need_bkg = H5T_BKG_NO; break; @@ -3845,9 +3850,8 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src_p=(H5T_t *)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; expo_max = ((hssize_t)1 << dst.u.f.esize) - 1; @@ -3878,11 +3882,11 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + if(H5P_get(plist,H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") /* Allocate space for order-reversed source buffer */ src_rev = (uint8_t*)H5MM_calloc(src_p->shared->size); @@ -4319,15 +4323,15 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: if(src_rev) H5MM_free(src_rev); FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_f_f() */ /*------------------------------------------------------------------------- @@ -4365,22 +4369,21 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_ENTER_NOAPI(H5T_conv_s_s, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src=(H5T_t *)H5I_object(src_id)) || - NULL==(dst=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (8*src->shared->size != src->shared->u.atomic.prec || 8*dst->shared->size != dst->shared->u.atomic.prec) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision"); - if (0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset"); - if (H5T_CSET_ASCII != src->shared->u.atomic.u.s.cset && H5T_CSET_UTF8 != src->shared->u.atomic.u.s.cset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad source character set"); - if (H5T_CSET_ASCII != dst->shared->u.atomic.u.s.cset && H5T_CSET_UTF8 != dst->shared->u.atomic.u.s.cset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad destination character set"); - if (src->shared->u.atomic.u.s.pad<0 || src->shared->u.atomic.u.s.pad>=H5T_NPAD || - dst->shared->u.atomic.u.s.pad<0 || dst->shared->u.atomic.u.s.pad>=H5T_NPAD) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if(8 * src->shared->size != src->shared->u.atomic.prec || 8 * dst->shared->size != dst->shared->u.atomic.prec) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision") + if(0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset") + if(H5T_CSET_ASCII != src->shared->u.atomic.u.s.cset && H5T_CSET_UTF8 != src->shared->u.atomic.u.s.cset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad source character set") + if(H5T_CSET_ASCII != dst->shared->u.atomic.u.s.cset && H5T_CSET_UTF8 != dst->shared->u.atomic.u.s.cset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad destination character set") + if(src->shared->u.atomic.u.s.pad < 0 || src->shared->u.atomic.u.s.pad >= H5T_NPAD || + dst->shared->u.atomic.u.s.pad < 0 || dst->shared->u.atomic.u.s.pad >= H5T_NPAD) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding") cdata->need_bkg = H5T_BKG_NO; break; @@ -4389,9 +4392,8 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src=(H5T_t *)H5I_object(src_id)) || - NULL==(dst=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* * Do we process the values from beginning to end or vice versa? Also, @@ -4422,22 +4424,22 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* Allocate the overlap buffer */ - if (NULL==(dbuf=(uint8_t *)H5MM_malloc(dst->shared->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for string conversion"); + if(NULL == (dbuf = (uint8_t *)H5MM_malloc(dst->shared->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for string conversion") /* The conversion loop. */ - for (elmtno=0; elmtno<nelmts; elmtno++) { + for(elmtno = 0; elmtno < nelmts; elmtno++) { /* * If the source and destination buffers overlap then use a * temporary buffer for the destination. */ - if (direction>0) { + if(direction > 0) { s = sp; - d = elmtno<olap ? dbuf : dp; + d = elmtno < olap ? dbuf : dp; } else { s = sp; - d = elmtno+olap >= nelmts ? dbuf : dp; + d = elmtno + olap >= nelmts ? dbuf : dp; } #ifndef NDEBUG /* I don't quite trust the overlap calculations yet --rpm */ @@ -4453,7 +4455,7 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, #endif /* Copy characters from source to destination */ - switch (src->shared->u.atomic.u.s.pad) { + switch(src->shared->u.atomic.u.s.pad) { case H5T_STR_NULLTERM: for (nchars=0; nchars<dst->shared->size && nchars<src->shared->size && s[nchars]; @@ -4493,24 +4495,24 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_STR_RESERVED_14: case H5T_STR_RESERVED_15: case H5T_STR_ERROR: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source string padding method not supported"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source string padding method not supported") + } /* end switch */ /* Terminate or pad the destination */ - switch (dst->shared->u.atomic.u.s.pad) { + switch(dst->shared->u.atomic.u.s.pad) { case H5T_STR_NULLTERM: - while (nchars<dst->shared->size) + while(nchars < dst->shared->size) d[nchars++] = '\0'; - d[dst->shared->size-1] = '\0'; + d[dst->shared->size - 1] = '\0'; break; case H5T_STR_NULLPAD: - while (nchars<dst->shared->size) + while(nchars < dst->shared->size) d[nchars++] = '\0'; break; case H5T_STR_SPACEPAD: - while (nchars<dst->shared->size) + while(nchars < dst->shared->size) d[nchars++] = ' '; break; @@ -4528,8 +4530,8 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_STR_RESERVED_14: case H5T_STR_RESERVED_15: case H5T_STR_ERROR: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination string padding method not supported"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination string padding method not supported") + } /* end switch */ /* * If we used a temporary buffer for the destination then we @@ -4544,17 +4546,18 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, sp += direction * src->shared->size; dp += direction * dst->shared->size; } - } + } /* end for */ break; default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown converson command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown converson command") + } /* end switch */ done: H5MM_xfree(dbuf); + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_s_s() */ /*------------------------------------------------------------------------- @@ -9714,7 +9717,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, +H5T_conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg, hid_t dxpl_id) { @@ -9750,19 +9753,18 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_ENTER_NOAPI(H5T_conv_f_i, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t*)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t*)H5I_object(src_id)) || NULL == (dst_p = (H5T_t*)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE!=src.order && H5T_ORDER_BE!=src.order && H5T_ORDER_VAX!=src.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size>sizeof(dbuf)) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8*sizeof(expo)-1<src.u.f.esize) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + if(H5T_ORDER_LE != src.order && H5T_ORDER_BE != src.order && H5T_ORDER_VAX != src.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large") + if(8 * sizeof(expo) - 1 < src.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large") cdata->need_bkg = H5T_BKG_NO; break; @@ -9771,9 +9773,8 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t*)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t*)H5I_object(src_id)) || NULL == (dst_p = (H5T_t*)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -9782,7 +9783,7 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * how many of the elements have the source and destination areas * overlapping? */ - if (src_p->shared->size==dst_p->shared->size || buf_stride) { + if(src_p->shared->size==dst_p->shared->size || buf_stride) { sp = dp = (uint8_t*)buf; direction = 1; olap = nelmts; @@ -9809,11 +9810,11 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Get the plist structure. Do I need to close it? */ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ if(H5P_get(plist, H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") /* Allocate space for order-reversed source buffer */ src_rev = (uint8_t*)H5MM_calloc(src_p->shared->size); @@ -10265,16 +10266,17 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: if(int_buf) H5MM_xfree(int_buf); if(src_rev) H5MM_free(src_rev); + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_f_i() */ /*------------------------------------------------------------------------- @@ -10302,7 +10304,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, +H5T_conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg, hid_t dxpl_id) { @@ -10317,7 +10319,7 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t tsize; /*type size for swapping bytes */ size_t olap; /*num overlapping elements */ uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t *src_rev=NULL; /*order-reversed source buffer */ + uint8_t *src_rev = NULL; /*order-reversed source buffer */ uint8_t dbuf[64]; /*temp destination buffer */ uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ @@ -10327,32 +10329,31 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t sign; /*source sign bit value */ hbool_t is_max_neg; /*source is maximal negative value*/ hbool_t do_round; /*whether there is roundup */ - uint8_t *int_buf=NULL; /*buffer for temporary value */ + uint8_t *int_buf = NULL; /*buffer for temporary value */ size_t buf_size; /*buffer size for temporary value */ size_t i; /*miscellaneous counters */ size_t first; /*first bit(MSB) in an integer */ ssize_t sfirst; /*a signed version of `first' */ H5P_genplist_t *plist; /*Property list pointer */ - H5T_conv_cb_t cb_struct={NULL, NULL}; /*conversion callback structure */ + H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ hbool_t reverse; /*if reverse the order of destination */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5T_conv_i_f, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t*)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE!=dst.order && H5T_ORDER_BE!=dst.order && H5T_ORDER_VAX!=dst.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size>sizeof(dbuf)) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8*sizeof(expo)-1<src.u.f.esize) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + if(H5T_ORDER_LE != dst.order && H5T_ORDER_BE != dst.order && H5T_ORDER_VAX != dst.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large") + if(8 * sizeof(expo) - 1 < src.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large") cdata->need_bkg = H5T_BKG_NO; break; @@ -10361,9 +10362,8 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t*)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -10399,11 +10399,11 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + if(H5P_get(plist,H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") /* Allocate space for order-reversed source buffer */ src_rev = (uint8_t*)H5MM_calloc(src_p->shared->size); @@ -10696,16 +10696,17 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: if(int_buf) H5MM_xfree(int_buf); if(src_rev) H5MM_free(src_rev); + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_i_f() */ /*------------------------------------------------------------------------- diff --git a/src/H5Znbit.c b/src/H5Znbit.c index bcdd549..263b2cd 100644 --- a/src/H5Znbit.c +++ b/src/H5Znbit.c @@ -1365,17 +1365,17 @@ static void H5Z_nbit_compress_one_compound(unsigned char *data, size_t data_offs static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, size_t *buffer_size, const unsigned parms[]) { - /* i: index of data, j: index of buffer, + /* i: index of data, new_size: index of buffer, buf_len: number of bits to be filled in current byte */ - size_t i, j, size; + size_t i, size; + size_t new_size = 0; int buf_len; parms_atomic p; /* must initialize buffer to be zeros */ - for(j = 0; j < *buffer_size; j++) buffer[j] = 0; + HDmemset(buffer, 0, *buffer_size); /* initialization before the loop */ - j = 0; buf_len = sizeof(unsigned char) * 8; switch(parms[3]) { @@ -1387,14 +1387,14 @@ static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned c p.offset = parms[7]; for(i = 0; i < d_nelmts; i++) { - H5Z_nbit_compress_one_atomic(data, i*p.size, buffer, &j, &buf_len, p); + H5Z_nbit_compress_one_atomic(data, i*p.size, buffer, &new_size, &buf_len, p); } break; case H5Z_NBIT_ARRAY: size = parms[4]; parms_index = 4; for(i = 0; i < d_nelmts; i++) { - H5Z_nbit_compress_one_array(data, i*size, buffer, &j, &buf_len, parms); + H5Z_nbit_compress_one_array(data, i*size, buffer, &new_size, &buf_len, parms); parms_index = 4; } break; @@ -1402,10 +1402,14 @@ static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned c size = parms[4]; parms_index = 4; for(i = 0; i < d_nelmts; i++) { - H5Z_nbit_compress_one_compound(data, i*size, buffer, &j, &buf_len, parms); + H5Z_nbit_compress_one_compound(data, i*size, buffer, &new_size, &buf_len, parms); parms_index = 4; } break; } /* end switch */ + + /* Update the size to the new value after compression. If there are any bits hanging over in + * the last byte, increment the value by 1. */ + *buffer_size = new_size + 1; } #endif /* H5_HAVE_FILTER_NBIT */ diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index eb3c6e6..c524141 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -53,16 +53,16 @@ static size_t H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, static void H5Z_scaleoffset_convert(void *buf, unsigned d_nelmts, size_t dtype_size); static unsigned H5Z_scaleoffset_log2(unsigned long long num); static void H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, - enum H5Z_scaleoffset_t type, unsigned filavail, const void *filval_buf, + enum H5Z_scaleoffset_t type, unsigned filavail, const unsigned cd_values[], uint32_t *minbits, unsigned long long *minval); static void H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, - enum H5Z_scaleoffset_t type, unsigned filavail, const void *filval_buf, + enum H5Z_scaleoffset_t type, unsigned filavail, const unsigned cd_values[], uint32_t minbits, unsigned long long minval); static herr_t H5Z_scaleoffset_precompress_fd(void *data, unsigned d_nelmts, - enum H5Z_scaleoffset_t type, unsigned filavail, const void *filval_buf, + enum H5Z_scaleoffset_t type, unsigned filavail, const unsigned cd_values[], uint32_t *minbits, unsigned long long *minval, double D_val); static herr_t H5Z_scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, - enum H5Z_scaleoffset_t type, unsigned filavail, const void *filval_buf, + enum H5Z_scaleoffset_t type, unsigned filavail, const unsigned cd_values[], uint32_t minbits, unsigned long long minval, double D_val); static void H5Z_scaleoffset_next_byte(size_t *j, unsigned *buf_len); static void H5Z_scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, @@ -119,24 +119,71 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ /* Store fill value in cd_values[] */ #define H5Z_scaleoffset_save_filval(type, cd_values, fill_val) \ { \ - unsigned char *fill_parm; /* Pointer to fill value parameter */ \ + unsigned _i = H5Z_SCALEOFFSET_PARM_FILVAL; /* index into cd_values */ \ + uint32_t _cd_value; /* Current cd_value */ \ + char *_fv_p; /* Pointer to current byte in fill_val */ \ + size_t _copy_size = 4; /* # of bytes to copy this iteration */ \ + size_t _size_rem = sizeof(type); /* # of bytes left to copy to cd_values */ \ \ /* Store the fill value as the last entry in cd_values[] \ * Store byte by byte from least significant byte to most significant byte \ * Plenty of space left for the fill value (from index 8 to 19) \ + * H5O_pline_encode will byte-swap each individual cd value, but we still \ + * need to swap the cd values as a whole if we are on a BE machine. Note \ + * that we need to make sure to put the data only in the lowest 4 bytes of \ + * each, if sizeof(unsigned) > 4. \ */ \ - fill_parm = (unsigned char *)&cd_values[H5Z_SCALEOFFSET_PARM_FILVAL]; \ - if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(fill_parm, &fill_val, sizeof(type)); \ - else { \ - unsigned char *fill_buf; /* Pointer to fill value in memory */ \ - unsigned u; /* index */ \ + if(H5T_native_order_g == H5T_ORDER_LE) { \ + _fv_p = (char *)&(fill_val); \ + /* Copy 4 bytes at a time to each cd value */ \ + do { \ + if(_size_rem < 4) { \ + /* Amount left to copy is smaller than a cd_value, adjust copy \ + * size and initialize cd_value as it will not be fully \ + * overwritten */ \ + _copy_size = _size_rem; \ + _cd_value = (uint32_t)0; \ + } /* end if */ \ + \ + /* Copy the value */ \ + HDmemcpy(&_cd_value, _fv_p, _copy_size); \ + (cd_values)[_i] = (unsigned)_cd_value; \ \ + /* Next field */ \ + _i++; \ + _fv_p += _copy_size; \ + _size_rem -= _copy_size; \ + } while(_size_rem); \ + } /* end if */ \ + else { \ HDassert(H5T_native_order_g == H5T_ORDER_BE); \ \ - fill_buf = (unsigned char *)&fill_val; \ - for(u = 0; u < sizeof(type); u++) \ - fill_parm[u] = fill_buf[sizeof(type) - (u + 1)]; \ + /* Copy 4 bytes at a time to each cd value, but start at the end \ + * (highest address) of fill_val */ \ + _fv_p = ((char *)&(fill_val)) + sizeof(type) - MIN(4, _size_rem); \ + while(_size_rem >= 4) { \ + /* Copy the value */ \ + HDmemcpy(&_cd_value, _fv_p, _copy_size); \ + (cd_values)[_i] = (unsigned)_cd_value; \ + \ + /* Next field */ \ + _i++; \ + _size_rem -= 4; \ + if(_size_rem >= 4) \ + _fv_p -= 4; \ + else \ + _fv_p -= _size_rem; \ + } /* end while */ \ + \ + HDassert(_fv_p == (char *)&(fill_val)); \ + if(_size_rem) { \ + /* Amount left to copy is smaller than a cd_value, initialize \ + * _cd_value as it will not be fully overwritten and copy to the end \ + * of _cd value as it is BE. */ \ + _cd_value = (uint32_t)0; \ + HDmemcpy((char *)&_cd_value + 4 - _size_rem, _fv_p, _size_rem); \ + (cd_values)[_i] = (unsigned)_cd_value; \ + } /* end if */ \ } /* end else */ \ } @@ -180,7 +227,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "unable to get fill value") \ \ /* Store the fill value as the last entry in cd_values[] */ \ - ((unsigned char *)&cd_values[H5Z_SCALEOFFSET_PARM_FILVAL])[0] = (unsigned char)fill_val; \ + (cd_values)[H5Z_SCALEOFFSET_PARM_FILVAL] = (unsigned)((unsigned char)fill_val); \ } /* Set the fill value parameter in cd_values[] for floating-point type */ @@ -199,33 +246,78 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Get the fill value for integer type */ -#define H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ -{ \ - const unsigned char *fill_parm; /* Pointer to fill value parameter */ \ - \ - /* retrieve fill value from corresponding positions of cd_values[] \ - * retrieve them corresponding to how they are stored \ - */ \ - fill_parm = (const unsigned char *)filval_buf; \ - if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(&filval, fill_parm, sizeof(type)); \ - else { \ - unsigned char *fill_buf; /* Pointer to fill value in memory */ \ - unsigned u; /* index */ \ - \ - HDassert(H5T_native_order_g == H5T_ORDER_BE); \ - \ - fill_buf = (unsigned char *)&filval; \ - for(u = 0; u < sizeof(type); u++) \ - fill_buf[u] = fill_parm[sizeof(type) - (u + 1)]; \ - } /* end else */ \ +#define H5Z_scaleoffset_get_filval_1(type, cd_values, fill_val) \ +{ \ + unsigned _i = H5Z_SCALEOFFSET_PARM_FILVAL; /* index into cd_values */ \ + uint32_t _cd_value; /* Current cd_value */ \ + char *_fv_p; /* Pointer to current byte in fill_val */ \ + size_t _copy_size = 4; /* # of bytes to copy this iteration */ \ + size_t _size_rem = sizeof(type); /* # of bytes left to copy to filval */ \ + \ + /* Retrieve the fill value from the last entry in cd_values[] \ + * Store byte by byte from least significant byte to most significant byte \ + * Plenty of space left for the fill value (from index 8 to 19) \ + * H5O_pline_encode will byte-swap each individual cd value, but we still \ + * need to swap the cd values as a whole if we are on a BE machine. Note \ + * that we need to make sure to put the data only in the lowest 4 bytes of \ + * each, if sizeof(unsigned) > 4. \ + */ \ + if(H5T_native_order_g == H5T_ORDER_LE) { \ + _fv_p = (char *)&(fill_val); \ + /* Copy 4 bytes at a time to each cd value */ \ + do { \ + if(_size_rem < 4) \ + /* Amount left to copy is smaller than a cd_value, adjust copy \ + * size and initialize cd_value as it will not be fully \ + * overwritten */ \ + _copy_size = _size_rem; \ + \ + /* Copy the value */ \ + _cd_value = (uint32_t)(cd_values)[_i]; \ + HDmemcpy(_fv_p, &_cd_value, _copy_size); \ + \ + /* Next field */ \ + _i++; \ + _fv_p += _copy_size; \ + _size_rem -= _copy_size; \ + } while(_size_rem); \ + } /* end if */ \ + else { \ + HDassert(H5T_native_order_g == H5T_ORDER_BE); \ + \ + /* Copy 4 bytes at a time to each cd value, but start at the end \ + * (highest address) of fill_val */ \ + _fv_p = ((char *)&(fill_val)) + sizeof(type) - MIN(4, _size_rem); \ + while(_size_rem >= 4) { \ + /* Copy the value */ \ + _cd_value = (uint32_t)(cd_values)[_i]; \ + HDmemcpy(_fv_p, &_cd_value, _copy_size); \ + \ + /* Next field */ \ + _i++; \ + _size_rem -= 4; \ + if(_size_rem >=4) \ + _fv_p -= 4; \ + else \ + _fv_p -= _size_rem; \ + } /* end while */ \ + \ + HDassert(_fv_p == (char *)&(fill_val)); \ + if(_size_rem) { \ + /* Amount left to copy is smaller than a cd_value, initialize \ + * _cd_value as it will not be fully overwritten and copy to the end \ + * of _cd value as it is BE. */ \ + _cd_value = (uint32_t)(cd_values)[_i]; \ + HDmemcpy(_fv_p, (char *)&_cd_value + 4 - _size_rem, _size_rem); \ + } /* end if */ \ + } /* end else */ \ } /* Get the fill value for floating-point type */ -#define H5Z_scaleoffset_get_filval_2(type, filval_buf, filval) \ +#define H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ { \ if(sizeof(type) <= sizeof(long long)) \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -258,7 +350,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ i = 0; while(i < d_nelmts && HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) i++; \ if(i < d_nelmts) min = max = buf[i]; \ for(; i < d_nelmts; i++) { \ - if(HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) \ + if(HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) \ continue; /* ignore fill value */ \ if(buf[i] > max) max = buf[i]; \ if(buf[i] < min) min = buf[i]; \ @@ -321,13 +413,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Precompress for unsigned integer type */ -#define H5Z_scaleoffset_precompress_1(type, data, d_nelmts, filavail, filval_buf, minbits, minval)\ +#define H5Z_scaleoffset_precompress_1(type, data, d_nelmts, filavail, cd_values, minbits, minval)\ { \ type *buf = (type *)data, min = 0, max = 0, span, filval = 0; \ unsigned i; \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ if(*minbits == H5Z_SO_INT_MINBITS_DEFAULT) { /* minbits not set yet, calculate max, min, and minbits */ \ H5Z_scaleoffset_max_min_1(i, d_nelmts, buf, filval, max, min) \ H5Z_scaleoffset_check_1(type, max, min, minbits) \ @@ -354,13 +446,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Precompress for signed integer type */ -#define H5Z_scaleoffset_precompress_2(type, data, d_nelmts, filavail, filval_buf, minbits, minval)\ +#define H5Z_scaleoffset_precompress_2(type, data, d_nelmts, filavail, cd_values, minbits, minval)\ { \ type *buf = (type *)data, min = 0, max = 0, filval = 0; \ unsigned type span; unsigned i; \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ if(*minbits == H5Z_SO_INT_MINBITS_DEFAULT) { /* minbits not set yet, calculate max, min, and minbits */ \ H5Z_scaleoffset_max_min_1(i, d_nelmts, buf, filval, max, min) \ H5Z_scaleoffset_check_2(type, max, min, minbits) \ @@ -423,15 +515,15 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ if(sizeof(type)==sizeof(int)) \ for(i = 0; i < d_nelmts; i++) \ *(int *)&buf[i] = H5Z_scaleoffset_rnd( \ - buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ + buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ else if(sizeof(type)==sizeof(long)) \ for(i = 0; i < d_nelmts; i++) \ *(long *)&buf[i] = H5Z_scaleoffset_rnd( \ - buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ + buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ else if(sizeof(type)==sizeof(long long)) \ for(i = 0; i < d_nelmts; i++) \ *(long long *)&buf[i] = H5Z_scaleoffset_rnd( \ - buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ + buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype")\ } @@ -439,38 +531,33 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ /* Save the minimum value for floating-point type */ #define H5Z_scaleoffset_save_min(i, type, minval, min) \ { \ - if(sizeof(type) <= sizeof(long long)) { \ - unsigned char *min_parm; /* Pointer to min value parameter */ \ - \ - min_parm = (unsigned char *)minval; \ + if(sizeof(type) <= sizeof(long long)) \ + /* Save min value to corresponding position \ + * byte-order will be swapped as appropriate, but be sure to \ + * account for offset in BE if sizes differ \ + */ \ if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(min_parm, &min, sizeof(type)); \ + HDmemcpy(minval, &min, sizeof(type)); \ else { \ - unsigned char *min_buf; /* Pointer to min value in memory */ \ - unsigned u; /* index */ \ - \ HDassert(H5T_native_order_g == H5T_ORDER_BE); \ - \ - min_buf = (unsigned char *)&min; \ - for(u = 0; u < sizeof(type); u++) \ - min_parm[u] = min_buf[sizeof(type) - (u + 1)]; \ + HDmemcpy(((char *)minval) + (sizeof(long long) - sizeof(type)), \ + &min, sizeof(type)); \ } /* end else */ \ - } /* end if */ \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } /* Precompress for floating-point type using variable-minimum-bits method */ -#define H5Z_scaleoffset_precompress_3(type, data, d_nelmts, filavail, filval_buf, \ +#define H5Z_scaleoffset_precompress_3(type, data, d_nelmts, filavail, cd_values, \ minbits, minval, D_val) \ { \ - type *buf = (type *)data, min = 0, max = 0, filval = 0; \ + type *buf = (type *)data, min = 0, max = 0, filval = 0; \ unsigned long long span; \ unsigned i; \ \ *minval = 0; \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_2(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ H5Z_scaleoffset_max_min_3(i, d_nelmts, buf, filval, max, min, D_val) \ H5Z_scaleoffset_check_3(i, type, max, min, minbits, D_val) \ span = H5Z_scaleoffset_rnd(max * HDpow(10.0, D_val) - min * HDpow(10.0, D_val)) + 1; \ @@ -489,12 +576,12 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Postdecompress for unsigned integer type */ -#define H5Z_scaleoffset_postdecompress_1(type, data, d_nelmts, filavail, filval_buf, minbits, minval)\ +#define H5Z_scaleoffset_postdecompress_1(type, data, d_nelmts, filavail, cd_values, minbits, minval)\ { \ type *buf = (type *)data, filval = 0; unsigned i; \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ for(i = 0; i < d_nelmts; i++) \ buf[i] = (type)((buf[i] == (((type)1 << minbits) - 1)) ? filval : (buf[i] + minval)); \ } else /* fill value undefined */ \ @@ -502,13 +589,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Postdecompress for signed integer type */ -#define H5Z_scaleoffset_postdecompress_2(type, data, d_nelmts, filavail, filval_buf, minbits, minval)\ +#define H5Z_scaleoffset_postdecompress_2(type, data, d_nelmts, filavail, cd_values, minbits, minval)\ { \ type *buf = (type *)data, filval = 0; \ unsigned i; \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ for(i = 0; i < d_nelmts; i++) \ buf[i] = (type)(((unsigned type)buf[i] == (((unsigned type)1 << minbits) - 1)) ? filval : (buf[i] + minval));\ } else /* fill value undefined */ \ @@ -519,26 +606,18 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ /* Retrive minimum value of floating-point type */ #define H5Z_scaleoffset_get_min(type, minval, min) \ { \ - if(sizeof(type) <= sizeof(long long)) { \ - const unsigned char *min_parm; /* Pointer to min value parameter */ \ - \ - /* retrieve min value from corresponding positions \ - * retrieve them corresponding to how they are stored \ + if(sizeof(type) <= sizeof(long long)) \ + /* retrieve min value from corresponding position \ + * byte-order has already been swapped as appropriate, but be sure to \ + * account for offset in BE if sizes differ \ */ \ - min_parm = (const unsigned char *)&minval; \ if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(&min, min_parm, sizeof(type)); \ + HDmemcpy(&min, &minval, sizeof(type)); \ else { \ - unsigned char *min_buf; /* Pointer to min value in memory */ \ - unsigned u; /* index */ \ - \ HDassert(H5T_native_order_g == H5T_ORDER_BE); \ - \ - min_buf = (unsigned char *)&min; \ - for(u = 0; u < sizeof(type); u++) \ - min_buf[u] = min_parm[sizeof(type) - (u + 1)]; \ + HDmemcpy(&min, ((char *)&minval) + (sizeof(long long) \ + - sizeof(type)), sizeof(type)); \ } /* end else */ \ - } /* end if */ \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -579,7 +658,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Postdecompress for floating-point type using variable-minimum-bits method */ -#define H5Z_scaleoffset_postdecompress_3(type, data, d_nelmts, filavail, filval_buf, \ +#define H5Z_scaleoffset_postdecompress_3(type, data, d_nelmts, filavail, cd_values, \ minbits, minval, D_val) \ { \ type *buf = (type *)data, filval = 0, min = 0; \ @@ -588,7 +667,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ H5Z_scaleoffset_get_min(type, minval, min) \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_2(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ H5Z_scaleoffset_modify_3(i, type, buf, d_nelmts, filval, minbits, min, D_val) \ } else /* fill value undefined */ \ H5Z_scaleoffset_modify_4(i, type, buf, d_nelmts, min, D_val) \ @@ -1125,12 +1204,12 @@ H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_value /* postprocess after decompression */ if(dtype_class==H5Z_SCALEOFFSET_CLS_INTEGER) H5Z_scaleoffset_postdecompress_i(outbuf, d_nelmts, type, filavail, - &cd_values[H5Z_SCALEOFFSET_PARM_FILVAL], minbits, minval); + cd_values, minbits, minval); if(dtype_class==H5Z_SCALEOFFSET_CLS_FLOAT) if(scale_type==0) { /* variable-minimum-bits method */ if(H5Z_scaleoffset_postdecompress_fd(outbuf, d_nelmts, type, filavail, - &cd_values[H5Z_SCALEOFFSET_PARM_FILVAL], minbits, minval, D_val)==FAIL) + cd_values, minbits, minval, D_val)==FAIL) HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, 0, "post-decompression failed") } @@ -1153,12 +1232,12 @@ H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_value /* preprocess before compression */ if(dtype_class==H5Z_SCALEOFFSET_CLS_INTEGER) H5Z_scaleoffset_precompress_i(*buf, d_nelmts, type, filavail, - &cd_values[H5Z_SCALEOFFSET_PARM_FILVAL], &minbits, &minval); + cd_values, &minbits, &minval); if(dtype_class==H5Z_SCALEOFFSET_CLS_FLOAT) if(scale_type==0) { /* variable-minimum-bits method */ if(H5Z_scaleoffset_precompress_fd(*buf, d_nelmts, type, filavail, - &cd_values[H5Z_SCALEOFFSET_PARM_FILVAL], &minbits, &minval, D_val)==FAIL) + cd_values, &minbits, &minval, D_val)==FAIL) HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, 0, "pre-compression failed") } @@ -1308,30 +1387,30 @@ H5Z_scaleoffset_log2(unsigned long long num) /* precompress for integer type */ static void H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type, - unsigned filavail, const void *filval_buf, uint32_t *minbits, unsigned long long *minval) + unsigned filavail, const unsigned cd_values[], uint32_t *minbits, unsigned long long *minval) { if(type == t_uchar) H5Z_scaleoffset_precompress_1(unsigned char, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_ushort) H5Z_scaleoffset_precompress_1(unsigned short, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_uint) H5Z_scaleoffset_precompress_1(unsigned int, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_ulong) H5Z_scaleoffset_precompress_1(unsigned long, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_ulong_long) H5Z_scaleoffset_precompress_1(unsigned long long, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_schar) { signed char *buf = (signed char *)data, min = 0, max = 0, filval = 0; unsigned char span; unsigned i; if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ - H5Z_scaleoffset_get_filval_1(signed char, filval_buf, filval); + H5Z_scaleoffset_get_filval_1(signed char, cd_values, filval); if(*minbits == H5Z_SO_INT_MINBITS_DEFAULT) { /* minbits not set yet, calculate max, min, and minbits */ H5Z_scaleoffset_max_min_1(i, d_nelmts, buf, filval, max, min) if((unsigned char)(max - min) > (unsigned char)(~(unsigned char)0 - 2)) { @@ -1365,46 +1444,46 @@ H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffse } else if(type == t_short) H5Z_scaleoffset_precompress_2(short, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_int) H5Z_scaleoffset_precompress_2(int, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_long) H5Z_scaleoffset_precompress_2(long, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_long_long) H5Z_scaleoffset_precompress_2(long long, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) } /* postdecompress for integer type */ static void H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type, - unsigned filavail, const void *filval_buf, uint32_t minbits, unsigned long long minval) + unsigned filavail, const unsigned cd_values[], uint32_t minbits, unsigned long long minval) { long long sminval = *(long long*)&minval; /* for signed integer types */ if(type == t_uchar) H5Z_scaleoffset_postdecompress_1(unsigned char, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_ushort) H5Z_scaleoffset_postdecompress_1(unsigned short, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_uint) H5Z_scaleoffset_postdecompress_1(unsigned int, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_ulong) H5Z_scaleoffset_postdecompress_1(unsigned long, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_ulong_long) H5Z_scaleoffset_postdecompress_1(unsigned long long, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_schar) { signed char *buf = (signed char *)data, filval = 0; unsigned i; if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ - H5Z_scaleoffset_get_filval_1(signed char, filval_buf, filval) + H5Z_scaleoffset_get_filval_1(signed char, cd_values, filval) for(i = 0; i < d_nelmts; i++) buf[i] = (signed char)((buf[i] == (((unsigned char)1 << minbits) - 1)) ? filval : (buf[i] + sminval)); } else /* fill value undefined */ @@ -1413,23 +1492,23 @@ H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleof } else if(type == t_short) H5Z_scaleoffset_postdecompress_2(short, data, d_nelmts, filavail, - filval_buf, minbits, sminval) + cd_values, minbits, sminval) else if(type == t_int) H5Z_scaleoffset_postdecompress_2(int, data, d_nelmts, filavail, - filval_buf, minbits, sminval) + cd_values, minbits, sminval) else if(type == t_long) H5Z_scaleoffset_postdecompress_2(long, data, d_nelmts, filavail, - filval_buf, minbits, sminval) + cd_values, minbits, sminval) else if(type == t_long_long) H5Z_scaleoffset_postdecompress_2(long long, data, d_nelmts, filavail, - filval_buf, minbits, sminval) + cd_values, minbits, sminval) } /* precompress for floating-point type, variable-minimum-bits method success: non-negative, failure: negative 4/15/05 */ static herr_t H5Z_scaleoffset_precompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type, - unsigned filavail, const void *filval_buf, uint32_t *minbits, + unsigned filavail, const unsigned cd_values[], uint32_t *minbits, unsigned long long *minval, double D_val) { herr_t ret_value=SUCCEED; /* Return value */ @@ -1438,10 +1517,10 @@ H5Z_scaleoffset_precompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffs if(type == t_float) H5Z_scaleoffset_precompress_3(float, data, d_nelmts, - filavail, filval_buf, minbits, minval, D_val) + filavail, cd_values, minbits, minval, D_val) else if(type == t_double) H5Z_scaleoffset_precompress_3(double, data, d_nelmts, - filavail, filval_buf, minbits, minval, D_val) + filavail, cd_values, minbits, minval, D_val) done: FUNC_LEAVE_NOAPI(ret_value) @@ -1451,7 +1530,7 @@ done: success: non-negative, failure: negative 4/15/05 */ static herr_t H5Z_scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type, - unsigned filavail, const void *filval_buf, uint32_t minbits, + unsigned filavail, const unsigned cd_values[], uint32_t minbits, unsigned long long minval, double D_val) { long long sminval = (long long)minval; /* for signed integer types */ @@ -1461,10 +1540,10 @@ H5Z_scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleo if(type == t_float) H5Z_scaleoffset_postdecompress_3(float, data, d_nelmts, filavail, - filval_buf, minbits, sminval, D_val) + cd_values, minbits, sminval, D_val) else if(type == t_double) H5Z_scaleoffset_postdecompress_3(double, data, d_nelmts, filavail, - filval_buf, minbits, sminval, D_val) + cd_values, minbits, sminval, D_val) done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5api_adpt.h b/src/H5api_adpt.h index dbd8d94..fc0b467 100644 --- a/src/H5api_adpt.h +++ b/src/H5api_adpt.h @@ -235,7 +235,7 @@ #define H5_FCDLLVAR extern #endif /* H5_FCDLL */ -#if defined(hdf5_f90Ctest_EXPORTS) +#if defined(hdf5_test_f90cstub_EXPORTS) #if defined (_MSC_VER) /* MSVC Compiler Case */ #define H5_FCTESTDLL __declspec(dllexport) #define H5_FCTESTDLLVAR extern __declspec(dllexport) @@ -281,10 +281,26 @@ #define HDF5_HL_F90CSTUBDLLVAR extern #endif /* HDF5_HL_F90CSTUBDLL */ +#elif defined(H5_BUILT_AS_STATIC_LIB) + #define H5_DLL + #define H5_HLDLL + #define H5_HLCPPDLL + #define HDF5_HL_F90CSTUBDLL + #define H5_DLLVAR extern + #define H5_DLLCPP + #define H5TEST_DLL + #define H5TEST_DLLVAR extern + #define H5TOOLS_DLL + #define H5TOOLS_DLLVAR extern + #define H5_FCDLL + #define H5_FCDLLVAR extern + #define H5_FCTESTDLL + #define H5_FCTESTDLLVAR extern + #else /* This is the original HDFGroup defined preprocessor code which should still work * with the VS projects that are maintained by "The HDF Group" - * This will be removed after the next release. + * The Visual Studio project files will not be supported in the next major release of 1.10. */ #if defined(_WIN32) diff --git a/src/H5config.h.in b/src/H5config.h.in index 3283893..c53ccca 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -435,6 +435,10 @@ values correctly. */ #undef LDOUBLE_TO_LLONG_ACCURATE +/* Define if your system converts long double to (unsigned) long values with + special algorithm. */ +#undef LDOUBLE_TO_LONG_SPECIAL + /* Define if your system can convert long double to unsigned int values correctly. */ #undef LDOUBLE_TO_UINT_ACCURATE @@ -446,6 +450,10 @@ values correctly. */ #undef LLONG_TO_LDOUBLE_CORRECT +/* Define if your system can convert (unsigned) long to long double values + with special algorithm. */ +#undef LONG_TO_LDOUBLE_SPECIAL + /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR diff --git a/src/H5private.h b/src/H5private.h index f13ad84..9cebdaa 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -403,11 +403,6 @@ # error "nothing appropriate for int32_t" #endif -/* Definition of uint32_t was moved to H5public.h */ - -/* Definition of int64_t was moved to H5public.h */ -/* Definition of uint64_t was moved to H5public.h */ - /* * Maximum and minimum values. These should be defined in <limits.h> for the * most part. diff --git a/src/H5public.h b/src/H5public.h index 19791b3..1f835f7 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -75,10 +75,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 76 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 80 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.76" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.80" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/H5win32defs.h b/src/H5win32defs.h index d478e4c..fb37059 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -56,12 +56,7 @@ typedef __int64 h5_stat_size_t; #endif /* H5_HAVE_GETTIMEOFDAY */ #define HDgetdrive() _getdrive() #define HDlseek(F,O,W) _lseeki64(F,O,W) -#if !defined(__MWERKS__) -# /*MSVC*/ -# define HDoff_t __int64 -#else -# define HDoff_t off_t -#endif +#define HDoff_t __int64 #define HDmemset(X,C,Z) memset((void*)(X),C,Z) #define HDmkdir(S,M) _mkdir(S) #define HDopen(S,F,M) _open(S,F|_O_BINARY,M) diff --git a/src/Makefile.in b/src/Makefile.in index f6a3a31..55e52ae 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -228,6 +228,7 @@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DEPRECATED_SYMBOLS = @DEPRECATED_SYMBOLS@ DIRECT_VFD = @DIRECT_VFD@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_DIRS = @DYNAMIC_DIRS@ @@ -289,6 +290,7 @@ LTLIBOBJS = @LTLIBOBJS@ LT_STATIC_EXEC = @LT_STATIC_EXEC@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MPE = @MPE@ MPI_GET_SIZE = @MPI_GET_SIZE@ @@ -345,6 +347,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ @@ -455,7 +458,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 66 +LT_VERS_REVISION = 70 LT_VERS_AGE = 0 H5detect_CFLAGS = -g $(AM_CFLAGS) |