From 495b8de00214c9f99d6f10fd91de0feef55cefa8 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 13 Sep 2012 14:18:45 -0500 Subject: [svn-r22761] Purpose: Fix testswmr failures Description: Patched H5B2 shadowed list implementation to remove nodes from the shadowed list when they are evicted, and added some missing initializations. Also removed inadvertent temporary changes to the tests that disabled srandom, added assertions and fixed formatting. Tested: ummon --- src/H5B2cache.c | 76 ++++++++++++++++++++++++++++++++++++++++------- src/H5B2hdr.c | 4 +++ src/H5B2int.c | 10 +++++-- src/H5B2pkg.h | 2 ++ test/swmr_addrem_writer.c | 2 +- test/swmr_writer.c | 2 +- 6 files changed, 82 insertions(+), 14 deletions(-) diff --git a/src/H5B2cache.c b/src/H5B2cache.c index 96faa13..31277a7 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -345,34 +345,38 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, /* Metadata checksum */ UINT32ENCODE(p, metadata_chksum); - /* Write the B-tree header. */ + /* Write the B-tree header. */ HDassert((size_t)(p - buf) == hdr->hdr_size); - if(H5F_block_write(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk") + if(H5F_block_write(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk") - hdr->cache_info.is_dirty = FALSE; + hdr->cache_info.is_dirty = FALSE; - /* Clear shadowed node lists, as the header has been flushed and all - * nodes must be shadowed again (if doing SWMR writes). Note that this - * algorithm does one extra iteration at the end, as the last node's - * shadowed_next pointer points to itself. */ - while(hdr->shadowed_internal) { + /* Clear shadowed node lists, as the header has been flushed and all + * nodes must be shadowed again (if doing SWMR writes). Note that this + * algorithm does one extra iteration at the end, as the last node's + * shadowed_next pointer points to itself. */ + while(hdr->shadowed_internal) { H5B2_internal_t *next = hdr->shadowed_internal->shadowed_next; + HDassert(!hdr->shadowed_internal->cache_info.is_dirty); hdr->shadowed_internal->shadowed_next = NULL; + hdr->shadowed_internal->shadowed_prev = NULL; hdr->shadowed_internal = next; } /* end while */ while(hdr->shadowed_leaf) { H5B2_leaf_t *next = hdr->shadowed_leaf->shadowed_next; + HDassert(!hdr->shadowed_leaf->cache_info.is_dirty); hdr->shadowed_leaf->shadowed_next = NULL; + hdr->shadowed_leaf->shadowed_prev = NULL; hdr->shadowed_leaf = next; } /* end while */ } /* end if */ if(destroy) if(H5B2_cache_hdr_dest(f, hdr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header") + HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header") done: /* Release resources */ @@ -599,6 +603,8 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata) /* Share B-tree information */ internal->hdr = udata->hdr; internal->parent = udata->parent; + internal->shadowed_next = NULL; + internal->shadowed_prev = NULL; /* Read header from disk */ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0) @@ -808,6 +814,30 @@ H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal) /* If we're going to free the space on disk, the address must be valid */ HDassert(!internal->cache_info.free_file_space_on_destroy || H5F_addr_defined(internal->cache_info.addr)); + /* Unlink from shadowed list */ + if(internal->shadowed_next) { + if(internal->shadowed_next != internal) { + internal->shadowed_next->shadowed_prev = internal->shadowed_prev; + + if(internal->shadowed_prev) + internal->shadowed_prev->shadowed_next = internal->shadowed_next; + else { + HDassert(internal->hdr->shadowed_internal = internal); + + internal->hdr->shadowed_internal = internal->shadowed_next; + } /* end else */ + } /* end if */ + else { + if(internal->shadowed_prev) + internal->shadowed_prev->shadowed_next = internal->shadowed_prev; + else { + HDassert(internal->hdr->shadowed_internal = internal); + + internal->hdr->shadowed_internal = NULL; + } /* end else */ + } /* end else */ + } /* end if */ + /* Check for freeing file space for B-tree internal node */ if(internal->cache_info.free_file_space_on_destroy) { /* Release the space on disk */ @@ -997,6 +1027,8 @@ H5B2_cache_leaf_load(H5F_t UNUSED *f, hid_t dxpl_id, haddr_t addr, void *_udata) /* Share B-tree header information */ leaf->hdr = udata->hdr; leaf->parent = udata->parent; + leaf->shadowed_next = NULL; + leaf->shadowed_prev = NULL; /* Read header from disk */ if(H5F_block_read(udata->f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0) @@ -1172,6 +1204,30 @@ H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf) /* If we're going to free the space on disk, the address must be valid */ HDassert(!leaf->cache_info.free_file_space_on_destroy || H5F_addr_defined(leaf->cache_info.addr)); + /* Unlink from shadowed list */ + if(leaf->shadowed_next) { + if(leaf->shadowed_next != leaf) { + leaf->shadowed_next->shadowed_prev = leaf->shadowed_prev; + + if(leaf->shadowed_prev) + leaf->shadowed_prev->shadowed_next = leaf->shadowed_next; + else { + HDassert(leaf->hdr->shadowed_leaf = leaf); + + leaf->hdr->shadowed_leaf = leaf->shadowed_next; + } /* end else */ + } /* end if */ + else { + if(leaf->shadowed_prev) + leaf->shadowed_prev->shadowed_next = leaf->shadowed_prev; + else { + HDassert(leaf->hdr->shadowed_leaf = leaf); + + leaf->hdr->shadowed_leaf = NULL; + } /* end else */ + } /* end else */ + } /* end if */ + /* Check for freeing file space for B-tree leaf node */ if(leaf->cache_info.free_file_space_on_destroy) { /* Release the space on disk */ diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c index 54842ff..d0ea61b 100644 --- a/src/H5B2hdr.c +++ b/src/H5B2hdr.c @@ -214,6 +214,10 @@ HDmemset(hdr->page, 0, hdr->node_size); && (hdr->cls->id == H5B2_CDSET_ID || hdr->cls->id == H5B2_CDSET_FILT_ID); + /* Clear the shadowed list pointers */ + hdr->shadowed_leaf = NULL; + hdr->shadowed_internal = NULL; + /* Create the callback context, if the callback exists */ if(hdr->cls->crt_context) { if(NULL == (hdr->cb_ctx = (*hdr->cls->crt_context)(ctx_udata))) diff --git a/src/H5B2int.c b/src/H5B2int.c index 29d12e8..3d6ac14 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -4214,6 +4214,7 @@ H5B2_shadow_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, HDassert(internal); HDassert(*internal); HDassert(hdr->swmr_write); + HDassert((*internal)->hdr == hdr); /* We only need to shadow the node if it has not been shadowed since the * last time the header was flushed, as otherwise it will be unreachable by @@ -4254,8 +4255,10 @@ H5B2_shadow_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, node_protected = TRUE; /* Add node to shadowed node list */ - if(hdr->shadowed_internal) + if(hdr->shadowed_internal) { (*internal)->shadowed_next = hdr->shadowed_internal; + hdr->shadowed_internal->shadowed_prev = *internal; + } /* end if */ else (*internal)->shadowed_next = *internal; hdr->shadowed_internal = *internal; @@ -4307,6 +4310,7 @@ H5B2_shadow_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, HDassert(leaf); HDassert(*leaf); HDassert(hdr->swmr_write); + HDassert((*leaf)->hdr == hdr); /* We only need to shadow the node if it has not been shadowed since the * last time the header was flushed, as otherwise it will be unreachable by @@ -4347,8 +4351,10 @@ H5B2_shadow_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, node_protected = TRUE; /* Add node to shadowed node list */ - if(hdr->shadowed_leaf) + if(hdr->shadowed_leaf) { (*leaf)->shadowed_next = hdr->shadowed_leaf; + hdr->shadowed_leaf->shadowed_prev = *leaf; + } /* end if */ else (*leaf)->shadowed_next = *leaf; hdr->shadowed_leaf = *leaf; diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index 96ef54f..eb7d833 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -193,6 +193,7 @@ typedef struct H5B2_leaf_t { uint8_t *leaf_native; /* Pointer to native records */ uint16_t nrec; /* Number of records in node */ struct H5B2_leaf_t *shadowed_next; /* Next node in shadowed list */ + struct H5B2_leaf_t *shadowed_prev; /* Previous node in shadowed list */ } H5B2_leaf_t; /* B-tree internal node information */ @@ -208,6 +209,7 @@ typedef struct H5B2_internal_t { uint16_t nrec; /* Number of records in node */ uint16_t depth; /* Depth of this node in the B-tree */ struct H5B2_internal_t *shadowed_next; /* Next node in shadowed list */ + struct H5B2_internal_t *shadowed_prev; /* Previous node in shadowed list */ } H5B2_internal_t; /* v2 B-tree */ diff --git a/test/swmr_addrem_writer.c b/test/swmr_addrem_writer.c index 24c485f..b175a14 100644 --- a/test/swmr_addrem_writer.c +++ b/test/swmr_addrem_writer.c @@ -269,7 +269,7 @@ int main(int argc, const char *argv[]) /* Create randomized set of numbers */ curr_time = time(NULL); - //srandom((unsigned)curr_time); + srandom((unsigned)curr_time); /* Emit informational message */ if(verbose) diff --git a/test/swmr_writer.c b/test/swmr_writer.c index d465d70..4957b00 100644 --- a/test/swmr_writer.c +++ b/test/swmr_writer.c @@ -244,7 +244,7 @@ int main(int argc, const char *argv[]) /* Create randomized set of numbers */ curr_time = time(NULL); - srandom(15);//srandom((unsigned)curr_time); + srandom((unsigned)curr_time); /* Emit informational message */ if(verbose) -- cgit v0.12