diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2009-11-16 04:17:45 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2009-11-16 04:17:45 (GMT) |
commit | 4fe33eda1c243a0e6410e57c151b93e1950cf192 (patch) | |
tree | 857b21defd5b7804fd8edd0e3429a57213b849cc /src | |
parent | 6d5d4ed1d10498bf776b5a4d41cf2384b4d8fe28 (diff) | |
download | hdf5-4fe33eda1c243a0e6410e57c151b93e1950cf192.zip hdf5-4fe33eda1c243a0e6410e57c151b93e1950cf192.tar.gz hdf5-4fe33eda1c243a0e6410e57c151b93e1950cf192.tar.bz2 |
[svn-r17895] Description:
Correct & simplify client callback context for extensible and fixed
array data structures.
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/default API=1.8.x,
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 debug mode
Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
Mac OS X/32 10.6.2 (amazon) in debug mode
Mac OS X/32 10.6.2 (amazon) w/C++ & FORTRAN, w/threadsafe,
in production mode
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 4 | ||||
-rw-r--r-- | src/H5EA.c | 66 | ||||
-rw-r--r-- | src/H5EAcache.c | 14 | ||||
-rw-r--r-- | src/H5EAhdr.c | 28 | ||||
-rw-r--r-- | src/H5EApkg.h | 8 | ||||
-rw-r--r-- | src/H5EAprivate.h | 6 | ||||
-rw-r--r-- | src/H5FA.c | 64 | ||||
-rw-r--r-- | src/H5FAcache.c | 21 | ||||
-rw-r--r-- | src/H5FAhdr.c | 64 | ||||
-rw-r--r-- | src/H5FApkg.h | 6 | ||||
-rw-r--r-- | src/H5FAprivate.h | 11 |
11 files changed, 201 insertions, 91 deletions
@@ -61,6 +61,10 @@ static void H5_debug_mask(const char*); /* Library Private Variables */ /*****************************/ +/* HDF5 API Entered variable */ +/* (move to H5.c when new FUNC_ENTER macros in actual use -QAK) */ +hbool_t H5_api_entered_g = FALSE; + /* statically initialize block for pthread_once call used in initializing */ /* the first global mutex */ #ifdef H5_HAVE_THREADSAFE @@ -79,9 +79,16 @@ typedef herr_t (*H5EA__unprotect_func_t)(void *thing, hid_t dxpl_id, /* Package Variables */ /*********************/ -/* HDF5 API Entered variable */ -/* (move to H5.c when new FUNC_ENTER macros in actual use -QAK) */ -hbool_t H5_api_entered_g = FALSE; +/* Extensible array client ID to class mapping */ + +/* Remember to add client ID to H5EA_cls_id_t in H5EAprivate.h when adding a new + * client class.. + */ +extern const H5EA_class_t H5EA_CLS_TEST[1]; + +const H5EA_class_t *const H5EA_client_class_g[] = { + H5EA_CLS_TEST, /* 0 - H5EA_TEST_ID */ +}; /*****************************/ @@ -131,6 +138,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(f); HDassert(cparam); + /* H5EA interface sanity check */ + HDcompile_assert(H5EA_NUM_CLS_ID == NELMTS(H5EA_client_class_g)); + /* Create extensible array header */ if(HADDR_UNDEF == (ea_addr = H5EA__hdr_create(f, dxpl_id, cparam, ctx_udata))) H5E_THROW(H5E_CANTINIT, "can't create extensible array header") @@ -140,7 +150,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array info") /* Lock the array header into memory */ - if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, cparam->cls, NULL, H5AC_WRITE))) + if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header") /* Point extensible array wrapper at header and bump it's ref count */ @@ -185,8 +195,7 @@ END_FUNC(PRIV) /* end H5EA_create() */ */ BEGIN_FUNC(PRIV, ERR, H5EA_t *, NULL, NULL, -H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5EA_class_t *cls, - void *ctx_udata)) +H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata)) /* Local variables */ H5EA_t *ea = NULL; /* Pointer to new extensible array wrapper */ @@ -197,13 +206,12 @@ H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5EA_class_t *cls, */ HDassert(f); HDassert(H5F_addr_defined(ea_addr)); - HDassert(cls); /* Load the array header into memory */ #ifdef QAK HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr); #endif /* QAK */ - if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, cls, ctx_udata, H5AC_READ))) + if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header, address = %llu", (unsigned long long)ea_addr) /* Check for pending array deletion */ @@ -1031,28 +1039,52 @@ HDfprintf(stderr, "%s: Called\n", FUNC); } /* end if */ } /* end if */ - /* Decrement the reference count on the array header */ - /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted - * immediately -QAK) - */ - if(H5EA__hdr_decr(ea->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") - /* Check for pending array deletion */ if(pending_delete) { H5EA_hdr_t *hdr; /* Another pointer to extensible array header */ +#ifndef NDEBUG +{ + unsigned hdr_status = 0; /* Header's status in the metadata cache */ + + /* Check the header's status in the metadata cache */ + if(H5AC_get_entry_status(ea->f, ea_addr, &hdr_status) < 0) + H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for extensible array header") + + /* Sanity checks on header */ + HDassert(hdr_status & H5AC_ES__IN_CACHE); + HDassert(hdr_status & H5AC_ES__IS_PINNED); + HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED)); +} +#endif /* NDEBUG */ + /* Lock the array header into memory */ + /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(ea->f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE))) H5E_THROW(H5E_CANTLOAD, "unable to load extensible array header") /* Set the shared array header's file context for this operation */ hdr->f = ea->f; + /* Decrement the reference count on the array header */ + /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5EA__hdr_decr(ea->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + /* Delete array, starting with header (unprotects header) */ if(H5EA__hdr_delete(hdr, dxpl_id) < 0) H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array") } /* end if */ + else { + /* Decrement the reference count on the array header */ + /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5EA__hdr_decr(ea->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + } /* end else */ /* Release the extensible array wrapper */ ea = (H5EA_t *)H5FL_FREE(H5EA_t, ea); @@ -1077,7 +1109,7 @@ END_FUNC(PRIV) /* end H5EA_close() */ */ BEGIN_FUNC(PRIV, ERR, herr_t, SUCCEED, FAIL, -H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr)) +H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata)) /* Local variables */ H5EA_hdr_t *hdr = NULL; /* The fractal heap header information */ @@ -1092,7 +1124,7 @@ H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr)) #ifdef QAK HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr); #endif /* QAK */ - if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE))) + if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array header, address = %llu", (unsigned long long)ea_addr) /* Check for files using shared array header */ diff --git a/src/H5EAcache.c b/src/H5EAcache.c index 00d3089..5138ae4 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -198,11 +198,11 @@ const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1] = {{ */ BEGIN_FUNC(STATIC, ERR, H5EA_hdr_t *, NULL, NULL, -H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, +H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *ctx_udata)) /* Local variables */ - const H5EA_class_t *cls = (const H5EA_class_t *)_cls; /* Extensible array class */ + H5EA_cls_id_t id; /* ID of extensible array class, as found in file */ H5EA_hdr_t *hdr = NULL; /* Extensible array info */ size_t size; /* Header size */ H5WB_t *wb = NULL; /* Wrapped buffer for header data */ @@ -217,7 +217,7 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, HDassert(H5F_addr_defined(addr)); /* Allocate space for the extensible array data structure */ - if(NULL == (hdr = H5EA__hdr_alloc(f, cls, ctx_udata))) + if(NULL == (hdr = H5EA__hdr_alloc(f))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header") /* Set the extensible array header's address */ @@ -250,9 +250,11 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, if(*p++ != H5EA_HDR_VERSION) H5E_THROW(H5E_VERSION, "wrong extensible array header version") - /* Extensible array type */ - if(*p++ != (uint8_t)cls->id) + /* Extensible array class */ + id = *p++; + if(id >= H5EA_NUM_CLS_ID) H5E_THROW(H5E_BADTYPE, "incorrect extensible array class") + hdr->cparam.cls = H5EA_client_class_g[id]; /* General array creation/configuration information */ hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */ @@ -314,7 +316,7 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array header") /* Finish initializing extensible array header */ - if(H5EA__hdr_init(hdr) < 0) + if(H5EA__hdr_init(hdr, ctx_udata) < 0) H5E_THROW(H5E_CANTINIT, "initialization failed for extensible array header") HDassert(hdr->size == size); diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c index f821476..b8d3334 100644 --- a/src/H5EAhdr.c +++ b/src/H5EAhdr.c @@ -118,14 +118,13 @@ H5FL_SEQ_DEFINE_STATIC(H5EA_sblk_info_t); */ BEGIN_FUNC(PKG, ERR, H5EA_hdr_t *, NULL, NULL, -H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls, void *udata)) +H5EA__hdr_alloc(H5F_t *f)) /* Local variables */ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */ /* Check arguments */ HDassert(f); - HDassert(cls); /* Allocate space for the shared information */ if(NULL == (hdr = H5FL_CALLOC(H5EA_hdr_t))) @@ -139,13 +138,6 @@ H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls, void *udata)) hdr->sizeof_addr = H5F_SIZEOF_ADDR(f); hdr->sizeof_size = H5F_SIZEOF_SIZE(f); - /* Set the class of the array */ - hdr->cparam.cls = cls; - - /* Create the callback context */ - if(NULL == (hdr->cb_ctx = (*cls->crt_context)(udata))) - H5E_THROW(H5E_CANTCREATE, "unable to create extensible array client callback context") - /* Set the return value */ ret_value = hdr; @@ -195,7 +187,7 @@ END_FUNC(PKG) /* end H5EA__hdr_alloc() */ */ BEGIN_FUNC(PKG, ERR, herr_t, SUCCEED, FAIL, -H5EA__hdr_init(H5EA_hdr_t *hdr)) +H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata)) /* Local variables */ hsize_t start_idx; /* First element index for each super block */ @@ -240,6 +232,12 @@ HDfprintf(stderr, "%s: hdr->sblk_info[%Zu] = {%Zu, %Zu, %Hu, %Hu}\n", FUNC, u, h /* Set size of header on disk (locally and in statistics) */ hdr->stats.computed.hdr_size = hdr->size = H5EA_HEADER_SIZE(hdr); + /* Create the callback context, if there's one */ + if(hdr->cparam.cls->crt_context) { + if(NULL == (hdr->cb_ctx = (*hdr->cparam.cls->crt_context)(ctx_udata))) + H5E_THROW(H5E_CANTCREATE, "unable to create extensible array client callback context") + } /* end if */ + CATCH END_FUNC(PKG) /* end H5EA__hdr_init() */ @@ -419,7 +417,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); #endif /* NDEBUG */ /* Allocate space for the shared information */ - if(NULL == (hdr = H5EA__hdr_alloc(f, cparam->cls, ctx_udata))) + if(NULL == (hdr = H5EA__hdr_alloc(f))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header") /* Set the internal parameters for the array */ @@ -429,7 +427,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); /* Finish initializing extensible array header */ - if(H5EA__hdr_init(hdr) < 0) + if(H5EA__hdr_init(hdr, ctx_udata) < 0) H5E_THROW(H5E_CANTINIT, "initialization failed for extensible array header") /* Allocate space for the header on disk */ @@ -694,8 +692,10 @@ H5EA__hdr_dest(H5EA_hdr_t *hdr)) HDassert(hdr->rc == 0); /* Destroy the callback context */ - if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) - H5E_THROW(H5E_CANTRELEASE, "unable to destroy extensible array client callback context") + if(hdr->cb_ctx) { + if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTRELEASE, "unable to destroy extensible array client callback context") + } /* end if */ hdr->cb_ctx = NULL; /* Check for data block element buffer factory info to free */ diff --git a/src/H5EApkg.h b/src/H5EApkg.h index 01090ea..6e86a34 100644 --- a/src/H5EApkg.h +++ b/src/H5EApkg.h @@ -353,6 +353,9 @@ H5_DLLVAR const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1]; H5_DLLVAR const H5EA_class_t H5EA_CLS_TEST[1]; #endif /* H5EA_TESTING */ +/* Array of extensible array client ID -> client class mappings */ +extern const H5EA_class_t *const H5EA_client_class_g[]; + /******************************/ /* Package Private Prototypes */ @@ -365,9 +368,8 @@ H5_DLL herr_t H5EA__destroy_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_en H5AC_info_t *child_entry); /* Header routines */ -H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls, - void *ctx_udata); -H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr); +H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f); +H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata); H5_DLL haddr_t H5EA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam, void *ctx_udata); H5_DLL void *H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts); diff --git a/src/H5EAprivate.h b/src/H5EAprivate.h index a132006..db61dee 100644 --- a/src/H5EAprivate.h +++ b/src/H5EAprivate.h @@ -50,6 +50,7 @@ /* Extensible array class IDs */ typedef enum H5EA_cls_id_t { /* Start real class IDs at 0 -QAK */ + /* (keep these last) */ H5EA_CLS_TEST_ID, /* Extensible array is for testing (do not use for actual data) */ H5EA_NUM_CLS_ID /* Number of Extensible Array class IDs (must be last) */ } H5EA_cls_id_t; @@ -121,8 +122,7 @@ typedef struct H5EA_t H5EA_t; /* General routines */ H5_DLL H5EA_t *H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam, void *ctx_udata); -H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, - const H5EA_class_t *cls, void *ctx_udata); +H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata); H5_DLL herr_t H5EA_get_nelmts(const H5EA_t *ea, hsize_t *nelmts); H5_DLL herr_t H5EA_get_addr(const H5EA_t *ea, haddr_t *addr); H5_DLL herr_t H5EA_set(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt); @@ -134,7 +134,7 @@ H5_DLL herr_t H5EA_support(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, H5_DLL herr_t H5EA_unsupport(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, H5AC_info_t *child_entry); H5_DLL herr_t H5EA_close(H5EA_t *ea, hid_t dxpl_id); -H5_DLL herr_t H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr); +H5_DLL herr_t H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata); /* Statistics routines */ H5_DLL herr_t H5EA_get_stats(const H5EA_t *ea, H5EA_stat_t *stats); @@ -70,6 +70,17 @@ /* Package Variables */ /*********************/ +/* Fixed array client ID to class mapping */ + +/* Remember to add client ID to H5FA_cls_id_t in H5FAprivate.h when adding a new + * client class.. + */ +extern const H5FA_class_t H5FA_CLS_TEST[1]; + +const H5FA_class_t *const H5FA_client_class_g[] = { + H5FA_CLS_TEST, /* 0 - H5FA_TEST_ID */ +}; + /*****************************/ /* Library Private Variables */ @@ -120,6 +131,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(f); HDassert(cparam); + /* H5FA interface sanity check */ + HDcompile_assert(H5FA_NUM_CLS_ID == NELMTS(H5FA_client_class_g)); + /* Create fixed array header */ if(HADDR_UNDEF == (fa_addr = H5FA__hdr_create(f, dxpl_id, cparam, ctx_udata))) H5E_THROW(H5E_CANTINIT, "can't create fixed array header") @@ -129,7 +143,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info") /* Lock the array header into memory */ - if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, cparam->cls, NULL, H5AC_WRITE))) + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header") /* Point fixed array wrapper at header and bump it's ref count */ @@ -173,8 +187,7 @@ END_FUNC(PRIV) /* end H5FA_create() */ */ BEGIN_FUNC(PRIV, ERR, H5FA_t *, NULL, NULL, -H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, const H5FA_class_t *cls, - void *ctx_udata)) +H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata)) /* Local variables */ H5FA_t *fa = NULL; /* Pointer to new fixed array wrapper */ @@ -185,13 +198,12 @@ H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, const H5FA_class_t *cls, */ HDassert(f); HDassert(H5F_addr_defined(fa_addr)); - HDassert(cls); /* Load the array header into memory */ #ifdef H5FA_DEBUG HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr); #endif /* H5FA_DEBUG */ - if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, cls, ctx_udata, H5AC_READ))) + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header, address = %llu", (unsigned long long)fa_addr) /* Check for pending array deletion */ @@ -561,28 +573,52 @@ HDfprintf(stderr, "%s: Called\n", FUNC); } /* end if */ } /* end if */ - /* Decrement the reference count on the array header */ - /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted - * immediately -QAK) - */ - if(H5FA__hdr_decr(fa->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") - /* Check for pending array deletion */ if(pending_delete) { H5FA_hdr_t *hdr; /* Another pointer to fixed array header */ +#ifndef NDEBUG +{ + unsigned hdr_status = 0; /* Header's status in the metadata cache */ + + /* Check the header's status in the metadata cache */ + if(H5AC_get_entry_status(fa->f, fa_addr, &hdr_status) < 0) + H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for fixed array header") + + /* Sanity checks on header */ + HDassert(hdr_status & H5AC_ES__IN_CACHE); + HDassert(hdr_status & H5AC_ES__IS_PINNED); + HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED)); +} +#endif /* NDEBUG */ + /* Lock the array header into memory */ + /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(fa->f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE))) H5E_THROW(H5E_CANTLOAD, "unable to load fixed array header") /* Set the shared array header's file context for this operation */ hdr->f = fa->f; + /* Decrement the reference count on the array header */ + /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5FA__hdr_decr(fa->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + /* Delete array, starting with header (unprotects header) */ if(H5FA__hdr_delete(hdr, dxpl_id) < 0) H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array") } /* end if */ + else { + /* Decrement the reference count on the array header */ + /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5FA__hdr_decr(fa->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + } /* end else */ /* Release the fixed array wrapper */ fa = H5FL_FREE(H5FA_t, fa); @@ -606,7 +642,7 @@ END_FUNC(PRIV) /* end H5FA_close() */ */ BEGIN_FUNC(PRIV, ERR, herr_t, SUCCEED, FAIL, -H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr)) +H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata)) /* Local variables */ H5FA_hdr_t *hdr = NULL; /* The fixed array header information */ @@ -621,7 +657,7 @@ H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr)) #ifdef H5FA_DEBUG HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr); #endif /* H5FA_DEBUG */ - if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE))) + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array header, address = %llu", (unsigned long long)fa_addr) /* Check for files using shared array header */ diff --git a/src/H5FAcache.c b/src/H5FAcache.c index 59a81e2..3488531 100644 --- a/src/H5FAcache.c +++ b/src/H5FAcache.c @@ -158,11 +158,11 @@ const H5AC_class_t H5AC_FARRAY_DBLK_PAGE[1] = {{ */ BEGIN_FUNC(STATIC, ERR, H5FA_hdr_t *, NULL, NULL, -H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, +H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *ctx_udata)) /* Local variables */ - const H5FA_class_t *cls = (const H5FA_class_t *)_cls; /* Fixed array class */ + H5FA_cls_id_t id; /* ID of fixed array class, as found in file */ H5FA_hdr_t *hdr = NULL; /* Fixed array info */ size_t size; /* Header size */ H5WB_t *wb = NULL; /* Wrapped buffer for header data */ @@ -177,7 +177,7 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, HDassert(H5F_addr_defined(addr)); /* Allocate space for the fixed array data structure */ - if(NULL == (hdr = H5FA__hdr_alloc(f, cls, ctx_udata))) + if(NULL == (hdr = H5FA__hdr_alloc(f))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array shared header") /* Set the fixed array header's address */ @@ -210,9 +210,11 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, if(*p++ != H5FA_HDR_VERSION) H5E_THROW(H5E_VERSION, "wrong fixed array header version") - /* Fixed array type */ - if(*p++ != (uint8_t)cls->id) + /* Fixed array class */ + id = *p++; + if(id >= H5FA_NUM_CLS_ID) H5E_THROW(H5E_BADTYPE, "incorrect fixed array class") + hdr->cparam.cls = H5FA_client_class_g[id]; /* General array creation/configuration information */ hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */ @@ -226,10 +228,6 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, /* Internal information */ H5F_addr_decode(f, &p, &hdr->dblk_addr); /* Address of index block */ - /* Initializations of header info */ - hdr->stats.nelmts = hdr->cparam.nelmts; - hdr->stats.hdr_size = hdr->size = size; /* Size of header in file */ - /* Check for data block */ if(H5F_addr_defined(hdr->dblk_addr)) { H5FA_dblock_t dblock; /* Fake data block for computing size */ @@ -267,6 +265,11 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, if(stored_chksum != computed_chksum) H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array header") + /* Finish initializing fixed array header */ + if(H5FA__hdr_init(hdr, ctx_udata) < 0) + H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header") + HDassert(hdr->size == size); + /* Set return value */ ret_value = hdr; diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c index e6231d4..94fb7b2 100644 --- a/src/H5FAhdr.c +++ b/src/H5FAhdr.c @@ -95,14 +95,13 @@ H5FL_DEFINE_STATIC(H5FA_hdr_t); */ BEGIN_FUNC(PKG, ERR, H5FA_hdr_t *, NULL, NULL, -H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *udata)) +H5FA__hdr_alloc(H5F_t *f)) /* Local variables */ H5FA_hdr_t *hdr = NULL; /* Shared Fixed Array header */ /* Check arguments */ HDassert(f); - HDassert(cls); /* Allocate space for the shared information */ if(NULL == (hdr = H5FL_CALLOC(H5FA_hdr_t))) @@ -116,13 +115,6 @@ H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *udata)) hdr->sizeof_addr = H5F_SIZEOF_ADDR(f); hdr->sizeof_size = H5F_SIZEOF_SIZE(f); - /* Set the class of the array */ - hdr->cparam.cls = cls; - - /* Create the callback context */ - if(NULL == (hdr->cb_ctx = (*cls->crt_context)(udata))) - H5E_THROW(H5E_CANTCREATE, "unable to create fixed array client callback context") - /* Set the return value */ ret_value = hdr; @@ -135,6 +127,44 @@ END_FUNC(PKG) /* end H5FA__hdr_alloc() */ /*------------------------------------------------------------------------- + * Function: H5FA__hdr_init + * + * Purpose: Initialize shared fixed array header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Sunday, November 15, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__hdr_init(H5FA_hdr_t *hdr, void *ctx_udata)) + + /* Local variables */ + + /* Check arguments */ + HDassert(hdr); + + /* Set size of header on disk (locally and in statistics) */ + hdr->stats.hdr_size = hdr->size = H5FA_HEADER_SIZE(hdr); + + /* Set number of elements for Fixed Array in statistics */ + hdr->stats.nelmts = hdr->cparam.nelmts; + + /* Create the callback context, if there's one */ + if(hdr->cparam.cls->crt_context) { + if(NULL == (hdr->cb_ctx = (*hdr->cparam.cls->crt_context)(ctx_udata))) + H5E_THROW(H5E_CANTCREATE, "unable to create fixed array client callback context") + } /* end if */ + +CATCH + +END_FUNC(PKG) /* end H5FA__hdr_init() */ + + +/*------------------------------------------------------------------------- * Function: H5FA__hdr_create * * Purpose: Creates a new Fixed Array header in the file @@ -175,7 +205,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); #endif /* NDEBUG */ /* Allocate space for the shared information */ - if(NULL == (hdr = H5FA__hdr_alloc(f, cparam->cls, ctx_udata))) + if(NULL == (hdr = H5FA__hdr_alloc(f))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for Fixed Array shared header") hdr->dblk_addr = HADDR_UNDEF; @@ -183,11 +213,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC); /* Set the creation parameters for the array */ HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); - /* Set size of header on disk (locally and in statistics) */ - hdr->stats.hdr_size = hdr->size = H5FA_HEADER_SIZE(hdr); - - /* Set number of elements for Fixed Array in statistics */ - hdr->stats.nelmts = hdr->cparam.nelmts; + /* Finish initializing fixed array header */ + if(H5FA__hdr_init(hdr, ctx_udata) < 0) + H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header") /* Allocate space for the header on disk */ if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_FARRAY_HDR, dxpl_id, (hsize_t)hdr->size))) @@ -445,8 +473,10 @@ H5FA__hdr_dest(H5FA_hdr_t *hdr)) HDassert(hdr->rc == 0); /* Destroy the callback context */ - if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) - H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context") + if(hdr->cb_ctx) { + if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context") + } /* end if */ hdr->cb_ctx = NULL; /* Free the shared info itself */ diff --git a/src/H5FApkg.h b/src/H5FApkg.h index 1ba8f84..c817b1a 100644 --- a/src/H5FApkg.h +++ b/src/H5FApkg.h @@ -228,13 +228,17 @@ H5_DLLVAR const H5FA_class_t H5FA_CLS_FILT_CHUNK[1]; H5_DLLVAR const H5FA_class_t H5FA_CLS_TEST[1]; #endif /* H5FA_TESTING */ +/* Array of fixed array client ID -> client class mappings */ +extern const H5FA_class_t *const H5FA_client_class_g[]; + /******************************/ /* Package Private Prototypes */ /******************************/ /* Header routines */ -H5_DLL H5FA_hdr_t *H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *ctx_udata); +H5_DLL H5FA_hdr_t *H5FA__hdr_alloc(H5F_t *f); +H5_DLL herr_t H5FA__hdr_init(H5FA_hdr_t *hdr, void *ctx_udata); H5_DLL haddr_t H5FA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata); H5_DLL void *H5FA__hdr_alloc_elmts(H5FA_hdr_t *hdr, size_t nelmts); H5_DLL herr_t H5FA__hdr_free_elmts(H5FA_hdr_t *hdr, size_t nelmts, void *elmts); diff --git a/src/H5FAprivate.h b/src/H5FAprivate.h index 16397fd..1a5a6a0 100644 --- a/src/H5FAprivate.h +++ b/src/H5FAprivate.h @@ -46,9 +46,7 @@ /* Fixed Array class IDs */ typedef enum H5FA_cls_id_t { - H5FA_CLS_CHUNK_ID = 0, /* Fixed array is for indexing dataset chunks w/o filters */ - H5FA_CLS_FILT_CHUNK_ID, /* Fixed array is for indexing dataset chunks w/filters */ - + /* Start real class IDs at 0 -QAK */ /* (keep these last) */ H5FA_CLS_TEST_ID, /* Fixed array is for testing (do not use for actual data) */ H5FA_NUM_CLS_ID /* Number of Fixed Array class IDs (must be last) */ @@ -113,15 +111,14 @@ typedef int (*H5FA_operator_t)(hsize_t idx, const void *_elmt, void *_udata); /* General routines */ H5_DLL H5FA_t *H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata); -H5_DLL H5FA_t *H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5FA_class_t *cls, - void *ctx_udata); +H5_DLL H5FA_t *H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata); H5_DLL herr_t H5FA_get_nelmts(const H5FA_t *ea, hsize_t *nelmts); H5_DLL herr_t H5FA_get_addr(const H5FA_t *ea, haddr_t *addr); H5_DLL herr_t H5FA_set(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt); H5_DLL herr_t H5FA_get(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt); -H5_DLL herr_t H5FA_close(H5FA_t *ea, hid_t dxpl_id); -H5_DLL herr_t H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr); H5_DLL herr_t H5FA_iterate(H5FA_t *fa, hid_t dxpl_id, H5FA_operator_t op, void *udata); +H5_DLL herr_t H5FA_close(H5FA_t *ea, hid_t dxpl_id); +H5_DLL herr_t H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata); /* Statistics routines */ H5_DLL herr_t H5FA_get_stats(const H5FA_t *ea, H5FA_stat_t *stats); |