From 0d1d64ad87c42dd3c283c0598295260826e3d819 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 31 Mar 2009 11:46:04 -0500 Subject: [svn-r16633] Description: Use metadata cache flush dependencies (and 'notify' callback) to give extensible arrays SWMR (single-writer/multiple-reader) access capability. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.6 (amazon) in debug mode Mac OS X/32 10.5.6 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode --- src/H5EA.c | 24 +++--- src/H5EAcache.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++---- src/H5EAdbg.c | 6 +- src/H5EAdblkpage.c | 19 +++-- src/H5EAdblock.c | 28 ++++--- src/H5EAiblock.c | 4 +- src/H5EAint.c | 63 +++++++++++++++ src/H5EApkg.h | 52 ++++++++++--- src/H5EAsblock.c | 29 ++++--- 9 files changed, 379 insertions(+), 71 deletions(-) diff --git a/src/H5EA.c b/src/H5EA.c index 568b301..85ae821 100644 --- a/src/H5EA.c +++ b/src/H5EA.c @@ -411,7 +411,7 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i /* Create data block */ dblk_off = hdr->sblk_info[sblk_idx].start_idx + (dblk_idx * hdr->sblk_info[sblk_idx].dblk_nelmts); - dblk_addr = H5EA__dblock_create(hdr, dxpl_id, &stats_changed, dblk_off, hdr->sblk_info[sblk_idx].dblk_nelmts); + dblk_addr = H5EA__dblock_create(hdr, dxpl_id, iblock, &stats_changed, dblk_off, hdr->sblk_info[sblk_idx].dblk_nelmts); if(!H5F_addr_defined(dblk_addr)) H5E_THROW(H5E_CANTCREATE, "unable to create extensible array data block") @@ -421,7 +421,7 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i } /* end if */ /* Protect data block */ - if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, iblock->dblk_addrs[dblk_idx], hdr->sblk_info[sblk_idx].dblk_nelmts, H5AC_WRITE))) + if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, iblock, iblock->dblk_addrs[dblk_idx], hdr->sblk_info[sblk_idx].dblk_nelmts, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)iblock->dblk_addrs[dblk_idx]) /* Adjust index to offset in data block */ @@ -443,7 +443,7 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i haddr_t sblk_addr; /* Address of data block created */ /* Create super block */ - sblk_addr = H5EA__sblock_create(hdr, dxpl_id, &stats_changed, sblk_idx); + sblk_addr = H5EA__sblock_create(hdr, dxpl_id, iblock, &stats_changed, sblk_idx); #ifdef QAK HDfprintf(stderr, "%s: New super block address is: %a\n", FUNC, sblk_addr); #endif /* QAK */ @@ -456,7 +456,7 @@ HDfprintf(stderr, "%s: New super block address is: %a\n", FUNC, sblk_addr); } /* end if */ /* Protect super block */ - if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, iblock->sblk_addrs[sblk_off], sblk_idx, H5AC_WRITE))) + if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, iblock, iblock->sblk_addrs[sblk_off], sblk_idx, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)iblock->sblk_addrs[sblk_off]) /* Compute the data block index in super block */ @@ -473,7 +473,7 @@ HDfprintf(stderr, "%s: dblk_idx = %u, sblock->ndblks = %Zu\n", FUNC, dblk_idx, s /* Create data block */ dblk_off = hdr->sblk_info[sblk_idx].start_idx + (dblk_idx * hdr->sblk_info[sblk_idx].dblk_nelmts); - dblk_addr = H5EA__dblock_create(hdr, dxpl_id, &stats_changed, dblk_off, sblock->dblk_nelmts); + dblk_addr = H5EA__dblock_create(hdr, dxpl_id, sblock, &stats_changed, dblk_off, sblock->dblk_nelmts); if(!H5F_addr_defined(dblk_addr)) H5E_THROW(H5E_CANTCREATE, "unable to create extensible array data block") @@ -524,7 +524,7 @@ HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_ /* Check if page has been initialized yet */ if(!H5V_bit_get(sblock->page_init, page_init_idx)) { /* Create the data block page */ - if(H5EA__dblk_page_create(hdr, dxpl_id, dblk_page_addr) < 0) + if(H5EA__dblk_page_create(hdr, dxpl_id, sblock, dblk_page_addr) < 0) H5E_THROW(H5E_CANTCREATE, "unable to create data block page") /* Mark data block page as initialized in super block */ @@ -533,7 +533,7 @@ HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_ } /* end if */ /* Protect data block page */ - if(NULL == (dblk_page = H5EA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, H5AC_WRITE))) + if(NULL == (dblk_page = H5EA__dblk_page_protect(hdr, dxpl_id, sblock, dblk_page_addr, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block page, address = %llu", (unsigned long long)dblk_page_addr) /* Set pointer to elements */ @@ -541,7 +541,7 @@ HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_ } /* end if */ else { /* Protect data block */ - if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, H5AC_WRITE))) + if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)sblock->dblk_addrs[dblk_idx]) /* Set pointer to elements */ @@ -687,7 +687,7 @@ HDfprintf(stderr, "%s: dblk_idx = %u\n", FUNC, dblk_idx); } /* end if */ else { /* Protect data block */ - if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, iblock->dblk_addrs[dblk_idx], hdr->sblk_info[sblk_idx].dblk_nelmts, H5AC_READ))) + if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, iblock, iblock->dblk_addrs[dblk_idx], hdr->sblk_info[sblk_idx].dblk_nelmts, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)iblock->dblk_addrs[dblk_idx]) /* Adjust index to offset in data block */ @@ -711,7 +711,7 @@ HDfprintf(stderr, "%s: dblk_idx = %u\n", FUNC, dblk_idx); } /* end if */ else { /* Protect super block */ - if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, iblock->sblk_addrs[sblk_off], sblk_idx, H5AC_READ))) + if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, iblock, iblock->sblk_addrs[sblk_off], sblk_idx, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)iblock->sblk_addrs[sblk_off]) /* Compute the data block index in super block */ @@ -785,7 +785,7 @@ HDfprintf(stderr, "%s: elmt_idx = %Hu, dblk_page_addr = %a\n", FUNC, elmt_idx, d #endif /* QAK */ /* Protect data block page */ - if(NULL == (dblk_page = H5EA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, H5AC_READ))) + if(NULL == (dblk_page = H5EA__dblk_page_protect(hdr, dxpl_id, sblock, dblk_page_addr, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block page, address = %llu", (unsigned long long)dblk_page_addr) /* Set pointer to elements */ @@ -794,7 +794,7 @@ HDfprintf(stderr, "%s: elmt_idx = %Hu, dblk_page_addr = %a\n", FUNC, elmt_idx, d } /* end if */ else { /* Protect data block */ - if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, H5AC_READ))) + if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)sblock->dblk_addrs[dblk_idx]) /* Set pointer to elements */ diff --git a/src/H5EAcache.c b/src/H5EAcache.c index 565127f..8947960 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -88,22 +88,26 @@ static herr_t H5EA__cache_hdr_dest(H5F_t *f, H5EA_hdr_t *hdr); static H5EA_iblock_t *H5EA__cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5EA__cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_iblock_t *iblock, unsigned * flags_ptr); static herr_t H5EA__cache_iblock_clear(H5F_t *f, H5EA_iblock_t *iblock, hbool_t destroy); +static herr_t H5EA__cache_iblock_notify(H5AC_notify_action_t action, H5EA_iblock_t *iblock); static herr_t H5EA__cache_iblock_size(const H5F_t *f, const H5EA_iblock_t *iblock, size_t *size_ptr); static herr_t H5EA__cache_iblock_dest(H5F_t *f, H5EA_iblock_t *iblock); static H5EA_sblock_t *H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5EA__cache_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_sblock_t *sblock, unsigned * flags_ptr); static herr_t H5EA__cache_sblock_clear(H5F_t *f, H5EA_sblock_t *sblock, hbool_t destroy); static herr_t H5EA__cache_sblock_size(const H5F_t *f, const H5EA_sblock_t *sblock, size_t *size_ptr); +static herr_t H5EA__cache_sblock_notify(H5AC_notify_action_t action, H5EA_sblock_t *sblock); static herr_t H5EA__cache_sblock_dest(H5F_t *f, H5EA_sblock_t *sblock); static H5EA_dblock_t *H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5EA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_dblock_t *dblock, unsigned * flags_ptr); static herr_t H5EA__cache_dblock_clear(H5F_t *f, H5EA_dblock_t *dblock, hbool_t destroy); static herr_t H5EA__cache_dblock_size(const H5F_t *f, const H5EA_dblock_t *dblock, size_t *size_ptr); +static herr_t H5EA__cache_dblock_notify(H5AC_notify_action_t action, H5EA_dblock_t *dblock); static herr_t H5EA__cache_dblock_dest(H5F_t *f, H5EA_dblock_t *dblock); static H5EA_dblk_page_t *H5EA__cache_dblk_page_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5EA__cache_dblk_page_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_dblk_page_t *dblk_page, unsigned * flags_ptr); static herr_t H5EA__cache_dblk_page_clear(H5F_t *f, H5EA_dblk_page_t *dblk_page, hbool_t destroy); static herr_t H5EA__cache_dblk_page_size(const H5F_t *f, const H5EA_dblk_page_t *dblk_page, size_t *size_ptr); +static herr_t H5EA__cache_dblk_page_notify(H5AC_notify_action_t action, H5EA_dblk_page_t *dblk_page); static herr_t H5EA__cache_dblk_page_dest(H5F_t *f, H5EA_dblk_page_t *dblk_page); @@ -129,7 +133,7 @@ const H5AC_class_t H5AC_EARRAY_IBLOCK[1] = {{ (H5AC_flush_func_t)H5EA__cache_iblock_flush, (H5AC_dest_func_t)H5EA__cache_iblock_dest, (H5AC_clear_func_t)H5EA__cache_iblock_clear, - (H5AC_notify_func_t)NULL, + (H5AC_notify_func_t)H5EA__cache_iblock_notify, (H5AC_size_func_t)H5EA__cache_iblock_size, }}; @@ -140,7 +144,7 @@ const H5AC_class_t H5AC_EARRAY_SBLOCK[1] = {{ (H5AC_flush_func_t)H5EA__cache_sblock_flush, (H5AC_dest_func_t)H5EA__cache_sblock_dest, (H5AC_clear_func_t)H5EA__cache_sblock_clear, - (H5AC_notify_func_t)NULL, + (H5AC_notify_func_t)H5EA__cache_sblock_notify, (H5AC_size_func_t)H5EA__cache_sblock_size, }}; @@ -151,7 +155,7 @@ const H5AC_class_t H5AC_EARRAY_DBLOCK[1] = {{ (H5AC_flush_func_t)H5EA__cache_dblock_flush, (H5AC_dest_func_t)H5EA__cache_dblock_dest, (H5AC_clear_func_t)H5EA__cache_dblock_clear, - (H5AC_notify_func_t)NULL, + (H5AC_notify_func_t)H5EA__cache_dblock_notify, (H5AC_size_func_t)H5EA__cache_dblock_size, }}; @@ -162,7 +166,7 @@ const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1] = {{ (H5AC_flush_func_t)H5EA__cache_dblk_page_flush, (H5AC_dest_func_t)H5EA__cache_dblk_page_dest, (H5AC_clear_func_t)H5EA__cache_dblk_page_clear, - (H5AC_notify_func_t)NULL, + (H5AC_notify_func_t)H5EA__cache_dblk_page_notify, (H5AC_size_func_t)H5EA__cache_dblk_page_size, }}; @@ -834,6 +838,53 @@ END_FUNC(STATIC) /* end H5EA__cache_iblock_clear() */ /*------------------------------------------------------------------------- + * Function: H5EA__cache_iblock_notify + * + * Purpose: Handle cache action notifications + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 31 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5EA__cache_iblock_notify(H5AC_notify_action_t action, H5EA_iblock_t *iblock)) + + /* Sanity check */ + HDassert(iblock); + + /* Determine which action to take */ + switch(action) { + case H5AC_NOTIFY_ACTION_AFTER_INSERT: + /* Create flush dependency on extensible array header */ + if(H5EA__create_flush_depend(iblock->hdr, (H5AC_info_t *)iblock->hdr, (H5AC_info_t *)iblock) < 0) + H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between index block and header, address = %llu", (unsigned long long)iblock->addr) + break; + + case H5AC_NOTIFY_ACTION_BEFORE_EVICT: + /* Destroy flush dependency on extensible array header */ + if(H5EA__destroy_flush_depend(iblock->hdr, (H5AC_info_t *)iblock->hdr, (H5AC_info_t *)iblock) < 0) + H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between index block and header, address = %llu", (unsigned long long)iblock->addr) + break; + + default: +#ifdef NDEBUG + H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache") +#else /* NDEBUG */ + HDassert(0 && "Unknown action?!?"); +#endif /* NDEBUG */ + } /* end switch */ + +CATCH + +END_FUNC(STATIC) /* end H5EA__cache_iblock_notify() */ + + +/*------------------------------------------------------------------------- * Function: H5EA__cache_iblock_size * * Purpose: Compute the size in bytes of a extensible array index block @@ -929,11 +980,11 @@ END_FUNC(STATIC) /* end H5EA__cache_iblock_dest() */ BEGIN_FUNC(STATIC, ERR, H5EA_sblock_t *, NULL, NULL, H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, - const void *_sblk_idx, void *_hdr)) + const void *_udata1, void *_hdr)) /* Local variables */ H5EA_hdr_t *hdr = (H5EA_hdr_t *)_hdr; /* Shared extensible array information */ - const unsigned *sblk_idx = (const unsigned *)_sblk_idx; /* Index of this super block */ + const H5EA_sblock_load_ud_t *ud_load = (const H5EA_sblock_load_ud_t *)_udata1; /* User data for loading super block */ H5EA_sblock_t *sblock = NULL; /* Super block info */ size_t size; /* Super block size */ H5WB_t *wb = NULL; /* Wrapped buffer for super block data */ @@ -948,11 +999,11 @@ H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, /* Sanity check */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(sblk_idx && *sblk_idx > 0); + HDassert(ud_load && ud_load->parent && ud_load->sblk_idx > 0); HDassert(hdr); /* Allocate the extensible array super block */ - if(NULL == (sblock = H5EA__sblock_alloc(hdr, *sblk_idx))) + if(NULL == (sblock = H5EA__sblock_alloc(hdr, ud_load->parent, ud_load->sblk_idx))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block") /* Set the extensible array super block's address */ @@ -1218,6 +1269,53 @@ END_FUNC(STATIC) /* end H5EA__cache_sblock_size() */ /*------------------------------------------------------------------------- + * Function: H5EA__cache_sblock_notify + * + * Purpose: Handle cache action notifications + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 31 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5EA__cache_sblock_notify(H5AC_notify_action_t action, H5EA_sblock_t *sblock)) + + /* Sanity check */ + HDassert(sblock); + + /* Determine which action to take */ + switch(action) { + case H5AC_NOTIFY_ACTION_AFTER_INSERT: + /* Create flush dependency on index block */ + if(H5EA__create_flush_depend(sblock->hdr, (H5AC_info_t *)sblock->parent, (H5AC_info_t *)sblock) < 0) + H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between super block and index block, address = %llu", (unsigned long long)sblock->addr) + break; + + case H5AC_NOTIFY_ACTION_BEFORE_EVICT: + /* Destroy flush dependency on index block */ + if(H5EA__destroy_flush_depend(sblock->hdr, (H5AC_info_t *)sblock->parent, (H5AC_info_t *)sblock) < 0) + H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between super block and index block, address = %llu", (unsigned long long)sblock->addr) + break; + + default: +#ifdef NDEBUG + H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache") +#else /* NDEBUG */ + HDassert(0 && "Unknown action?!?"); +#endif /* NDEBUG */ + } /* end switch */ + +CATCH + +END_FUNC(STATIC) /* end H5EA__cache_sblock_notify() */ + + +/*------------------------------------------------------------------------- * Function: H5EA__cache_sblock_dest * * Purpose: Destroys an extensible array super block in memory. @@ -1281,11 +1379,11 @@ END_FUNC(STATIC) /* end H5EA__cache_sblock_dest() */ BEGIN_FUNC(STATIC, ERR, H5EA_dblock_t *, NULL, NULL, H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, - const void *_nelmts, void *_hdr)) + const void *_udata1, void *_hdr)) /* Local variables */ H5EA_hdr_t *hdr = (H5EA_hdr_t *)_hdr; /* Shared extensible array information */ - const size_t *nelmts = (const size_t *)_nelmts; /* Number of elements in data block */ + const H5EA_dblock_load_ud_t *ud_load = (const H5EA_dblock_load_ud_t *)_udata1; /* User data for loading data block */ H5EA_dblock_t *dblock = NULL; /* Data block info */ size_t size; /* Data block size */ H5WB_t *wb = NULL; /* Wrapped buffer for data block data */ @@ -1299,11 +1397,11 @@ H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, /* Sanity check */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(nelmts && *nelmts > 0); + HDassert(ud_load && ud_load->parent && ud_load->nelmts > 0); HDassert(hdr); /* Allocate the extensible array data block */ - if(NULL == (dblock = H5EA__dblock_alloc(hdr, *nelmts))) + if(NULL == (dblock = H5EA__dblock_alloc(hdr, ud_load->parent, ud_load->nelmts))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block") /* Set the extensible array data block's information */ @@ -1357,9 +1455,9 @@ H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, if(!dblock->npages) { /* Decode elements in data block */ /* Convert from raw elements on disk into native elements in memory */ - if((hdr->cparam.cls->decode)(p, dblock->elmts, *nelmts, hdr->cb_ctx) < 0) + if((hdr->cparam.cls->decode)(p, dblock->elmts, ud_load->nelmts, hdr->cb_ctx) < 0) H5E_THROW(H5E_CANTDECODE, "can't decode extensible array data elements") - p += (*nelmts * hdr->cparam.raw_elmt_size); + p += (ud_load->nelmts * hdr->cparam.raw_elmt_size); } /* end if */ /* Sanity check */ @@ -1536,6 +1634,53 @@ END_FUNC(STATIC) /* end H5EA__cache_dblock_clear() */ /*------------------------------------------------------------------------- + * Function: H5EA__cache_dblock_notify + * + * Purpose: Handle cache action notifications + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 31 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5EA__cache_dblock_notify(H5AC_notify_action_t action, H5EA_dblock_t *dblock)) + + /* Sanity check */ + HDassert(dblock); + + /* Determine which action to take */ + switch(action) { + case H5AC_NOTIFY_ACTION_AFTER_INSERT: + /* Create flush dependency on parent */ + if(H5EA__create_flush_depend(dblock->hdr, (H5AC_info_t *)dblock->parent, (H5AC_info_t *)dblock) < 0) + H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block and parent, address = %llu", (unsigned long long)dblock->addr) + break; + + case H5AC_NOTIFY_ACTION_BEFORE_EVICT: + /* Destroy flush dependency on parent */ + if(H5EA__destroy_flush_depend(dblock->hdr, (H5AC_info_t *)dblock->parent, (H5AC_info_t *)dblock) < 0) + H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block and parent, address = %llu", (unsigned long long)dblock->addr) + break; + + default: +#ifdef NDEBUG + H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache") +#else /* NDEBUG */ + HDassert(0 && "Unknown action?!?"); +#endif /* NDEBUG */ + } /* end switch */ + +CATCH + +END_FUNC(STATIC) /* end H5EA__cache_dblock_notify() */ + + +/*------------------------------------------------------------------------- * Function: H5EA__cache_dblock_size * * Purpose: Compute the size in bytes of a extensible array data block @@ -1636,10 +1781,11 @@ END_FUNC(STATIC) /* end H5EA__cache_dblock_dest() */ BEGIN_FUNC(STATIC, ERR, H5EA_dblk_page_t *, NULL, NULL, H5EA__cache_dblk_page_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, - const void UNUSED *udata1, void *_hdr)) + const void *_ud_load, void *_hdr)) /* Local variables */ H5EA_hdr_t *hdr = (H5EA_hdr_t *)_hdr; /* Shared extensible array information */ + const H5EA_dblk_page_load_ud_t *ud_load = (const H5EA_dblk_page_load_ud_t *)_ud_load; /* User data for loading data block page */ H5EA_dblk_page_t *dblk_page = NULL; /* Data block page info */ size_t size; /* Data block page size */ H5WB_t *wb = NULL; /* Wrapped buffer for data block page data */ @@ -1658,7 +1804,7 @@ HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr); #endif /* QAK */ /* Allocate the extensible array data block page */ - if(NULL == (dblk_page = H5EA__dblk_page_alloc(hdr))) + if(NULL == (dblk_page = H5EA__dblk_page_alloc(hdr, ud_load->parent))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block page") /* Set the extensible array data block's information */ @@ -1842,6 +1988,53 @@ END_FUNC(STATIC) /* end H5EA__cache_dblk_page_clear() */ /*------------------------------------------------------------------------- + * Function: H5EA__cache_dblk_page_notify + * + * Purpose: Handle cache action notifications + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 31 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5EA__cache_dblk_page_notify(H5AC_notify_action_t action, H5EA_dblk_page_t *dblk_page)) + + /* Sanity check */ + HDassert(dblk_page); + + /* Determine which action to take */ + switch(action) { + case H5AC_NOTIFY_ACTION_AFTER_INSERT: + /* Create flush dependency on parent */ + if(H5EA__create_flush_depend(dblk_page->hdr, (H5AC_info_t *)dblk_page->parent, (H5AC_info_t *)dblk_page) < 0) + H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block page and parent, address = %llu", (unsigned long long)dblk_page->addr) + break; + + case H5AC_NOTIFY_ACTION_BEFORE_EVICT: + /* Destroy flush dependency on parent */ + if(H5EA__destroy_flush_depend(dblk_page->hdr, (H5AC_info_t *)dblk_page->parent, (H5AC_info_t *)dblk_page) < 0) + H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block page and parent, address = %llu", (unsigned long long)dblk_page->addr) + break; + + default: +#ifdef NDEBUG + H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache") +#else /* NDEBUG */ + HDassert(0 && "Unknown action?!?"); +#endif /* NDEBUG */ + } /* end switch */ + +CATCH + +END_FUNC(STATIC) /* end H5EA__cache_dblk_page_notify() */ + + +/*------------------------------------------------------------------------- * Function: H5EA__cache_dblk_page_size * * Purpose: Compute the size in bytes of a extensible array data block page diff --git a/src/H5EAdbg.c b/src/H5EAdbg.c index 0acef62..8e4c634 100644 --- a/src/H5EAdbg.c +++ b/src/H5EAdbg.c @@ -320,7 +320,8 @@ H5EA__sblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int inde H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header") /* Protect super block */ - if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, addr, sblk_idx, H5AC_READ))) + /* (Note: setting parent of super block to 'hdr' for this operation should be OK -QAK) */ + if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, hdr, addr, sblk_idx, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)addr) /* Print opening message */ @@ -404,7 +405,8 @@ H5EA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int inde H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header") /* Protect data block */ - if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, addr, dblk_nelmts, H5AC_READ))) + /* (Note: setting parent of data block to 'hdr' for this operation should be OK -QAK) */ + if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, hdr, addr, dblk_nelmts, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)addr) /* Print opening message */ diff --git a/src/H5EAdblkpage.c b/src/H5EAdblkpage.c index a8edae1..429e9f8 100644 --- a/src/H5EAdblkpage.c +++ b/src/H5EAdblkpage.c @@ -100,7 +100,7 @@ H5FL_DEFINE_STATIC(H5EA_dblk_page_t); */ BEGIN_FUNC(PKG, ERR, H5EA_dblk_page_t *, NULL, NULL, -H5EA__dblk_page_alloc(H5EA_hdr_t *hdr)) +H5EA__dblk_page_alloc(H5EA_hdr_t *hdr, H5EA_sblock_t *parent)) /* Local variables */ H5EA_dblk_page_t *dblk_page = NULL; /* Extensible array data block page */ @@ -118,7 +118,7 @@ H5EA__dblk_page_alloc(H5EA_hdr_t *hdr)) dblk_page->hdr = hdr; /* Set non-zero internal fields */ - /* */ + dblk_page->parent = parent; /* Allocate buffer for elements in data block page */ if(NULL == (dblk_page->elmts = H5EA__hdr_alloc_elmts(hdr, hdr->dblk_page_nelmts))) @@ -150,7 +150,8 @@ END_FUNC(PKG) /* end H5EA__dblk_page_alloc() */ */ BEGIN_FUNC(PKG, ERR, herr_t, SUCCEED, FAIL, -H5EA__dblk_page_create(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t addr)) +H5EA__dblk_page_create(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_sblock_t *parent, + haddr_t addr)) /* Local variables */ H5EA_dblk_page_t *dblk_page = NULL; /* Extensible array data block page */ @@ -163,7 +164,7 @@ HDfprintf(stderr, "%s: Called, addr = %a\n", FUNC, addr); HDassert(hdr); /* Allocate the data block page */ - if(NULL == (dblk_page = H5EA__dblk_page_alloc(hdr))) + if(NULL == (dblk_page = H5EA__dblk_page_alloc(hdr, parent))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block page") /* Set info about data block page on disk */ @@ -208,10 +209,11 @@ END_FUNC(PKG) /* end H5EA__dblk_page_create() */ */ BEGIN_FUNC(PKG, ERR, H5EA_dblk_page_t *, NULL, NULL, -H5EA__dblk_page_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_page_addr, - H5AC_protect_t rw)) +H5EA__dblk_page_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_sblock_t *parent, + haddr_t dblk_page_addr, H5AC_protect_t rw)) /* Local variables */ + H5EA_dblk_page_load_ud_t load_ud; /* Information needed for loading data block page */ #ifdef QAK HDfprintf(stderr, "%s: Called\n", FUNC); @@ -221,8 +223,11 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(hdr); HDassert(H5F_addr_defined(dblk_page_addr)); + /* Set up user data */ + load_ud.parent = parent; + /* Protect the data block page */ - if(NULL == (ret_value = (H5EA_dblk_page_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_DBLK_PAGE, dblk_page_addr, NULL, hdr, rw))) + if(NULL == (ret_value = (H5EA_dblk_page_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_DBLK_PAGE, dblk_page_addr, &load_ud, hdr, rw))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block page, address = %llu", (unsigned long long)dblk_page_addr) CATCH diff --git a/src/H5EAdblock.c b/src/H5EAdblock.c index 07ba3d1..344b9fa 100644 --- a/src/H5EAdblock.c +++ b/src/H5EAdblock.c @@ -101,13 +101,14 @@ H5FL_DEFINE_STATIC(H5EA_dblock_t); */ BEGIN_FUNC(PKG, ERR, H5EA_dblock_t *, NULL, NULL, -H5EA__dblock_alloc(H5EA_hdr_t *hdr, size_t nelmts)) +H5EA__dblock_alloc(H5EA_hdr_t *hdr, void *parent, size_t nelmts)) /* Local variables */ H5EA_dblock_t *dblock = NULL; /* Extensible array data block */ /* Check arguments */ HDassert(hdr); + HDassert(parent); HDassert(nelmts > 0); /* Allocate memory for the data block */ @@ -120,6 +121,7 @@ H5EA__dblock_alloc(H5EA_hdr_t *hdr, size_t nelmts)) dblock->hdr = hdr; /* Set non-zero internal fields */ + dblock->parent = parent; dblock->nelmts = nelmts; /* Check if the data block is not going to be paged */ @@ -160,8 +162,8 @@ END_FUNC(PKG) /* end H5EA__dblock_alloc() */ */ BEGIN_FUNC(PKG, ERR, haddr_t, HADDR_UNDEF, HADDR_UNDEF, -H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hbool_t *stats_changed, - hsize_t dblk_off, size_t nelmts)) +H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent, + hbool_t *stats_changed, hsize_t dblk_off, size_t nelmts)) /* Local variables */ H5EA_dblock_t *dblock = NULL; /* Extensible array data block */ @@ -177,7 +179,7 @@ HDfprintf(stderr, "%s: Called, hdr->dblk_page_nelmts = %Zu, nelmts = %Zu\n", FUN HDassert(nelmts > 0); /* Allocate the data block */ - if(NULL == (dblock = H5EA__dblock_alloc(hdr, nelmts))) + if(NULL == (dblock = H5EA__dblock_alloc(hdr, parent, nelmts))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block") /* Set size of data block on disk */ @@ -301,10 +303,11 @@ END_FUNC(PKG) /* end H5EA__dblock_sblk_idx() */ */ BEGIN_FUNC(PKG, ERR, H5EA_dblock_t *, NULL, NULL, -H5EA__dblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_addr, - size_t dblk_nelmts, H5AC_protect_t rw)) +H5EA__dblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent, + haddr_t dblk_addr, size_t dblk_nelmts, H5AC_protect_t rw)) /* Local variables */ + H5EA_dblock_load_ud_t load_ud; /* Information needed for loading data block */ #ifdef QAK HDfprintf(stderr, "%s: Called\n", FUNC); @@ -315,8 +318,12 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(H5F_addr_defined(dblk_addr)); HDassert(dblk_nelmts); + /* Set up user data */ + load_ud.parent = parent; + load_ud.nelmts = dblk_nelmts; + /* Protect the data block */ - if(NULL == (ret_value = (H5EA_dblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_DBLOCK, dblk_addr, &dblk_nelmts, hdr, rw))) + if(NULL == (ret_value = (H5EA_dblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_DBLOCK, dblk_addr, &load_ud, hdr, rw))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)dblk_addr) CATCH @@ -374,8 +381,8 @@ END_FUNC(PKG) /* end H5EA__dblock_unprotect() */ */ BEGIN_FUNC(PKG, ERR, herr_t, SUCCEED, FAIL, -H5EA__dblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_addr, - size_t dblk_nelmts)) +H5EA__dblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent, + haddr_t dblk_addr, size_t dblk_nelmts)) /* Local variables */ H5EA_dblock_t *dblock = NULL; /* Pointer to data block */ @@ -386,11 +393,12 @@ HDfprintf(stderr, "%s: Called\n", FUNC); /* Sanity check */ HDassert(hdr); + HDassert(parent); HDassert(H5F_addr_defined(dblk_addr)); HDassert(dblk_nelmts > 0); /* Protect data block */ - if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, dblk_addr, dblk_nelmts, H5AC_WRITE))) + if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, parent, dblk_addr, dblk_nelmts, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)dblk_addr) /* Check if this is a paged data block */ diff --git a/src/H5EAiblock.c b/src/H5EAiblock.c index b6d80a8..9920277 100644 --- a/src/H5EAiblock.c +++ b/src/H5EAiblock.c @@ -376,7 +376,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); /* Check for data block existing */ if(H5F_addr_defined(iblock->dblk_addrs[u])) { /* Delete data block */ - if(H5EA__dblock_delete(hdr, dxpl_id, iblock->dblk_addrs[u], hdr->sblk_info[sblk_idx].dblk_nelmts) < 0) + if(H5EA__dblock_delete(hdr, dxpl_id, iblock, iblock->dblk_addrs[u], hdr->sblk_info[sblk_idx].dblk_nelmts) < 0) H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array data block") iblock->dblk_addrs[u] = HADDR_UNDEF; } /* end if */ @@ -401,7 +401,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); /* Check for data block existing */ if(H5F_addr_defined(iblock->sblk_addrs[u])) { /* Delete super block */ - if(H5EA__sblock_delete(hdr, dxpl_id, iblock->sblk_addrs[u], (unsigned)(u + iblock->nsblks)) < 0) + if(H5EA__sblock_delete(hdr, dxpl_id, iblock, iblock->sblk_addrs[u], (unsigned)(u + iblock->nsblks)) < 0) H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array super block") iblock->sblk_addrs[u] = HADDR_UNDEF; } /* end if */ diff --git a/src/H5EAint.c b/src/H5EAint.c index a53d4f9..5ce88fc 100644 --- a/src/H5EAint.c +++ b/src/H5EAint.c @@ -79,3 +79,66 @@ /*******************/ + +/*------------------------------------------------------------------------- + * Function: H5EA__create_flush_depend + * + * Purpose: Create a flush dependency between two data structure components + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 26 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5EA__create_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_entry, + H5AC_info_t *child_entry)) + + /* Sanity check */ + HDassert(hdr); + HDassert(parent_entry); + HDassert(child_entry); + + /* Create a flush dependency between parent and child entry */ + if(H5AC_create_flush_dependency(hdr->f, parent_entry, child_entry) < 0) + H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency") + +CATCH + +END_FUNC(PKG) /* end H5EA__create_flush_depend() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__destroy_flush_depend + * + * Purpose: Destroy a flush dependency between two data structure components + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 26 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5EA__destroy_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_entry, H5AC_info_t *child_entry)) + + /* Sanity check */ + HDassert(hdr); + HDassert(parent_entry); + HDassert(child_entry); + + /* Destroy a flush dependency between parent and child entry */ + if(H5AC_destroy_flush_dependency(hdr->f, parent_entry, child_entry) < 0) + H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency") + +CATCH + +END_FUNC(PKG) /* end H5EA__destroy_flush_depend() */ + diff --git a/src/H5EApkg.h b/src/H5EApkg.h index 2364eb8..3f32b19 100644 --- a/src/H5EApkg.h +++ b/src/H5EApkg.h @@ -539,6 +539,7 @@ typedef struct H5EA_sblock_t { /* Internal array information (not stored) */ size_t rc; /* Reference count of objects using this block */ H5EA_hdr_t *hdr; /* Shared array header info */ + H5EA_iblock_t *parent; /* Parent object for super block (index block) */ haddr_t addr; /* Address of this index block on disk */ size_t size; /* Size of index block on disk */ @@ -562,6 +563,7 @@ typedef struct H5EA_dblock_t { /* Internal array information (not stored) */ H5EA_hdr_t *hdr; /* Shared array header info */ + void *parent; /* Parent object for data block (index or super block) */ haddr_t addr; /* Address of this data block on disk */ size_t size; /* Size of data block on disk */ @@ -580,6 +582,7 @@ typedef struct H5EA_dbk_page_t { /* Internal array information (not stored) */ H5EA_hdr_t *hdr; /* Shared array header info */ + H5EA_sblock_t *parent; /* Parent object for data block page (super block) */ haddr_t addr; /* Address of this data block page on disk */ size_t size; /* Size of data block page on disk */ @@ -593,6 +596,25 @@ struct H5EA_t { H5F_t *f; /* Pointer to file for extensible array */ }; +/* Metadata cache callback user data types */ + +/* Info needed for loading data block page */ +typedef struct H5EA_dblk_page_load_ud_t { + H5EA_sblock_t *parent; /* Pointer to parent object for data block page (super block) */ +} H5EA_dblk_page_load_ud_t; + +/* Info needed for loading data block */ +typedef struct H5EA_dblock_load_ud_t { + void *parent; /* Pointer to parent object for data block (index or super block) */ + size_t nelmts; /* Number of elements in data block */ +} H5EA_dblock_load_ud_t; + +/* Info needed for loading super block */ +typedef struct H5EA_sblock_load_ud_t { + H5EA_iblock_t *parent; /* Pointer to parent object for super block (index block) */ + unsigned sblk_idx; /* Index of super block */ +} H5EA_sblock_load_ud_t; + /*****************************/ /* Package Private Variables */ @@ -623,6 +645,12 @@ H5_DLLVAR const H5EA_class_t H5EA_CLS_TEST[1]; /* Package Private Prototypes */ /******************************/ +/* Generic routines */ +H5_DLL herr_t H5EA__create_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_entry, + H5AC_info_t *child_entry); +H5_DLL herr_t H5EA__destroy_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_entry, + H5AC_info_t *child_entry); + /* Header routines */ H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls); H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr); @@ -649,36 +677,38 @@ H5_DLL herr_t H5EA__iblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id); H5_DLL herr_t H5EA__iblock_dest(H5F_t *f, H5EA_iblock_t *iblock); /* Super block routines */ -H5_DLL H5EA_sblock_t *H5EA__sblock_alloc(H5EA_hdr_t *hdr, unsigned sblk_idx); +H5_DLL H5EA_sblock_t *H5EA__sblock_alloc(H5EA_hdr_t *hdr, H5EA_iblock_t *parent, + unsigned sblk_idx); H5_DLL haddr_t H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, - hbool_t *stats_changed, unsigned sblk_idx); + H5EA_iblock_t *parent, hbool_t *stats_changed, unsigned sblk_idx); H5_DLL H5EA_sblock_t *H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, - haddr_t sblk_addr, unsigned sblk_idx, H5AC_protect_t rw); + H5EA_iblock_t *parent, haddr_t sblk_addr, unsigned sblk_idx, H5AC_protect_t rw); H5_DLL herr_t H5EA__sblock_unprotect(H5EA_sblock_t *sblock, hid_t dxpl_id, unsigned cache_flags); H5_DLL herr_t H5EA__sblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, - haddr_t sblk_addr, unsigned sblk_idx); + H5EA_iblock_t *parent, haddr_t sblk_addr, unsigned sblk_idx); H5_DLL herr_t H5EA__sblock_dest(H5F_t *f, H5EA_sblock_t *sblock); /* Data block routines */ -H5_DLL H5EA_dblock_t *H5EA__dblock_alloc(H5EA_hdr_t *hdr, size_t nelmts); -H5_DLL haddr_t H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, +H5_DLL H5EA_dblock_t *H5EA__dblock_alloc(H5EA_hdr_t *hdr, void *parent, + size_t nelmts); +H5_DLL haddr_t H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent, hbool_t *stats_changed, hsize_t dblk_off, size_t nelmts); H5_DLL unsigned H5EA__dblock_sblk_idx(const H5EA_hdr_t *hdr, hsize_t idx); H5_DLL H5EA_dblock_t *H5EA__dblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, - haddr_t dblk_addr, size_t dblk_nelmts, H5AC_protect_t rw); + void *parent, haddr_t dblk_addr, size_t dblk_nelmts, H5AC_protect_t rw); H5_DLL herr_t H5EA__dblock_unprotect(H5EA_dblock_t *dblock, hid_t dxpl_id, unsigned cache_flags); -H5_DLL herr_t H5EA__dblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, +H5_DLL herr_t H5EA__dblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent, haddr_t dblk_addr, size_t dblk_nelmts); H5_DLL herr_t H5EA__dblock_dest(H5F_t *f, H5EA_dblock_t *dblock); /* Data block page routines */ -H5_DLL H5EA_dblk_page_t *H5EA__dblk_page_alloc(H5EA_hdr_t *hdr); +H5_DLL H5EA_dblk_page_t *H5EA__dblk_page_alloc(H5EA_hdr_t *hdr, H5EA_sblock_t *parent); H5_DLL herr_t H5EA__dblk_page_create(H5EA_hdr_t *hdr, hid_t dxpl_id, - haddr_t addr); + H5EA_sblock_t *parent, haddr_t addr); H5_DLL H5EA_dblk_page_t *H5EA__dblk_page_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, - haddr_t dblk_page_addr, H5AC_protect_t rw); + H5EA_sblock_t *parent, haddr_t dblk_page_addr, H5AC_protect_t rw); H5_DLL herr_t H5EA__dblk_page_unprotect(H5EA_dblk_page_t *dblk_page, hid_t dxpl_id, unsigned cache_flags); H5_DLL herr_t H5EA__dblk_page_dest(H5EA_dblk_page_t *dblk_page); diff --git a/src/H5EAsblock.c b/src/H5EAsblock.c index 157d1aa..c6a4306 100644 --- a/src/H5EAsblock.c +++ b/src/H5EAsblock.c @@ -107,7 +107,7 @@ H5FL_BLK_DEFINE(page_init); */ BEGIN_FUNC(PKG, ERR, H5EA_sblock_t *, NULL, NULL, -H5EA__sblock_alloc(H5EA_hdr_t *hdr, unsigned sblk_idx)) +H5EA__sblock_alloc(H5EA_hdr_t *hdr, H5EA_iblock_t *parent, unsigned sblk_idx)) /* Local variables */ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */ @@ -125,6 +125,7 @@ H5EA__sblock_alloc(H5EA_hdr_t *hdr, unsigned sblk_idx)) sblock->hdr = hdr; /* Set non-zero internal fields */ + sblock->parent = parent; sblock->addr = HADDR_UNDEF; /* Compute/cache information */ @@ -190,8 +191,8 @@ END_FUNC(PKG) /* end H5EA__sblock_alloc() */ */ BEGIN_FUNC(PKG, ERR, haddr_t, HADDR_UNDEF, HADDR_UNDEF, -H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hbool_t *stats_changed, - unsigned sblk_idx)) +H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent, + hbool_t *stats_changed, unsigned sblk_idx)) /* Local variables */ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */ @@ -207,7 +208,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(stats_changed); /* Allocate the super block */ - if(NULL == (sblock = H5EA__sblock_alloc(hdr, sblk_idx))) + if(NULL == (sblock = H5EA__sblock_alloc(hdr, parent, sblk_idx))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block") /* Set size of super block on disk */ @@ -274,10 +275,12 @@ END_FUNC(PKG) /* end H5EA__sblock_create() */ */ BEGIN_FUNC(PKG, ERR, H5EA_sblock_t *, NULL, NULL, -H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t sblk_addr, - unsigned sblk_idx, H5AC_protect_t rw)) +H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent, + haddr_t sblk_addr, unsigned sblk_idx, H5AC_protect_t rw)) /* Local variables */ + H5EA_sblock_load_ud_t load_ud; /* Information needed for loading super block */ + #ifdef QAK HDfprintf(stderr, "%s: Called\n", FUNC); @@ -287,8 +290,12 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(hdr); HDassert(H5F_addr_defined(sblk_addr)); + /* Set up user data */ + load_ud.parent = parent; + load_ud.sblk_idx = sblk_idx; + /* Protect the super block */ - if(NULL == (ret_value = (H5EA_sblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblk_addr, &sblk_idx, hdr, rw))) + if(NULL == (ret_value = (H5EA_sblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblk_addr, &load_ud, hdr, rw))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)sblk_addr) CATCH @@ -346,8 +353,8 @@ END_FUNC(PKG) /* end H5EA__sblock_unprotect() */ */ BEGIN_FUNC(PKG, ERR, herr_t, SUCCEED, FAIL, -H5EA__sblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t sblk_addr, - unsigned sblk_idx)) +H5EA__sblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent, + haddr_t sblk_addr, unsigned sblk_idx)) /* Local variables */ H5EA_sblock_t *sblock = NULL; /* Pointer to super block */ @@ -362,7 +369,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(H5F_addr_defined(sblk_addr)); /* Protect super block */ - if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, sblk_addr, sblk_idx, H5AC_WRITE))) + if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, parent, sblk_addr, sblk_idx, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)sblk_addr) /* Iterate over data blocks */ @@ -370,7 +377,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); /* Check for data block existing */ if(H5F_addr_defined(sblock->dblk_addrs[u])) { /* Delete data block */ - if(H5EA__dblock_delete(hdr, dxpl_id, sblock->dblk_addrs[u], sblock->dblk_nelmts) < 0) + if(H5EA__dblock_delete(hdr, dxpl_id, sblock, sblock->dblk_addrs[u], sblock->dblk_nelmts) < 0) H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array data block") sblock->dblk_addrs[u] = HADDR_UNDEF; } /* end if */ -- cgit v0.12